summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet6
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-04-04 09:36:57 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-04-04 14:46:23 +0200
commitde8a76da2f374792594ce03a203b3f30e4889f6f (patch)
tree12b5e1e59358005c3c522955c08aee4795e4829c /freebsd/sys/netinet6
parentEnable bridging by default (diff)
downloadrtems-libbsd-de8a76da2f374792594ce03a203b3f30e4889f6f.tar.bz2
Update to FreeBSD head 2017-04-04
Git mirror commit 642b174daddbd0efd9bb5f242c43f4ab4db6869f.
Diffstat (limited to 'freebsd/sys/netinet6')
-rw-r--r--freebsd/sys/netinet6/frag6.c9
-rw-r--r--freebsd/sys/netinet6/icmp6.c6
-rw-r--r--freebsd/sys/netinet6/in6.c24
-rw-r--r--freebsd/sys/netinet6/in6.h8
-rw-r--r--freebsd/sys/netinet6/in6_cksum.c2
-rw-r--r--freebsd/sys/netinet6/in6_fib.c2
-rw-r--r--freebsd/sys/netinet6/in6_fib.h2
-rw-r--r--freebsd/sys/netinet6/in6_ifattach.c1
-rw-r--r--freebsd/sys/netinet6/in6_pcb.c6
-rw-r--r--freebsd/sys/netinet6/in6_pcb.h4
-rw-r--r--freebsd/sys/netinet6/in6_proto.c56
-rw-r--r--freebsd/sys/netinet6/in6_src.c6
-rw-r--r--freebsd/sys/netinet6/in6_var.h2
-rw-r--r--freebsd/sys/netinet6/ip6_forward.c229
-rw-r--r--freebsd/sys/netinet6/ip6_input.c97
-rw-r--r--freebsd/sys/netinet6/ip6_ipsec.c393
-rw-r--r--freebsd/sys/netinet6/ip6_ipsec.h42
-rw-r--r--freebsd/sys/netinet6/ip6_mroute.c2
-rw-r--r--freebsd/sys/netinet6/ip6_output.c145
-rw-r--r--freebsd/sys/netinet6/ip6_var.h2
-rw-r--r--freebsd/sys/netinet6/ip6protosw.h2
-rw-r--r--freebsd/sys/netinet6/mld6.c2
-rw-r--r--freebsd/sys/netinet6/nd6.c74
-rw-r--r--freebsd/sys/netinet6/nd6.h1
-rw-r--r--freebsd/sys/netinet6/nd6_nbr.c9
-rw-r--r--freebsd/sys/netinet6/nd6_rtr.c108
-rw-r--r--freebsd/sys/netinet6/raw_ip6.c28
-rw-r--r--freebsd/sys/netinet6/sctp6_usrreq.c9
-rw-r--r--freebsd/sys/netinet6/tcp6_var.h2
-rw-r--r--freebsd/sys/netinet6/udp6_usrreq.c51
-rw-r--r--freebsd/sys/netinet6/udp6_var.h2
31 files changed, 393 insertions, 933 deletions
diff --git a/freebsd/sys/netinet6/frag6.c b/freebsd/sys/netinet6/frag6.c
index 4cbd3000..f0721a4c 100644
--- a/freebsd/sys/netinet6/frag6.c
+++ b/freebsd/sys/netinet6/frag6.c
@@ -530,6 +530,11 @@ insert:
af6 = ip6af->ip6af_down;
frag6_deq(ip6af);
while (af6 != (struct ip6asfrag *)q6) {
+ m->m_pkthdr.csum_flags &=
+ IP6_REASS_MBUF(af6)->m_pkthdr.csum_flags;
+ m->m_pkthdr.csum_data +=
+ IP6_REASS_MBUF(af6)->m_pkthdr.csum_data;
+
af6dwn = af6->ip6af_down;
frag6_deq(af6);
while (t->m_next)
@@ -540,6 +545,10 @@ insert:
af6 = af6dwn;
}
+ while (m->m_pkthdr.csum_data & 0xffff0000)
+ m->m_pkthdr.csum_data = (m->m_pkthdr.csum_data & 0xffff) +
+ (m->m_pkthdr.csum_data >> 16);
+
/* adjust offset to point where the original next header starts */
offset = ip6af->ip6af_offset - sizeof(struct ip6_frag);
free(ip6af, M_FTABLE);
diff --git a/freebsd/sys/netinet6/icmp6.c b/freebsd/sys/netinet6/icmp6.c
index 14ce2b3b..48066467 100644
--- a/freebsd/sys/netinet6/icmp6.c
+++ b/freebsd/sys/netinet6/icmp6.c
@@ -43,7 +43,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -2161,7 +2161,7 @@ icmp6_reflect(struct mbuf *m, size_t off)
* source address of the erroneous packet.
*/
in6_splitscope(&ip6->ip6_src, &dst6, &scopeid);
- error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6,
+ error = in6_selectsrc_addr(M_GETFIB(m), &dst6,
scopeid, NULL, &src6, &hlim);
if (error) {
@@ -2303,7 +2303,7 @@ icmp6_redirect_input(struct mbuf *m, int off)
uint32_t scopeid;
in6_splitscope(&reddst6, &kdst, &scopeid);
- if (fib6_lookup_nh_basic(RT_DEFAULT_FIB, &kdst, scopeid, 0, 0,&nh6)==0){
+ if (fib6_lookup_nh_basic(ifp->if_fib, &kdst, scopeid, 0, 0,&nh6)==0){
if ((nh6.nh_flags & NHF_GATEWAY) == 0) {
nd6log((LOG_ERR,
"ICMP6 redirect rejected; no route "
diff --git a/freebsd/sys/netinet6/in6.c b/freebsd/sys/netinet6/in6.c
index 8a4c3663..bc390e50 100644
--- a/freebsd/sys/netinet6/in6.c
+++ b/freebsd/sys/netinet6/in6.c
@@ -43,7 +43,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -163,6 +163,7 @@ in6_newaddrmsg(struct in6_ifaddr *ia, int cmd)
struct sockaddr_dl gateway;
struct sockaddr_in6 mask, addr;
struct rtentry rt;
+ int fibnum;
/*
* initialize for rtmsg generation
@@ -180,8 +181,9 @@ in6_newaddrmsg(struct in6_ifaddr *ia, int cmd)
rt.rt_flags = RTF_HOST | RTF_STATIC;
if (cmd == RTM_ADD)
rt.rt_flags |= RTF_UP;
- /* Announce arrival of local address to all FIBs. */
- rt_newaddrmsg(cmd, &ia->ia_ifa, 0, &rt);
+ fibnum = V_rt_add_addr_allfibs ? RT_ALL_FIBS : ia62ifa(ia)->ifa_ifp->if_fib;
+ /* Announce arrival of local address to this FIB. */
+ rt_newaddrmsg_fib(cmd, &ia->ia_ifa, 0, &rt, fibnum);
}
int
@@ -558,8 +560,11 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
*/
if ((error = in6_update_ifa(ifp, ifra, ia, 0)) != 0)
goto out;
- if (ia != NULL)
+ if (ia != NULL) {
+ if (ia->ia_ifa.ifa_carp)
+ (*carp_detach_p)(&ia->ia_ifa, true);
ifa_free(&ia->ia_ifa);
+ }
if ((ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr))
== NULL) {
/*
@@ -626,7 +631,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
*/
if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0) {
if (carp_attached)
- (*carp_detach_p)(&ia->ia_ifa);
+ (*carp_detach_p)(&ia->ia_ifa, false);
goto out;
}
}
@@ -1247,7 +1252,7 @@ in6_purgeaddr(struct ifaddr *ifa)
int plen, error;
if (ifa->ifa_carp)
- (*carp_detach_p)(ifa);
+ (*carp_detach_p)(ifa, false);
/*
* Remove the loopback route to the interface address.
@@ -1963,7 +1968,6 @@ in6_if2idlen(struct ifnet *ifp)
case IFT_ETHER: /* RFC2464 */
case IFT_PROPVIRTUAL: /* XXX: no RFC. treat it as ether */
case IFT_L2VLAN: /* ditto */
- case IFT_IEEE80211: /* ditto */
case IFT_BRIDGE: /* bridge(4) only does Ethernet-like links */
case IFT_INFINIBAND:
return (64);
@@ -2119,15 +2123,15 @@ in6_lltable_rtcheck(struct ifnet *ifp,
uint32_t scopeid;
int error;
char ip6buf[INET6_ADDRSTRLEN];
+ int fibnum;
KASSERT(l3addr->sa_family == AF_INET6,
("sin_family %d", l3addr->sa_family));
- /* Our local addresses are always only installed on the default FIB. */
-
sin6 = (const struct sockaddr_in6 *)l3addr;
in6_splitscope(&sin6->sin6_addr, &dst, &scopeid);
- error = fib6_lookup_nh_basic(RT_DEFAULT_FIB, &dst, scopeid, 0, 0, &nh6);
+ fibnum = V_rt_add_addr_allfibs ? RT_DEFAULT_FIB : ifp->if_fib;
+ error = fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6);
if (error != 0 || (nh6.nh_flags & NHF_GATEWAY) || nh6.nh_ifp != ifp) {
struct ifaddr *ifa;
/*
diff --git a/freebsd/sys/netinet6/in6.h b/freebsd/sys/netinet6/in6.h
index 62c5e0b0..ed26a7cd 100644
--- a/freebsd/sys/netinet6/in6.h
+++ b/freebsd/sys/netinet6/in6.h
@@ -41,7 +41,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -432,10 +432,7 @@ struct route_in6 {
#define IPV6_BINDV6ONLY IPV6_V6ONLY
#endif
-#if 1 /* IPSEC */
#define IPV6_IPSEC_POLICY 28 /* struct; get/set security policy */
-#endif /* IPSEC */
-
/* 29; unused; was IPV6_FAITH */
#if 1 /* IPV6FIREWALL */
#define IPV6_FW_ADD 30 /* add a firewall rule to chain */
@@ -500,6 +497,9 @@ struct route_in6 {
#define IPV6_RECVFLOWID 70 /* bool; receive IP6 flowid/flowtype w/ datagram */
#define IPV6_RECVRSSBUCKETID 71 /* bool; receive IP6 RSS bucket id w/ datagram */
+#define IPV6_ORIGDSTADDR 72 /* bool: allow getting dstaddr /port info */
+#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR
+
/*
* The following option is private; do not use it from user applications.
* It is deliberately defined to the same value as IP_MSFILTER.
diff --git a/freebsd/sys/netinet6/in6_cksum.c b/freebsd/sys/netinet6/in6_cksum.c
index 6eebdadc..14e5dd30 100644
--- a/freebsd/sys/netinet6/in6_cksum.c
+++ b/freebsd/sys/netinet6/in6_cksum.c
@@ -43,7 +43,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet6/in6_fib.c b/freebsd/sys/netinet6/in6_fib.c
index 824db1fc..3c94b0c5 100644
--- a/freebsd/sys/netinet6/in6_fib.c
+++ b/freebsd/sys/netinet6/in6_fib.c
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet6/in6_fib.h b/freebsd/sys/netinet6/in6_fib.h
index 3d58cd22..53f35a84 100644
--- a/freebsd/sys/netinet6/in6_fib.h
+++ b/freebsd/sys/netinet6/in6_fib.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet6/in6_ifattach.c b/freebsd/sys/netinet6/in6_ifattach.c
index 879336a4..88bd95d4 100644
--- a/freebsd/sys/netinet6/in6_ifattach.c
+++ b/freebsd/sys/netinet6/in6_ifattach.c
@@ -282,7 +282,6 @@ found:
case IFT_ISO88025:
case IFT_ATM:
case IFT_IEEE1394:
- case IFT_IEEE80211:
/* IEEE802/EUI64 cases - what others? */
/* IEEE1394 uses 16byte length address starting with EUI64 */
if (addrlen > 8)
diff --git a/freebsd/sys/netinet6/in6_pcb.c b/freebsd/sys/netinet6/in6_pcb.c
index 95e376c7..960d8d1f 100644
--- a/freebsd/sys/netinet6/in6_pcb.c
+++ b/freebsd/sys/netinet6/in6_pcb.c
@@ -47,7 +47,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -1281,7 +1281,7 @@ in6_pcblookup_mbuf(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
}
void
-init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m)
+init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m, int srcordst)
{
struct ip6_hdr *ip;
@@ -1289,7 +1289,7 @@ init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m)
bzero(sin6, sizeof(*sin6));
sin6->sin6_len = sizeof(*sin6);
sin6->sin6_family = AF_INET6;
- sin6->sin6_addr = ip->ip6_src;
+ sin6->sin6_addr = srcordst ? ip->ip6_dst : ip->ip6_src;
(void)sa6_recoverscope(sin6); /* XXX: should catch errors... */
diff --git a/freebsd/sys/netinet6/in6_pcb.h b/freebsd/sys/netinet6/in6_pcb.h
index e758dace..f21230bc 100644
--- a/freebsd/sys/netinet6/in6_pcb.h
+++ b/freebsd/sys/netinet6/in6_pcb.h
@@ -41,7 +41,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -113,7 +113,7 @@ int in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam);
int in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam);
int in6_selecthlim(struct in6pcb *, struct ifnet *);
int in6_pcbsetport(struct in6_addr *, struct inpcb *, struct ucred *);
-void init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m);
+void init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m, int);
#endif /* _KERNEL */
#endif /* !_NETINET6_IN6_PCB_H_ */
diff --git a/freebsd/sys/netinet6/in6_proto.c b/freebsd/sys/netinet6/in6_proto.c
index 8a9c1cd9..03bbbeac 100644
--- a/freebsd/sys/netinet6/in6_proto.c
+++ b/freebsd/sys/netinet6/in6_proto.c
@@ -43,7 +43,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -123,11 +123,6 @@ __FBSDID("$FreeBSD$");
#include <netinet6/sctp6_var.h>
#endif /* SCTP */
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/ipsec6.h>
-#endif /* IPSEC */
-
#include <netinet6/ip6protosw.h>
/*
@@ -192,7 +187,7 @@ struct protosw inet6sw[] = {
.pr_type = SOCK_SEQPACKET,
.pr_domain = &inet6domain,
.pr_protocol = IPPROTO_SCTP,
- .pr_flags = PR_WANTRCVD,
+ .pr_flags = PR_WANTRCVD|PR_LASTHDR,
.pr_input = sctp6_input,
.pr_ctlinput = sctp6_ctlinput,
.pr_ctloutput = sctp_ctloutput,
@@ -206,7 +201,7 @@ struct protosw inet6sw[] = {
.pr_type = SOCK_STREAM,
.pr_domain = &inet6domain,
.pr_protocol = IPPROTO_SCTP,
- .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD,
+ .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_LASTHDR,
.pr_input = sctp6_input,
.pr_ctlinput = sctp6_ctlinput,
.pr_ctloutput = sctp_ctloutput,
@@ -278,33 +273,6 @@ struct protosw inet6sw[] = {
.pr_input = frag6_input,
.pr_usrreqs = &nousrreqs
},
-#ifdef IPSEC
-{
- .pr_type = SOCK_RAW,
- .pr_domain = &inet6domain,
- .pr_protocol = IPPROTO_AH,
- .pr_flags = PR_ATOMIC|PR_ADDR,
- .pr_input = ipsec6_common_input,
- .pr_usrreqs = &nousrreqs,
-},
-{
- .pr_type = SOCK_RAW,
- .pr_domain = &inet6domain,
- .pr_protocol = IPPROTO_ESP,
- .pr_flags = PR_ATOMIC|PR_ADDR,
- .pr_input = ipsec6_common_input,
- .pr_ctlinput = esp6_ctlinput,
- .pr_usrreqs = &nousrreqs,
-},
-{
- .pr_type = SOCK_RAW,
- .pr_domain = &inet6domain,
- .pr_protocol = IPPROTO_IPCOMP,
- .pr_flags = PR_ATOMIC|PR_ADDR,
- .pr_input = ipsec6_common_input,
- .pr_usrreqs = &nousrreqs,
-},
-#endif /* IPSEC */
#ifdef INET
{
.pr_type = SOCK_RAW,
@@ -472,7 +440,7 @@ SYSCTL_NODE(_net_inet6, IPPROTO_TCP, tcp6, CTLFLAG_RW, 0, "TCP6");
#ifdef SCTP
SYSCTL_NODE(_net_inet6, IPPROTO_SCTP, sctp6, CTLFLAG_RW, 0, "SCTP6");
#endif
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
SYSCTL_NODE(_net_inet6, IPPROTO_ESP, ipsec6, CTLFLAG_RW, 0, "IPSEC6");
#endif /* IPSEC */
@@ -509,19 +477,21 @@ sysctl_ip6_tempvltime(SYSCTL_HANDLER_ARGS)
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_FORWARDING, forwarding,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_forwarding), 0,
- "Enable IPv6 forwarding between interfaces");
+ "Enable forwarding of IPv6 packets between interfaces");
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_SENDREDIRECTS, redirect,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_sendredirects), 0,
- "Send a redirect message when forwarding back to a source link");
+ "Send ICMPv6 redirects for unforwardable IPv6 packets");
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFHLIM, hlim,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_defhlim), 0,
- "Default hop limit");
+ "Default hop limit to use for outgoing IPv6 packets");
SYSCTL_VNET_PCPUSTAT(_net_inet6_ip6, IPV6CTL_STATS, stats, struct ip6stat,
ip6stat,
"IP6 statistics (struct ip6stat, netinet6/ip6_var.h)");
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGPACKETS, maxfragpackets,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_maxfragpackets), 0,
- "Maximum allowed number of outstanding fragmented IPv6 packets");
+ "Default maximum number of outstanding fragmented IPv6 packets. "
+ "A value of 0 means no fragmented packets will be accepted, while a "
+ "a value of -1 means no limit");
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_ACCEPT_RTADV, accept_rtadv,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_accept_rtadv), 0,
"Default value of per-interface flag for accepting ICMPv6 RA messages");
@@ -543,7 +513,8 @@ SYSCTL_INT(_net_inet6_ip6, IPV6CTL_LOG_INTERVAL, log_interval,
"Frequency in seconds at which to log IPv6 forwarding errors");
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_HDRNESTLIMIT, hdrnestlimit,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_hdrnestlimit), 0,
- "Maximum allowed number of nested protocol headers");
+ "Default maximum number of IPv6 extension headers permitted on "
+ "incoming IPv6 packets, 0 for no artificial limit");
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DAD_COUNT, dad_count,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_dad_count), 0,
"Number of ICMPv6 NS messages sent during duplicate address detection");
@@ -552,7 +523,8 @@ SYSCTL_INT(_net_inet6_ip6, IPV6CTL_AUTO_FLOWLABEL, auto_flowlabel,
"Provide an IPv6 flowlabel in outbound packets");
SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFMCASTHLIM, defmcasthlim,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_defmcasthlim), 0,
- "Default hop limit for multicast packets");
+ "Default hop limit for IPv6 multicast packets originating from this "
+ "node");
SYSCTL_STRING(_net_inet6_ip6, IPV6CTL_KAME_VERSION, kame_version,
CTLFLAG_RD, __KAME_VERSION, 0,
"KAME version string");
diff --git a/freebsd/sys/netinet6/in6_src.c b/freebsd/sys/netinet6/in6_src.c
index 2a50a975..cae96274 100644
--- a/freebsd/sys/netinet6/in6_src.c
+++ b/freebsd/sys/netinet6/in6_src.c
@@ -43,7 +43,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -299,7 +299,7 @@ in6_selectsrc(uint32_t fibnum, struct sockaddr_in6 *dstsock,
*/
/* get the outgoing interface */
if ((error = in6_selectif(dstsock, opts, mopts, &ifp, oifp,
- (inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB)) != 0)
+ (inp != NULL) ? inp->inp_inc.inc_fibnum : fibnum)) != 0)
return (error);
#ifdef DIAGNOSTIC
@@ -565,7 +565,7 @@ in6_selectsrc_socket(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
uint32_t fibnum;
int error;
- fibnum = (inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB;
+ fibnum = inp->inp_inc.inc_fibnum;
retifp = NULL;
error = in6_selectsrc(fibnum, dstsock, opts, inp, cred, &retifp, srcp);
diff --git a/freebsd/sys/netinet6/in6_var.h b/freebsd/sys/netinet6/in6_var.h
index d7c10384..a3dac7f4 100644
--- a/freebsd/sys/netinet6/in6_var.h
+++ b/freebsd/sys/netinet6/in6_var.h
@@ -41,7 +41,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet6/ip6_forward.c b/freebsd/sys/netinet6/ip6_forward.c
index b57d31fa..f3e6c11c 100644
--- a/freebsd/sys/netinet6/ip6_forward.c
+++ b/freebsd/sys/netinet6/ip6_forward.c
@@ -71,12 +71,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/in_pcb.h>
-#ifdef IPSEC
-#include <netinet6/ip6_ipsec.h>
-#include <netipsec/ipsec.h>
-#include <netipsec/ipsec6.h>
-#include <netipsec/key.h>
-#endif /* IPSEC */
+#include <netipsec/ipsec_support.h>
/*
* Forward a packet. If some error occurs return the sender
@@ -102,9 +97,6 @@ ip6_forward(struct mbuf *m, int srcrt)
struct ifnet *origifp; /* maybe unnecessary */
u_int32_t inzone, outzone;
struct in6_addr src_in6, dst_in6, odst;
-#ifdef IPSEC
- struct secpolicy *sp = NULL;
-#endif
struct m_tag *fwd_tag;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
@@ -132,32 +124,17 @@ ip6_forward(struct mbuf *m, int srcrt)
m_freem(m);
return;
}
-#ifdef IPSEC
- /*
- * Check if this packet has an active SA and needs to be dropped
- * instead of forwarded.
- */
- if (ip6_ipsec_fwd(m) != 0) {
- IP6STAT_INC(ip6s_cantforward);
- m_freem(m);
- return;
- }
-#endif /* IPSEC */
+ if (
#ifdef IPSTEALTH
- if (!V_ip6stealth) {
+ V_ip6stealth == 0 &&
#endif
- if (ip6->ip6_hlim <= IPV6_HLIMDEC) {
+ ip6->ip6_hlim <= IPV6_HLIMDEC) {
/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */
icmp6_error(m, ICMP6_TIME_EXCEEDED,
- ICMP6_TIME_EXCEED_TRANSIT, 0);
+ ICMP6_TIME_EXCEED_TRANSIT, 0);
return;
}
- ip6->ip6_hlim -= IPV6_HLIMDEC;
-
-#ifdef IPSTEALTH
- }
-#endif
/*
* Save at most ICMPV6_PLD_MAXLEN (= the min IPv6 MTU -
@@ -170,167 +147,22 @@ ip6_forward(struct mbuf *m, int srcrt)
*/
mcopy = m_copym(m, 0, imin(m->m_pkthdr.len, ICMPV6_PLD_MAXLEN),
M_NOWAIT);
-
-#ifdef IPSEC
- /* get a security policy for this packet */
- sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, &error);
- if (sp == NULL) {
- IPSEC6STAT_INC(ips_out_inval);
- IP6STAT_INC(ip6s_cantforward);
- if (mcopy) {
-#if 0
- /* XXX: what icmp ? */
-#else
- m_freem(mcopy);
+#ifdef IPSTEALTH
+ if (V_ip6stealth == 0)
#endif
- }
- m_freem(m);
- return;
- }
-
- error = 0;
+ ip6->ip6_hlim -= IPV6_HLIMDEC;
- /* check policy */
- switch (sp->policy) {
- case IPSEC_POLICY_DISCARD:
- /*
- * This packet is just discarded.
- */
- IPSEC6STAT_INC(ips_out_polvio);
- IP6STAT_INC(ip6s_cantforward);
- KEY_FREESP(&sp);
- if (mcopy) {
-#if 0
- /* XXX: what icmp ? */
-#else
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ if (IPSEC_ENABLED(ipv6)) {
+ if ((error = IPSEC_FORWARD(ipv6, m)) != 0) {
+ /* mbuf consumed by IPsec */
m_freem(mcopy);
-#endif
- }
- m_freem(m);
- return;
-
- case IPSEC_POLICY_BYPASS:
- case IPSEC_POLICY_NONE:
- /* no need to do IPsec. */
- KEY_FREESP(&sp);
- goto skip_ipsec;
-
- case IPSEC_POLICY_IPSEC:
- if (sp->req == NULL) {
- /* XXX should be panic ? */
- printf("ip6_forward: No IPsec request specified.\n");
- IP6STAT_INC(ip6s_cantforward);
- KEY_FREESP(&sp);
- if (mcopy) {
-#if 0
- /* XXX: what icmp ? */
-#else
- m_freem(mcopy);
-#endif
- }
- m_freem(m);
+ if (error != EINPROGRESS)
+ IP6STAT_INC(ip6s_cantforward);
return;
}
- /* do IPsec */
- break;
-
- case IPSEC_POLICY_ENTRUST:
- default:
- /* should be panic ?? */
- printf("ip6_forward: Invalid policy found. %d\n", sp->policy);
- KEY_FREESP(&sp);
- goto skip_ipsec;
+ /* No IPsec processing required */
}
-
- {
- struct ipsecrequest *isr = NULL;
-
- /*
- * when the kernel forwards a packet, it is not proper to apply
- * IPsec transport mode to the packet. This check avoid from this.
- * at present, if there is even a transport mode SA request in the
- * security policy, the kernel does not apply IPsec to the packet.
- * this check is not enough because the following case is valid.
- * ipsec esp/tunnel/xxx-xxx/require esp/transport//require;
- */
- for (isr = sp->req; isr; isr = isr->next) {
- if (isr->saidx.mode == IPSEC_MODE_ANY)
- goto doipsectunnel;
- if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
- goto doipsectunnel;
- }
-
- /*
- * if there's no need for tunnel mode IPsec, skip.
- */
- if (!isr)
- goto skip_ipsec;
-
- doipsectunnel:
- /*
- * All the extension headers will become inaccessible
- * (since they can be encrypted).
- * Don't panic, we need no more updates to extension headers
- * on inner IPv6 packet (since they are now encapsulated).
- *
- * IPv6 [ESP|AH] IPv6 [extension headers] payload
- */
-
- /*
- * If we need to encapsulate the packet, do it here
- * ipsec6_proces_packet will send the packet using ip6_output
- */
- error = ipsec6_process_packet(m, sp->req);
- /* Release SP if an error occurred */
- if (error != 0)
- KEY_FREESP(&sp);
- if (error == EJUSTRETURN) {
- /*
- * We had a SP with a level of 'use' and no SA. We
- * will just continue to process the packet without
- * IPsec processing.
- */
- error = 0;
- goto skip_ipsec;
- }
-
- if (error) {
- /* mbuf is already reclaimed in ipsec6_process_packet. */
- switch (error) {
- case EHOSTUNREACH:
- case ENETUNREACH:
- case EMSGSIZE:
- case ENOBUFS:
- case ENOMEM:
- break;
- default:
- printf("ip6_output (ipsec): error code %d\n", error);
- /* FALLTHROUGH */
- case ENOENT:
- /* don't show these error codes to the user */
- break;
- }
- IP6STAT_INC(ip6s_cantforward);
- if (mcopy) {
-#if 0
- /* XXX: what icmp ? */
-#else
- m_freem(mcopy);
-#endif
- }
- return;
- } else {
- /*
- * In the FAST IPSec case we have already
- * re-injected the packet and it has been freed
- * by the ipsec_done() function. So, just clean
- * up after ourselves.
- */
- m = NULL;
- goto freecopy;
- }
- }
-skip_ipsec:
#endif
again:
bzero(&rin6, sizeof(struct route_in6));
@@ -542,34 +374,9 @@ pass:
/* See if the size was changed by the packet filter. */
if (m->m_pkthdr.len > IN6_LINKMTU(rt->rt_ifp)) {
in6_ifstat_inc(rt->rt_ifp, ifs6_in_toobig);
- if (mcopy) {
- u_long mtu;
-#ifdef IPSEC
- size_t ipsechdrsiz;
-#endif /* IPSEC */
-
- mtu = IN6_LINKMTU(rt->rt_ifp);
-#ifdef IPSEC
- /*
- * When we do IPsec tunnel ingress, we need to play
- * with the link value (decrement IPsec header size
- * from mtu value). The code is much simpler than v4
- * case, as we have the outgoing interface for
- * encapsulated packet as "rt->rt_ifp".
- */
- ipsechdrsiz = ipsec_hdrsiz(mcopy, IPSEC_DIR_OUTBOUND,
- NULL);
- if (ipsechdrsiz < mtu)
- mtu -= ipsechdrsiz;
- /*
- * if mtu becomes less than minimum MTU,
- * tell minimum MTU (and I'll need to fragment it).
- */
- if (mtu < IPV6_MMTU)
- mtu = IPV6_MMTU;
-#endif /* IPSEC */
- icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0, mtu);
- }
+ if (mcopy)
+ icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0,
+ IN6_LINKMTU(rt->rt_ifp));
goto bad;
}
diff --git a/freebsd/sys/netinet6/ip6_input.c b/freebsd/sys/netinet6/ip6_input.c
index e34ac0e6..5ef0e29a 100644
--- a/freebsd/sys/netinet6/ip6_input.c
+++ b/freebsd/sys/netinet6/ip6_input.c
@@ -43,7 +43,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -120,12 +120,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/nd6.h>
#include <netinet6/in6_rss.h>
-#ifdef IPSEC
-#include <netipsec/key.h>
-#include <netipsec/ipsec.h>
-#include <netinet6/ip6_ipsec.h>
-#include <netipsec/ipsec6.h>
-#endif /* IPSEC */
+#include <netipsec/ipsec_support.h>
#include <netinet6/ip6protosw.h>
@@ -527,14 +522,11 @@ ip6_direct_input(struct mbuf *m)
goto bad;
}
-#ifdef IPSEC
- /*
- * enforce IPsec policy checking if we are seeing last header.
- * note that we do not visit this with protocols with pcb layer
- * code - like udp/tcp/raw ip.
- */
- if (ip6_ipsec_input(m, nxt))
- goto bad;
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ if (IPSEC_ENABLED(ipv6)) {
+ if (IPSEC_INPUT(ipv6, m, off, nxt) != 0)
+ return;
+ }
#endif /* IPSEC */
nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
@@ -565,7 +557,7 @@ ip6_input(struct mbuf *m)
if ((ND_IFINFO(rcvif)->flags & ND6_IFF_IFDISABLED))
goto bad;
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/*
* should the inner packet be considered authentic?
* see comment in ah4_input().
@@ -737,9 +729,9 @@ ip6_input(struct mbuf *m)
* ip6 pointer.
*/
if (V_ip6_forwarding != 0
-#ifdef IPSEC
- && !key_havesp(IPSEC_DIR_INBOUND)
- && !key_havesp(IPSEC_DIR_OUTBOUND)
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ && (!IPSEC_ENABLED(ipv6) ||
+ IPSEC_CAPS(ipv6, m, IPSEC_CAP_OPERABLE) == 0)
#endif
) {
if ((m = ip6_tryforward(m)) == NULL)
@@ -751,12 +743,13 @@ ip6_input(struct mbuf *m)
goto hbhcheck;
}
}
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/*
* Bypass packet filtering for packets previously handled by IPsec.
*/
- if (ip6_ipsec_filtertunnel(m))
- goto passin;
+ if (IPSEC_ENABLED(ipv6) &&
+ IPSEC_CAPS(ipv6, m, IPSEC_CAP_BYPASS_FILTER) != 0)
+ goto passin;
#endif
/*
* Run through list of hooks for input packets.
@@ -964,14 +957,11 @@ passin:
goto bad;
}
-#ifdef IPSEC
- /*
- * enforce IPsec policy checking if we are seeing last header.
- * note that we do not visit this with protocols with pcb layer
- * code - like udp/tcp/raw ip.
- */
- if (ip6_ipsec_input(m, nxt))
- goto bad;
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ if (IPSEC_ENABLED(ipv6)) {
+ if (IPSEC_INPUT(ipv6, m, off, nxt) != 0)
+ return;
+ }
#endif /* IPSEC */
nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
@@ -1228,13 +1218,48 @@ ip6_savecontrol_v4(struct inpcb *inp, struct mbuf *m, struct mbuf **mp,
#ifdef SO_TIMESTAMP
if ((inp->inp_socket->so_options & SO_TIMESTAMP) != 0) {
- struct timeval tv;
+ union {
+ struct timeval tv;
+ struct bintime bt;
+ struct timespec ts;
+ } t;
+
+ switch (inp->inp_socket->so_ts_clock) {
+ case SO_TS_REALTIME_MICRO:
+ microtime(&t.tv);
+ *mp = sbcreatecontrol((caddr_t) &t.tv, sizeof(t.tv),
+ SCM_TIMESTAMP, SOL_SOCKET);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ break;
- microtime(&tv);
- *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
- SCM_TIMESTAMP, SOL_SOCKET);
- if (*mp)
- mp = &(*mp)->m_next;
+ case SO_TS_BINTIME:
+ bintime(&t.bt);
+ *mp = sbcreatecontrol((caddr_t)&t.bt, sizeof(t.bt),
+ SCM_BINTIME, SOL_SOCKET);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ break;
+
+ case SO_TS_REALTIME:
+ nanotime(&t.ts);
+ *mp = sbcreatecontrol((caddr_t)&t.ts, sizeof(t.ts),
+ SCM_REALTIME, SOL_SOCKET);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ break;
+
+ case SO_TS_MONOTONIC:
+ nanouptime(&t.ts);
+ *mp = sbcreatecontrol((caddr_t)&t.ts, sizeof(t.ts),
+ SCM_MONOTONIC, SOL_SOCKET);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ break;
+
+ default:
+ panic("unknown (corrupted) so_ts_clock");
+ }
}
#endif
diff --git a/freebsd/sys/netinet6/ip6_ipsec.c b/freebsd/sys/netinet6/ip6_ipsec.c
deleted file mode 100644
index fe61dab9..00000000
--- a/freebsd/sys/netinet6/ip6_ipsec.c
+++ /dev/null
@@ -1,393 +0,0 @@
-#include <machine/rtems-bsd-kernel-space.h>
-
-/*-
- * Copyright (c) 1982, 1986, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <rtems/bsd/local/opt_inet.h>
-#include <rtems/bsd/local/opt_inet6.h>
-#include <rtems/bsd/local/opt_ipsec.h>
-
-#include <rtems/bsd/sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/mac.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/sysctl.h>
-#include <sys/syslog.h>
-
-#include <net/if.h>
-#include <net/route.h>
-#include <net/vnet.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/in_pcb.h>
-#include <netinet/ip_var.h>
-#include <netinet/ip_options.h>
-
-#include <machine/in_cksum.h>
-
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/ipsec6.h>
-#include <netipsec/xform.h>
-#include <netipsec/key.h>
-#ifdef IPSEC_DEBUG
-#include <netipsec/key_debug.h>
-#else
-#define KEYDEBUG(lev,arg)
-#endif
-#endif /*IPSEC*/
-
-#include <netinet6/ip6_ipsec.h>
-#include <netinet6/ip6_var.h>
-
-extern struct protosw inet6sw[];
-
-
-#ifdef INET6
-#ifdef IPSEC
-#ifdef IPSEC_FILTERTUNNEL
-static VNET_DEFINE(int, ip6_ipsec6_filtertunnel) = 1;
-#else
-static VNET_DEFINE(int, ip6_ipsec6_filtertunnel) = 0;
-#endif
-#define V_ip6_ipsec6_filtertunnel VNET(ip6_ipsec6_filtertunnel)
-
-SYSCTL_DECL(_net_inet6_ipsec6);
-SYSCTL_VNET_INT(_net_inet6_ipsec6, OID_AUTO,
- filtertunnel, CTLFLAG_RW, &VNET_NAME(ip6_ipsec6_filtertunnel), 0,
- "If set filter packets from an IPsec tunnel.");
-#endif /* IPSEC */
-#endif /* INET6 */
-
-/*
- * Check if we have to jump over firewall processing for this packet.
- * Called from ip6_input().
- * 1 = jump over firewall, 0 = packet goes through firewall.
- */
-int
-ip6_ipsec_filtertunnel(struct mbuf *m)
-{
-#if defined(IPSEC)
-
- /*
- * Bypass packet filtering for packets previously handled by IPsec.
- */
- if (!V_ip6_ipsec6_filtertunnel &&
- m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL)
- return 1;
-#endif
- return 0;
-}
-
-/*
- * Check if this packet has an active SA and needs to be dropped instead
- * of forwarded.
- * Called from ip6_input().
- * 1 = drop packet, 0 = forward packet.
- */
-int
-ip6_ipsec_fwd(struct mbuf *m)
-{
-#ifdef IPSEC
- struct m_tag *mtag;
- struct tdb_ident *tdbi;
- struct secpolicy *sp;
- int s, error;
- mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
- s = splnet();
- if (mtag != NULL) {
- tdbi = (struct tdb_ident *)(mtag + 1);
- sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND);
- } else {
- sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
- IP_FORWARDING, &error);
- }
- if (sp == NULL) { /* NB: can happen if error */
- splx(s);
- /*XXX error stat???*/
- DPRINTF(("%s: no SP for forwarding\n", __func__)); /*XXX*/
- return 1;
- }
-
- /*
- * Check security policy against packet attributes.
- */
- error = ipsec_in_reject(sp, m);
- KEY_FREESP(&sp);
- splx(s);
- if (error) {
- IP6STAT_INC(ip6s_cantforward);
- return 1;
- }
-#endif /* IPSEC */
- return 0;
-}
-
-/*
- * Check if protocol type doesn't have a further header and do IPSEC
- * decryption or reject right now. Protocols with further headers get
- * their IPSEC treatment within the protocol specific processing.
- * Called from ip6_input().
- * 1 = drop packet, 0 = continue processing packet.
- */
-int
-ip6_ipsec_input(struct mbuf *m, int nxt)
-{
-#ifdef IPSEC
- struct m_tag *mtag;
- struct tdb_ident *tdbi;
- struct secpolicy *sp;
- int s, error;
- /*
- * enforce IPsec policy checking if we are seeing last header.
- * note that we do not visit this with protocols with pcb layer
- * code - like udp/tcp/raw ip.
- */
- if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
- ipsec6_in_reject(m, NULL)) {
-
- /*
- * Check if the packet has already had IPsec processing
- * done. If so, then just pass it along. This tag gets
- * set during AH, ESP, etc. input handling, before the
- * packet is returned to the ip input queue for delivery.
- */
- mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
- s = splnet();
- if (mtag != NULL) {
- tdbi = (struct tdb_ident *)(mtag + 1);
- sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND);
- } else {
- sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
- IP_FORWARDING, &error);
- }
- if (sp != NULL) {
- /*
- * Check security policy against packet attributes.
- */
- error = ipsec_in_reject(sp, m);
- KEY_FREESP(&sp);
- } else {
- /* XXX error stat??? */
- error = EINVAL;
- DPRINTF(("%s: no SP, packet discarded\n", __func__));/*XXX*/
- return 1;
- }
- splx(s);
- if (error)
- return 1;
- }
-#endif /* IPSEC */
- return 0;
-}
-
-/*
- * Called from ip6_output().
- * 1 = drop packet, 0 = continue processing packet,
- * -1 = packet was reinjected and stop processing packet
- */
-
-int
-ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error,
- struct ifnet **ifp, struct secpolicy **sp)
-{
-#ifdef IPSEC
- struct tdb_ident *tdbi;
- struct m_tag *mtag;
- /* XXX int s; */
- if (sp == NULL)
- return 1;
- mtag = m_tag_find(*m, PACKET_TAG_IPSEC_PENDING_TDB, NULL);
- if (mtag != NULL) {
- tdbi = (struct tdb_ident *)(mtag + 1);
- *sp = ipsec_getpolicy(tdbi, IPSEC_DIR_OUTBOUND);
- if (*sp == NULL)
- *error = -EINVAL; /* force silent drop */
- m_tag_delete(*m, mtag);
- } else {
- *sp = ipsec4_checkpolicy(*m, IPSEC_DIR_OUTBOUND, *flags,
- error, inp);
- }
-
- /*
- * There are four return cases:
- * sp != NULL apply IPsec policy
- * sp == NULL, error == 0 no IPsec handling needed
- * sp == NULL, error == -EINVAL discard packet w/o error
- * sp == NULL, error != 0 discard packet, report error
- */
- if (*sp != NULL) {
- /* Loop detection, check if ipsec processing already done */
- KASSERT((*sp)->req != NULL, ("ip_output: no ipsec request"));
- for (mtag = m_tag_first(*m); mtag != NULL;
- mtag = m_tag_next(*m, mtag)) {
- if (mtag->m_tag_cookie != MTAG_ABI_COMPAT)
- continue;
- if (mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_DONE &&
- mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED)
- continue;
- /*
- * Check if policy has no SA associated with it.
- * This can happen when an SP has yet to acquire
- * an SA; e.g. on first reference. If it occurs,
- * then we let ipsec4_process_packet do its thing.
- */
- if ((*sp)->req->sav == NULL)
- break;
- tdbi = (struct tdb_ident *)(mtag + 1);
- if (tdbi->spi == (*sp)->req->sav->spi &&
- tdbi->proto == (*sp)->req->sav->sah->saidx.proto &&
- bcmp(&tdbi->dst, &(*sp)->req->sav->sah->saidx.dst,
- sizeof (union sockaddr_union)) == 0) {
- /*
- * No IPsec processing is needed, free
- * reference to SP.
- *
- * NB: null pointer to avoid free at
- * done: below.
- */
- KEY_FREESP(sp), *sp = NULL;
- /* XXX splx(s); */
- goto done;
- }
- }
-
- /*
- * Do delayed checksums now because we send before
- * this is done in the normal processing path.
- * For IPv6 we do delayed checksums in ip6_output.c.
- */
-#ifdef INET
- if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
- ipseclog((LOG_DEBUG,
- "%s: we do not support IPv4 over IPv6", __func__));
- in_delayed_cksum(*m);
- (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
- }
-#endif
-
- /*
- * Preserve KAME behaviour: ENOENT can be returned
- * when an SA acquire is in progress. Don't propagate
- * this to user-level; it confuses applications.
- *
- * XXX this will go away when the SADB is redone.
- */
- if (*error == ENOENT)
- *error = 0;
- goto do_ipsec;
- } else { /* sp == NULL */
- if (*error != 0) {
- /*
- * Hack: -EINVAL is used to signal that a packet
- * should be silently discarded. This is typically
- * because we asked key management for an SA and
- * it was delayed (e.g. kicked up to IKE).
- */
- if (*error == -EINVAL)
- *error = 0;
- goto bad;
- } else {
- /* No IPsec processing for this packet. */
- }
- }
-done:
- return 0;
-do_ipsec:
- return -1;
-bad:
- return 1;
-#endif /* IPSEC */
- return 0;
-}
-
-#if 0
-/*
- * Compute the MTU for a forwarded packet that gets IPSEC encapsulated.
- * Called from ip_forward().
- * Returns MTU suggestion for ICMP needfrag reply.
- */
-int
-ip6_ipsec_mtu(struct mbuf *m)
-{
- int mtu = 0;
- /*
- * If the packet is routed over IPsec tunnel, tell the
- * originator the tunnel MTU.
- * tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz
- * XXX quickhack!!!
- */
-#ifdef IPSEC
- struct secpolicy *sp = NULL;
- int ipsecerror;
- int ipsechdr;
- struct route *ro;
- sp = ipsec_getpolicybyaddr(m,
- IPSEC_DIR_OUTBOUND,
- IP_FORWARDING,
- &ipsecerror);
- if (sp != NULL) {
- /* count IPsec header size */
- ipsechdr = ipsec_hdrsiz(m, IPSEC_DIR_OUTBOUND, NULL);
-
- /*
- * find the correct route for outer IPv4
- * header, compute tunnel MTU.
- */
- if (sp->req != NULL &&
- sp->req->sav != NULL &&
- sp->req->sav->sah != NULL) {
- ro = &sp->req->sav->sah->route_cache.sa_route;
- if (ro->ro_rt && ro->ro_rt->rt_ifp) {
- mtu =
- ro->ro_rt->rt_rmx.rmx_mtu ?
- ro->ro_rt->rt_rmx.rmx_mtu :
- ro->ro_rt->rt_ifp->if_mtu;
- mtu -= ipsechdr;
- }
- }
- KEY_FREESP(&sp);
- }
-#endif /* IPSEC */
- /* XXX else case missing. */
- return mtu;
-}
-#endif
diff --git a/freebsd/sys/netinet6/ip6_ipsec.h b/freebsd/sys/netinet6/ip6_ipsec.h
deleted file mode 100644
index e335d850..00000000
--- a/freebsd/sys/netinet6/ip6_ipsec.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*-
- * Copyright (c) 1982, 1986, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _NETINET_IP6_IPSEC_H_
-#define _NETINET_IP6_IPSEC_H_
-
-int ip6_ipsec_filtertunnel(struct mbuf *);
-int ip6_ipsec_fwd(struct mbuf *);
-int ip6_ipsec_input(struct mbuf *, int);
-int ip6_ipsec_output(struct mbuf **, struct inpcb *, int *);
-#if 0
-int ip6_ipsec_mtu(struct mbuf *);
-#endif
-#endif
diff --git a/freebsd/sys/netinet6/ip6_mroute.c b/freebsd/sys/netinet6/ip6_mroute.c
index e40ce06c..0a597191 100644
--- a/freebsd/sys/netinet6/ip6_mroute.c
+++ b/freebsd/sys/netinet6/ip6_mroute.c
@@ -47,7 +47,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet6/ip6_output.c b/freebsd/sys/netinet6/ip6_output.c
index 63d1dac1..3be690a4 100644
--- a/freebsd/sys/netinet6/ip6_output.c
+++ b/freebsd/sys/netinet6/ip6_output.c
@@ -43,7 +43,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_inet.h>
#include <rtems/bsd/local/opt_inet6.h>
+#include <rtems/bsd/local/opt_ratelimit.h>
#include <rtems/bsd/local/opt_ipsec.h>
#include <rtems/bsd/local/opt_sctp.h>
#include <rtems/bsd/local/opt_route.h>
@@ -109,12 +110,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/nd6.h>
#include <netinet6/in6_rss.h>
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/ipsec6.h>
-#include <netipsec/key.h>
-#include <netinet6/ip6_ipsec.h>
-#endif /* IPSEC */
+#include <netipsec/ipsec_support.h>
#ifdef SCTP
#include <netinet/sctp.h>
#include <netinet/sctp_crc32.h>
@@ -337,6 +333,21 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
}
}
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ /*
+ * IPSec checking which handles several cases.
+ * FAST IPSEC: We re-injected the packet.
+ * XXX: need scope argument.
+ */
+ if (IPSEC_ENABLED(ipv6)) {
+ if ((error = IPSEC_OUTPUT(ipv6, m, inp)) != 0) {
+ if (error == EINPROGRESS)
+ error = 0;
+ goto done;
+ }
+ }
+#endif /* IPSEC */
+
bzero(&exthdrs, sizeof(exthdrs));
if (opt) {
/* Hop-by-Hop options header */
@@ -361,24 +372,6 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2);
}
-#ifdef IPSEC
- /*
- * IPSec checking which handles several cases.
- * FAST IPSEC: We re-injected the packet.
- * XXX: need scope argument.
- */
- switch(ip6_ipsec_output(&m, inp, &error))
- {
- case 1: /* Bad packet */
- goto freehdrs;
- case -1: /* IPSec done */
- goto done;
- case 0: /* No IPSec */
- default:
- break;
- }
-#endif /* IPSEC */
-
/*
* Calculate the total length of the extension header chain.
* Keep the length of the unfragmentable part for fragmentation.
@@ -503,8 +496,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
if (ro == NULL) {
ro = &ip6route;
bzero((caddr_t)ro, sizeof(*ro));
- } else
- ro->ro_flags |= RT_LLE_CACHE;
+ }
ro_pmtu = ro;
if (opt && opt->ip6po_rthdr)
ro = &opt->ip6po_route;
@@ -956,8 +948,23 @@ passout:
m->m_pkthdr.len);
ifa_free(&ia6->ia_ifa);
}
+#ifdef RATELIMIT
+ if (inp != NULL) {
+ if (inp->inp_flags2 & INP_RATE_LIMIT_CHANGED)
+ in_pcboutput_txrtlmt(inp, ifp, m);
+ /* stamp send tag on mbuf */
+ m->m_pkthdr.snd_tag = inp->inp_snd_tag;
+ } else {
+ m->m_pkthdr.snd_tag = NULL;
+ }
+#endif
error = nd6_output_ifp(ifp, origifp, m, dst,
(struct route *)ro);
+#ifdef RATELIMIT
+ /* check for route change */
+ if (error == EAGAIN)
+ in_pcboutput_eagain(inp);
+#endif
goto done;
}
@@ -1056,8 +1063,23 @@ sendorfree:
counter_u64_add(ia->ia_ifa.ifa_obytes,
m->m_pkthdr.len);
}
+#ifdef RATELIMIT
+ if (inp != NULL) {
+ if (inp->inp_flags2 & INP_RATE_LIMIT_CHANGED)
+ in_pcboutput_txrtlmt(inp, ifp, m);
+ /* stamp send tag on mbuf */
+ m->m_pkthdr.snd_tag = inp->inp_snd_tag;
+ } else {
+ m->m_pkthdr.snd_tag = NULL;
+ }
+#endif
error = nd6_output_ifp(ifp, origifp, m, dst,
(struct route *)ro);
+#ifdef RATELIMIT
+ /* check for route change */
+ if (error == EAGAIN)
+ in_pcboutput_eagain(inp);
+#endif
} else
m_freem(m);
}
@@ -1443,6 +1465,16 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
INP_WUNLOCK(in6p);
error = 0;
break;
+ case SO_MAX_PACING_RATE:
+#ifdef RATELIMIT
+ INP_WLOCK(in6p);
+ in6p->inp_flags2 |= INP_RATE_LIMIT_CHANGED;
+ INP_WUNLOCK(in6p);
+ error = 0;
+#else
+ error = EOPNOTSUPP;
+#endif
+ break;
default:
break;
}
@@ -1514,6 +1546,7 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
#endif
case IPV6_V6ONLY:
case IPV6_AUTOFLOWLABEL:
+ case IPV6_ORIGDSTADDR:
case IPV6_BINDANY:
case IPV6_BINDMULTI:
#ifdef RSS
@@ -1699,6 +1732,9 @@ do { \
OPTSET(IN6P_AUTOFLOWLABEL);
break;
+ case IPV6_ORIGDSTADDR:
+ OPTSET2(INP_ORIGDSTADDR, optval);
+ break;
case IPV6_BINDANY:
OPTSET(INP_BINDANY);
break;
@@ -1873,23 +1909,13 @@ do { \
INP_WUNLOCK(in6p);
break;
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
case IPV6_IPSEC_POLICY:
- {
- caddr_t req;
- struct mbuf *m;
-
- if ((error = soopt_getm(sopt, &m)) != 0) /* XXX */
+ if (IPSEC_ENABLED(ipv6)) {
+ error = IPSEC_PCBCTL(ipv6, in6p, sopt);
break;
- if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */
- break;
- req = mtod(m, caddr_t);
- error = ipsec_set_policy(in6p, optname, req,
- m->m_len, (sopt->sopt_td != NULL) ?
- sopt->sopt_td->td_ucred : NULL);
- m_freem(m);
- break;
- }
+ }
+ /* FALLTHROUGH */
#endif /* IPSEC */
default:
@@ -1997,6 +2023,10 @@ do { \
optval = OPTBIT(IN6P_AUTOFLOWLABEL);
break;
+ case IPV6_ORIGDSTADDR:
+ optval = OPTBIT2(INP_ORIGDSTADDR);
+ break;
+
case IPV6_BINDANY:
optval = OPTBIT(INP_BINDANY);
break;
@@ -2114,37 +2144,14 @@ do { \
error = ip6_getmoptions(in6p, sopt);
break;
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
case IPV6_IPSEC_POLICY:
- {
- caddr_t req = NULL;
- size_t len = 0;
- struct mbuf *m = NULL;
- struct mbuf **mp = &m;
- size_t ovalsize = sopt->sopt_valsize;
- caddr_t oval = (caddr_t)sopt->sopt_val;
-
- error = soopt_getm(sopt, &m); /* XXX */
- if (error != 0)
+ if (IPSEC_ENABLED(ipv6)) {
+ error = IPSEC_PCBCTL(ipv6, in6p, sopt);
break;
- error = soopt_mcopyin(sopt, m); /* XXX */
- if (error != 0)
- break;
- sopt->sopt_valsize = ovalsize;
- sopt->sopt_val = oval;
- if (m) {
- req = mtod(m, caddr_t);
- len = m->m_len;
}
- error = ipsec_get_policy(in6p, req, len, mp);
- if (error == 0)
- error = soopt_mcopyout(sopt, m); /* XXX */
- if (error == 0 && m)
- m_freem(m);
- break;
- }
+ /* FALLTHROUGH */
#endif /* IPSEC */
-
default:
error = ENOPROTOOPT;
break;
diff --git a/freebsd/sys/netinet6/ip6_var.h b/freebsd/sys/netinet6/ip6_var.h
index e52a3206..65bf1e69 100644
--- a/freebsd/sys/netinet6/ip6_var.h
+++ b/freebsd/sys/netinet6/ip6_var.h
@@ -41,7 +41,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet6/ip6protosw.h b/freebsd/sys/netinet6/ip6protosw.h
index 9e80a698..edfbd0ab 100644
--- a/freebsd/sys/netinet6/ip6protosw.h
+++ b/freebsd/sys/netinet6/ip6protosw.h
@@ -41,7 +41,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet6/mld6.c b/freebsd/sys/netinet6/mld6.c
index 26efa852..420b2b4b 100644
--- a/freebsd/sys/netinet6/mld6.c
+++ b/freebsd/sys/netinet6/mld6.c
@@ -46,7 +46,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet6/nd6.c b/freebsd/sys/netinet6/nd6.c
index 757130b8..cb626e5a 100644
--- a/freebsd/sys/netinet6/nd6.c
+++ b/freebsd/sys/netinet6/nd6.c
@@ -159,6 +159,7 @@ nd6_lle_event(void *arg __unused, struct llentry *lle, int evt)
struct sockaddr_dl gw;
struct ifnet *ifp;
int type;
+ int fibnum;
LLE_WLOCK_ASSERT(lle);
@@ -196,8 +197,9 @@ nd6_lle_event(void *arg __unused, struct llentry *lle, int evt)
rtinfo.rti_info[RTAX_DST] = (struct sockaddr *)&dst;
rtinfo.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gw;
rtinfo.rti_addrs = RTA_DST | RTA_GATEWAY;
+ fibnum = V_rt_add_addr_allfibs ? RT_ALL_FIBS : ifp->if_fib;
rt_missmsg_fib(type, &rtinfo, RTF_HOST | RTF_LLDATA | (
- type == RTM_ADD ? RTF_UP: 0), 0, RT_DEFAULT_FIB);
+ type == RTM_ADD ? RTF_UP: 0), 0, fibnum);
}
/*
@@ -1202,7 +1204,7 @@ nd6_purge(struct ifnet *ifp)
if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV) {
/* Refresh default router list. */
- defrouter_select();
+ defrouter_select_fib(ifp->if_fib);
}
}
@@ -1255,7 +1257,7 @@ static int
nd6_is_new_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp)
{
struct nd_prefix *pr;
- struct ifaddr *dstaddr;
+ struct ifaddr *ifa;
struct rt_addrinfo info;
struct sockaddr_in6 rt_key;
const struct sockaddr *dst6;
@@ -1289,9 +1291,6 @@ nd6_is_new_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp)
bzero(&info, sizeof(info));
info.rti_info[RTAX_DST] = (struct sockaddr *)&rt_key;
- /* Always use the default FIB here. XXME - why? */
- fibnum = RT_DEFAULT_FIB;
-
/*
* If the address matches one of our addresses,
* it should be a neighbor.
@@ -1305,19 +1304,31 @@ restart:
continue;
if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
- /* Always use the default FIB here. */
dst6 = (const struct sockaddr *)&pr->ndpr_prefix;
- genid = V_nd6_list_genid;
- ND6_RUNLOCK();
-
- /* Restore length field before retrying lookup */
- rt_key.sin6_len = sizeof(rt_key);
- error = rib_lookup_info(fibnum, dst6, 0, 0, &info);
+ /*
+ * We only need to check all FIBs if add_addr_allfibs
+ * is unset. If set, checking any FIB will suffice.
+ */
+ fibnum = V_rt_add_addr_allfibs ? rt_numfibs - 1 : 0;
+ for (; fibnum < rt_numfibs; fibnum++) {
+ genid = V_nd6_list_genid;
+ ND6_RUNLOCK();
- ND6_RLOCK();
- if (genid != V_nd6_list_genid)
- goto restart;
+ /*
+ * Restore length field before
+ * retrying lookup
+ */
+ rt_key.sin6_len = sizeof(rt_key);
+ error = rib_lookup_info(fibnum, dst6, 0, 0,
+ &info);
+
+ ND6_RLOCK();
+ if (genid != V_nd6_list_genid)
+ goto restart;
+ if (error == 0)
+ break;
+ }
if (error != 0)
continue;
@@ -1348,13 +1359,18 @@ restart:
* If the address is assigned on the node of the other side of
* a p2p interface, the address should be a neighbor.
*/
- dstaddr = ifa_ifwithdstaddr((const struct sockaddr *)addr, RT_ALL_FIBS);
- if (dstaddr != NULL) {
- if (dstaddr->ifa_ifp == ifp) {
- ifa_free(dstaddr);
- return (1);
+ if (ifp->if_flags & IFF_POINTOPOINT) {
+ IF_ADDR_RLOCK(ifp);
+ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+ if (ifa->ifa_addr->sa_family != addr->sin6_family)
+ continue;
+ if (ifa->ifa_dstaddr != NULL &&
+ sa_equal(addr, ifa->ifa_dstaddr)) {
+ IF_ADDR_RUNLOCK(ifp);
+ return 1;
+ }
}
- ifa_free(dstaddr);
+ IF_ADDR_RUNLOCK(ifp);
}
/*
@@ -1487,7 +1503,7 @@ nd6_free(struct llentry **lnp, int gc)
/*
* We need to unlock to avoid a LOR with rt6_flush() with the
* rnh and for the calls to pfxlist_onlink_check() and
- * defrouter_select() in the block further down for calls
+ * defrouter_select_fib() in the block further down for calls
* into nd6_lookup(). We still hold a ref.
*/
LLE_WUNLOCK(ln);
@@ -1502,7 +1518,7 @@ nd6_free(struct llentry **lnp, int gc)
if (dr) {
/*
- * Since defrouter_select() does not affect the
+ * Since defrouter_select_fib() does not affect the
* on-link determination and MIP6 needs the check
* before the default router selection, we perform
* the check now.
@@ -1512,7 +1528,7 @@ nd6_free(struct llentry **lnp, int gc)
/*
* Refresh default router list.
*/
- defrouter_select();
+ defrouter_select_fib(dr->ifp->if_fib);
}
/*
@@ -2106,11 +2122,11 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
* Question: can we restrict the first condition to the "is_newentry"
* case?
* XXX: when we hear an RA from a new router with the link-layer
- * address option, defrouter_select() is called twice, since
+ * address option, defrouter_select_fib() is called twice, since
* defrtrlist_update called the function as well. However, I believe
* we can compromise the overhead, since it only happens the first
* time.
- * XXX: although defrouter_select() should not have a bad effect
+ * XXX: although defrouter_select_fib() should not have a bad effect
* for those are not autoconfigured hosts, we explicitly avoid such
* cases for safety.
*/
@@ -2119,7 +2135,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
/*
* guaranteed recursion
*/
- defrouter_select();
+ defrouter_select_fib(ifp->if_fib);
}
}
@@ -2261,7 +2277,6 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
case IFT_ETHER:
case IFT_FDDI:
case IFT_L2VLAN:
- case IFT_IEEE80211:
case IFT_BRIDGE:
case IFT_ISO88025:
ETHER_MAP_IPV6_MULTICAST(&dst6->sin6_addr,
@@ -2529,7 +2544,6 @@ nd6_need_cache(struct ifnet *ifp)
case IFT_FDDI:
case IFT_IEEE1394:
case IFT_L2VLAN:
- case IFT_IEEE80211:
case IFT_INFINIBAND:
case IFT_BRIDGE:
case IFT_PROPVIRTUAL:
diff --git a/freebsd/sys/netinet6/nd6.h b/freebsd/sys/netinet6/nd6.h
index 9b9fa3d1..243e9548 100644
--- a/freebsd/sys/netinet6/nd6.h
+++ b/freebsd/sys/netinet6/nd6.h
@@ -469,6 +469,7 @@ void nd6_dad_stop(struct ifaddr *);
void nd6_rs_input(struct mbuf *, int, int);
void nd6_ra_input(struct mbuf *, int, int);
void defrouter_reset(void);
+void defrouter_select_fib(int fibnum);
void defrouter_select(void);
void defrouter_ref(struct nd_defrouter *);
void defrouter_rele(struct nd_defrouter *);
diff --git a/freebsd/sys/netinet6/nd6_nbr.c b/freebsd/sys/netinet6/nd6_nbr.c
index e30dca8e..4fece39e 100644
--- a/freebsd/sys/netinet6/nd6_nbr.c
+++ b/freebsd/sys/netinet6/nd6_nbr.c
@@ -264,8 +264,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
bzero(&info, sizeof(info));
info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway;
- /* Always use the default FIB. */
- if (rib_lookup_info(RT_DEFAULT_FIB, (struct sockaddr *)&dst6,
+ if (rib_lookup_info(ifp->if_fib, (struct sockaddr *)&dst6,
0, 0, &info) == 0) {
if ((info.rti_flags & RTF_ANNOUNCE) != 0 &&
rt_gateway.sdl_family == AF_LINK) {
@@ -487,7 +486,7 @@ nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6,
uint32_t scopeid;
in6_splitscope(&ip6->ip6_dst, &dst6, &scopeid);
- error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6,
+ error = in6_selectsrc_addr(fibnum, &dst6,
scopeid, ifp, &src6, NULL);
if (error) {
char ip6buf[INET6_ADDRSTRLEN];
@@ -984,7 +983,7 @@ nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0,
* Select a source whose scope is the same as that of the dest.
*/
in6_splitscope(&daddr6, &dst6, &scopeid);
- error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6,
+ error = in6_selectsrc_addr(fibnum, &dst6,
scopeid, ifp, &src6, NULL);
if (error) {
char ip6buf[INET6_ADDRSTRLEN];
@@ -1088,7 +1087,6 @@ nd6_ifptomac(struct ifnet *ifp)
case IFT_FDDI:
case IFT_IEEE1394:
case IFT_L2VLAN:
- case IFT_IEEE80211:
case IFT_INFINIBAND:
case IFT_BRIDGE:
case IFT_ISO88025:
@@ -1459,7 +1457,6 @@ nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp)
case IFT_FDDI:
case IFT_ATM:
case IFT_IEEE1394:
- case IFT_IEEE80211:
case IFT_INFINIBAND:
in6 = ia->ia_addr.sin6_addr;
if (in6_get_hw_ifid(ifp, &in6) == 0 &&
diff --git a/freebsd/sys/netinet6/nd6_rtr.c b/freebsd/sys/netinet6/nd6_rtr.c
index f1ef143e..6e8d330f 100644
--- a/freebsd/sys/netinet6/nd6_rtr.c
+++ b/freebsd/sys/netinet6/nd6_rtr.c
@@ -502,7 +502,7 @@ defrouter_addreq(struct nd_defrouter *new)
error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&def,
(struct sockaddr *)&gate, (struct sockaddr *)&mask,
- RTF_GATEWAY, &newrt, RT_DEFAULT_FIB);
+ RTF_GATEWAY, &newrt, new->ifp->if_fib);
if (newrt) {
nd6_rtmsg(RTM_ADD, newrt); /* tell user process */
RTFREE(newrt);
@@ -553,8 +553,8 @@ defrouter_rele(struct nd_defrouter *dr)
/*
* Remove the default route for a given router.
- * This is just a subroutine function for defrouter_select(), and should
- * not be called from anywhere else.
+ * This is just a subroutine function for defrouter_select_fib(), and
+ * should not be called from anywhere else.
*/
static void
defrouter_delreq(struct nd_defrouter *dr)
@@ -573,7 +573,7 @@ defrouter_delreq(struct nd_defrouter *dr)
in6_rtrequest(RTM_DELETE, (struct sockaddr *)&def,
(struct sockaddr *)&gate,
- (struct sockaddr *)&mask, RTF_GATEWAY, &oldrt, RT_DEFAULT_FIB);
+ (struct sockaddr *)&mask, RTF_GATEWAY, &oldrt, dr->ifp->if_fib);
if (oldrt) {
nd6_rtmsg(RTM_DELETE, oldrt);
RTFREE(oldrt);
@@ -700,11 +700,11 @@ defrouter_del(struct nd_defrouter *dr)
/*
* If the router is the primary one, choose a new one.
- * Note that defrouter_select() will remove the current gateway
- * from the routing table.
+ * Note that defrouter_select_fib() will remove the current
+ * gateway from the routing table.
*/
if (deldr)
- defrouter_select();
+ defrouter_select_fib(deldr->ifp->if_fib);
/*
* Release the list reference.
@@ -732,13 +732,23 @@ defrouter_del(struct nd_defrouter *dr)
* even when the multipath routing is available, because we're not sure about
* the benefits for stub hosts comparing to the risk of making the code
* complicated and the possibility of introducing bugs.
+ *
+ * We maintain a single list of routers for multiple FIBs, only considering one
+ * at a time based on the receiving interface's FIB. If @fibnum is RT_ALL_FIBS,
+ * we do the whole thing multiple times.
*/
void
-defrouter_select(void)
+defrouter_select_fib(int fibnum)
{
struct nd_defrouter *dr, *selected_dr, *installed_dr;
struct llentry *ln = NULL;
+ if (fibnum == RT_ALL_FIBS) {
+ for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
+ defrouter_select_fib(fibnum);
+ }
+ }
+
ND6_RLOCK();
/*
* Let's handle easy case (3) first:
@@ -757,7 +767,7 @@ defrouter_select(void)
selected_dr = installed_dr = NULL;
TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) {
IF_AFDATA_RLOCK(dr->ifp);
- if (selected_dr == NULL &&
+ if (selected_dr == NULL && dr->ifp->if_fib == fibnum &&
(ln = nd6_lookup(&dr->rtaddr, 0, dr->ifp)) &&
ND6_IS_LLINFO_PROBREACH(ln)) {
selected_dr = dr;
@@ -769,14 +779,17 @@ defrouter_select(void)
ln = NULL;
}
- if (dr->installed) {
+ if (dr->installed && dr->ifp->if_fib == fibnum) {
if (installed_dr == NULL) {
installed_dr = dr;
defrouter_ref(installed_dr);
} else {
- /* this should not happen. warn for diagnosis. */
- log(LOG_ERR,
- "defrouter_select: more than one router is installed\n");
+ /*
+ * this should not happen.
+ * warn for diagnosis.
+ */
+ log(LOG_ERR, "defrouter_select_fib: more than "
+ "one router is installed\n");
}
}
}
@@ -791,14 +804,24 @@ defrouter_select(void)
if (selected_dr == NULL) {
if (installed_dr == NULL ||
TAILQ_NEXT(installed_dr, dr_entry) == NULL)
- selected_dr = TAILQ_FIRST(&V_nd_defrouter);
+ dr = TAILQ_FIRST(&V_nd_defrouter);
else
- selected_dr = TAILQ_NEXT(installed_dr, dr_entry);
- defrouter_ref(selected_dr);
+ dr = TAILQ_NEXT(installed_dr, dr_entry);
+
+ /* Ensure we select a router for this FIB. */
+ TAILQ_FOREACH_FROM(dr, &V_nd_defrouter, dr_entry) {
+ if (dr->ifp->if_fib == fibnum) {
+ selected_dr = dr;
+ defrouter_ref(selected_dr);
+ break;
+ }
+ }
} else if (installed_dr != NULL) {
IF_AFDATA_RLOCK(installed_dr->ifp);
- if ((ln = nd6_lookup(&installed_dr->rtaddr, 0, installed_dr->ifp)) &&
+ if ((ln = nd6_lookup(&installed_dr->rtaddr, 0,
+ installed_dr->ifp)) &&
ND6_IS_LLINFO_PROBREACH(ln) &&
+ installed_dr->ifp->if_fib == fibnum &&
rtpref(selected_dr) <= rtpref(installed_dr)) {
defrouter_rele(selected_dr);
selected_dr = installed_dr;
@@ -810,18 +833,30 @@ defrouter_select(void)
ND6_RUNLOCK();
/*
- * If the selected router is different than the installed one,
- * remove the installed router and install the selected one.
- * Note that the selected router is never NULL here.
+ * If we selected a router for this FIB and it's different
+ * than the installed one, remove the installed router and
+ * install the selected one in its place.
*/
if (installed_dr != selected_dr) {
if (installed_dr != NULL) {
defrouter_delreq(installed_dr);
defrouter_rele(installed_dr);
}
- defrouter_addreq(selected_dr);
+ if (selected_dr != NULL)
+ defrouter_addreq(selected_dr);
}
- defrouter_rele(selected_dr);
+ if (selected_dr != NULL)
+ defrouter_rele(selected_dr);
+}
+
+/*
+ * Maintain old KPI for default router selection.
+ * If unspecified, we can re-select routers for all FIBs.
+ */
+void
+defrouter_select(void)
+{
+ defrouter_select_fib(RT_ALL_FIBS);
}
/*
@@ -944,7 +979,7 @@ restart:
V_nd6_list_genid++;
ND6_WUNLOCK();
- defrouter_select();
+ defrouter_select_fib(new->ifp->if_fib);
return (n);
}
@@ -1733,7 +1768,7 @@ nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
struct rtentry *rt;
struct sockaddr_in6 mask6;
u_long rtflags;
- int error, a_failure, fibnum;
+ int error, a_failure, fibnum, maxfib;
/*
* in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs.
@@ -1744,8 +1779,15 @@ nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
mask6.sin6_addr = pr->ndpr_mask;
rtflags = (ifa->ifa_flags & ~IFA_RTSELF) | RTF_UP;
+ if(V_rt_add_addr_allfibs) {
+ fibnum = 0;
+ maxfib = rt_numfibs;
+ } else {
+ fibnum = ifa->ifa_ifp->if_fib;
+ maxfib = fibnum + 1;
+ }
a_failure = 0;
- for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
+ for (; fibnum < maxfib; fibnum++) {
rt = NULL;
error = in6_rtrequest(RTM_ADD,
@@ -1833,6 +1875,10 @@ nd6_prefix_onlink(struct nd_prefix *pr)
if ((opr->ndpr_stateflags & NDPRF_ONLINK) == 0)
continue;
+ if (!V_rt_add_addr_allfibs &&
+ opr->ndpr_ifp->if_fib != pr->ndpr_ifp->if_fib)
+ continue;
+
if (opr->ndpr_plen == pr->ndpr_plen &&
in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr,
&opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) {
@@ -1893,7 +1939,7 @@ nd6_prefix_offlink(struct nd_prefix *pr)
struct rtentry *rt;
char ip6buf[INET6_ADDRSTRLEN];
uint64_t genid;
- int fibnum, a_failure;
+ int fibnum, maxfib, a_failure;
ND6_ONLINK_LOCK_ASSERT();
ND6_UNLOCK_ASSERT();
@@ -1911,8 +1957,16 @@ nd6_prefix_offlink(struct nd_prefix *pr)
mask6.sin6_len = sizeof(sa6);
bcopy(&pr->ndpr_mask, &mask6.sin6_addr, sizeof(struct in6_addr));
+ if (V_rt_add_addr_allfibs) {
+ fibnum = 0;
+ maxfib = rt_numfibs;
+ } else {
+ fibnum = ifp->if_fib;
+ maxfib = fibnum + 1;
+ }
+
a_failure = 0;
- for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
+ for (; fibnum < maxfib; fibnum++) {
rt = NULL;
error = in6_rtrequest(RTM_DELETE, (struct sockaddr *)&sa6, NULL,
(struct sockaddr *)&mask6, 0, &rt, fibnum);
diff --git a/freebsd/sys/netinet6/raw_ip6.c b/freebsd/sys/netinet6/raw_ip6.c
index 5b0577d3..0c73429b 100644
--- a/freebsd/sys/netinet6/raw_ip6.c
+++ b/freebsd/sys/netinet6/raw_ip6.c
@@ -42,7 +42,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -106,10 +106,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/scope6_var.h>
#include <netinet6/send.h>
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/ipsec6.h>
-#endif /* IPSEC */
+#include <netipsec/ipsec_support.h>
#include <machine/stdarg.h>
@@ -171,7 +168,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
RIP6STAT_INC(rip6s_ipackets);
- init_sin6(&fromsa, m); /* general init */
+ init_sin6(&fromsa, m, 0); /* general init */
ifp = m->m_pkthdr.rcvif;
@@ -260,14 +257,18 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
if (last != NULL) {
struct mbuf *n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/*
* Check AH/ESP integrity.
*/
- if (n && ipsec6_in_reject(n, last)) {
- m_freem(n);
- /* Do not inject data into pcb. */
- } else
+ if (IPSEC_ENABLED(ipv6)) {
+ if (n != NULL &&
+ IPSEC_CHECK_POLICY(ipv6, n, last) != 0) {
+ m_freem(n);
+ /* Do not inject data into pcb. */
+ n = NULL;
+ }
+ }
#endif /* IPSEC */
if (n) {
if (last->inp_flags & INP_CONTROLOPTS ||
@@ -291,11 +292,12 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
last = in6p;
}
INP_INFO_RUNLOCK(&V_ripcbinfo);
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/*
* Check AH/ESP integrity.
*/
- if ((last != NULL) && ipsec6_in_reject(m, last)) {
+ if (IPSEC_ENABLED(ipv6) && last != NULL &&
+ IPSEC_CHECK_POLICY(ipv6, m, last) != 0) {
m_freem(m);
IP6STAT_DEC(ip6s_delivered);
/* Do not inject data into pcb. */
diff --git a/freebsd/sys/netinet6/sctp6_usrreq.c b/freebsd/sys/netinet6/sctp6_usrreq.c
index 751c18fd..03e20b18 100644
--- a/freebsd/sys/netinet6/sctp6_usrreq.c
+++ b/freebsd/sys/netinet6/sctp6_usrreq.c
@@ -57,11 +57,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/icmp6.h>
#include <netinet/udp.h>
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/ipsec6.h>
-#endif /* IPSEC */
-
extern struct protosw inetsw[];
int
@@ -560,10 +555,6 @@ sctp6_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNU
*/
inp6->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
#endif
- /*
- * Hmm what about the IPSEC stuff that is missing here but in
- * sctp_attach()?
- */
SCTP_INP_WUNLOCK(inp);
return (0);
}
diff --git a/freebsd/sys/netinet6/tcp6_var.h b/freebsd/sys/netinet6/tcp6_var.h
index 5cb04f99..1ef1eb95 100644
--- a/freebsd/sys/netinet6/tcp6_var.h
+++ b/freebsd/sys/netinet6/tcp6_var.h
@@ -39,7 +39,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/freebsd/sys/netinet6/udp6_usrreq.c b/freebsd/sys/netinet6/udp6_usrreq.c
index 2f950e62..0f5c6bd9 100644
--- a/freebsd/sys/netinet6/udp6_usrreq.c
+++ b/freebsd/sys/netinet6/udp6_usrreq.c
@@ -50,7 +50,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -122,10 +122,7 @@ __FBSDID("$FreeBSD$");
#include <netinet6/udp6_var.h>
#include <netinet6/scope6_var.h>
-#ifdef IPSEC
-#include <netipsec/ipsec.h>
-#include <netipsec/ipsec6.h>
-#endif /* IPSEC */
+#include <netipsec/ipsec_support.h>
#include <security/mac/mac_framework.h>
@@ -142,7 +139,7 @@ udp6_append(struct inpcb *inp, struct mbuf *n, int off,
struct sockaddr_in6 *fromsa)
{
struct socket *so;
- struct mbuf *opts;
+ struct mbuf *opts = NULL, *tmp_opts;
struct udpcb *up;
INP_LOCK_ASSERT(inp);
@@ -154,16 +151,18 @@ udp6_append(struct inpcb *inp, struct mbuf *n, int off,
if (up->u_tun_func != NULL) {
in_pcbref(inp);
INP_RUNLOCK(inp);
- (*up->u_tun_func)(n, off, inp, (struct sockaddr *)fromsa,
+ (*up->u_tun_func)(n, off, inp, (struct sockaddr *)&fromsa[0],
up->u_tun_ctx);
INP_RLOCK(inp);
return (in_pcbrele_rlocked(inp));
}
-#ifdef IPSEC
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
/* Check AH/ESP integrity. */
- if (ipsec6_in_reject(n, inp)) {
- m_freem(n);
- return (0);
+ if (IPSEC_ENABLED(ipv6)) {
+ if (IPSEC_CHECK_POLICY(ipv6, n, inp) != 0) {
+ m_freem(n);
+ return (0);
+ }
}
#endif /* IPSEC */
#ifdef MAC
@@ -176,11 +175,23 @@ udp6_append(struct inpcb *inp, struct mbuf *n, int off,
if (inp->inp_flags & INP_CONTROLOPTS ||
inp->inp_socket->so_options & SO_TIMESTAMP)
ip6_savecontrol(inp, n, &opts);
+ if ((inp->inp_vflag & INP_IPV6) && (inp->inp_flags2 & INP_ORIGDSTADDR)) {
+ tmp_opts = sbcreatecontrol((caddr_t)&fromsa[1],
+ sizeof(struct sockaddr_in6), IPV6_ORIGDSTADDR, IPPROTO_IPV6);
+ if (tmp_opts) {
+ if (opts) {
+ tmp_opts->m_next = opts;
+ opts = tmp_opts;
+ } else
+ opts = tmp_opts;
+ }
+
+ }
m_adj(n, off + sizeof(struct udphdr));
so = inp->inp_socket;
SOCKBUF_LOCK(&so->so_rcv);
- if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)fromsa, n,
+ if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)&fromsa[0], n,
opts) == 0) {
SOCKBUF_UNLOCK(&so->so_rcv);
m_freem(n);
@@ -205,7 +216,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
int off = *offp;
int cscov_partial;
int plen, ulen;
- struct sockaddr_in6 fromsa;
+ struct sockaddr_in6 fromsa[2];
struct m_tag *fwd_tag;
uint16_t uh_sum;
uint8_t nxt;
@@ -280,8 +291,10 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
/*
* Construct sockaddr format source address.
*/
- init_sin6(&fromsa, m);
- fromsa.sin6_port = uh->uh_sport;
+ init_sin6(&fromsa[0], m, 0);
+ fromsa[0].sin6_port = uh->uh_sport;
+ init_sin6(&fromsa[1], m, 1);
+ fromsa[1].sin6_port = uh->uh_dport;
pcbinfo = udp_get_inpcbinfo(nxt);
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
@@ -352,7 +365,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
blocked = im6o_mc_filter(imo, ifp,
(struct sockaddr *)&mcaddr,
- (struct sockaddr *)&fromsa);
+ (struct sockaddr *)&fromsa[0]);
if (blocked != MCAST_PASS) {
if (blocked == MCAST_NOTGMEMBER)
IP6STAT_INC(ip6s_notmember);
@@ -373,7 +386,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
INP_RLOCK(last);
UDP_PROBE(receive, NULL, last, ip6,
last, uh);
- if (udp6_append(last, n, off, &fromsa))
+ if (udp6_append(last, n, off, fromsa))
goto inp_lost;
INP_RUNLOCK(last);
}
@@ -405,7 +418,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
INP_RLOCK(last);
INP_INFO_RUNLOCK(pcbinfo);
UDP_PROBE(receive, NULL, last, ip6, last, uh);
- if (udp6_append(last, m, off, &fromsa) == 0)
+ if (udp6_append(last, m, off, fromsa) == 0)
INP_RUNLOCK(last);
inp_lost:
return (IPPROTO_DONE);
@@ -485,7 +498,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
}
}
UDP_PROBE(receive, NULL, inp, ip6, inp, uh);
- if (udp6_append(inp, m, off, &fromsa) == 0)
+ if (udp6_append(inp, m, off, fromsa) == 0)
INP_RUNLOCK(inp);
return (IPPROTO_DONE);
diff --git a/freebsd/sys/netinet6/udp6_var.h b/freebsd/sys/netinet6/udp6_var.h
index cdab98b0..8a2afa38 100644
--- a/freebsd/sys/netinet6/udp6_var.h
+++ b/freebsd/sys/netinet6/udp6_var.h
@@ -40,7 +40,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*