diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-11-04 11:33:00 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-11-04 15:28:21 +0100 |
commit | af5333e0a02b2295304d4e029b15ee15a4fe2b3a (patch) | |
tree | c5c43680d374f58b487eeeaf18fb7ec6b84ba074 /freebsd/sys/netinet6/ip6_output.c | |
parent | BUS_SPACE(9): Use simple memory model for ARM (diff) | |
download | rtems-libbsd-af5333e0a02b2295304d4e029b15ee15a4fe2b3a.tar.bz2 |
Update to FreeBSD 8.4
Diffstat (limited to 'freebsd/sys/netinet6/ip6_output.c')
-rw-r--r-- | freebsd/sys/netinet6/ip6_output.c | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/freebsd/sys/netinet6/ip6_output.c b/freebsd/sys/netinet6/ip6_output.c index d6d7eb6e..19c430a6 100644 --- a/freebsd/sys/netinet6/ip6_output.c +++ b/freebsd/sys/netinet6/ip6_output.c @@ -137,7 +137,7 @@ static int ip6_insertfraghdr __P((struct mbuf *, struct mbuf *, int, static int ip6_insert_jumboopt(struct ip6_exthdrs *, u_int32_t); static int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *); static int ip6_getpmtu __P((struct route_in6 *, struct route_in6 *, - struct ifnet *, struct in6_addr *, u_long *, int *)); + struct ifnet *, struct in6_addr *, u_long *, int *, u_int)); static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int); @@ -232,6 +232,9 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, goto bad; } + if (inp != NULL) + M_SETFIB(m, inp->inp_inc.inc_fibnum); + finaldst = ip6->ip6_dst; bzero(&exthdrs, sizeof(exthdrs)); @@ -259,11 +262,11 @@ 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. */ -#ifdef IPSEC switch(ip6_ipsec_output(&m, inp, &flags, &error, &ifp, &sp)) { case 1: /* Bad packet */ @@ -578,8 +581,8 @@ again: dst_sa.sin6_family = AF_INET6; dst_sa.sin6_len = sizeof(dst_sa); dst_sa.sin6_addr = ip6->ip6_dst; - if ((error = in6_selectroute(&dst_sa, opt, im6o, ro, - &ifp, &rt)) != 0) { + if ((error = in6_selectroute_fib(&dst_sa, opt, im6o, ro, + &ifp, &rt, inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m))) != 0) { switch (error) { case EHOSTUNREACH: V_ip6stat.ip6s_noroute++; @@ -747,7 +750,7 @@ again: /* Determine path MTU. */ if ((error = ip6_getpmtu(ro_pmtu, ro, ifp, &finaldst, &mtu, - &alwaysfrag)) != 0) + &alwaysfrag, inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m))) != 0) goto bad; /* @@ -1011,7 +1014,7 @@ passout: goto sendorfree; } m->m_pkthdr.rcvif = NULL; - m->m_flags = m0->m_flags & M_COPYFLAGS; + m->m_flags = m0->m_flags & M_COPYFLAGS; /* incl. FIB */ *mnext = m; mnext = &m->m_nextpkt; m->m_data += max_linkhdr; @@ -1266,7 +1269,7 @@ ip6_insertfraghdr(struct mbuf *m0, struct mbuf *m, int hlen, static int ip6_getpmtu(struct route_in6 *ro_pmtu, struct route_in6 *ro, struct ifnet *ifp, struct in6_addr *dst, u_long *mtup, - int *alwaysfragp) + int *alwaysfragp, u_int fibnum) { u_int32_t mtu = 0; int alwaysfrag = 0; @@ -1288,7 +1291,7 @@ ip6_getpmtu(struct route_in6 *ro_pmtu, struct route_in6 *ro, sa6_dst->sin6_len = sizeof(struct sockaddr_in6); sa6_dst->sin6_addr = *dst; - rtalloc((struct route *)ro_pmtu); + in6_rtalloc(ro_pmtu, fibnum); } } if (ro_pmtu->ro_rt) { @@ -1366,7 +1369,23 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt) optval = 0; uproto = (int)so->so_proto->pr_protocol; - if (level == IPPROTO_IPV6) { + if (level != IPPROTO_IPV6) { + error = EINVAL; + + if (sopt->sopt_level == SOL_SOCKET && + sopt->sopt_dir == SOPT_SET) { + switch (sopt->sopt_name) { + case SO_SETFIB: + INP_WLOCK(in6p); + in6p->inp_inc.inc_fibnum = so->so_fibnum; + INP_WUNLOCK(in6p); + error = 0; + break; + default: + break; + } + } + } else { switch (op) { case SOPT_SET: @@ -1455,18 +1474,22 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt) break; #define OPTSET(bit) \ do { \ + INP_WLOCK(in6p); \ if (optval) \ in6p->inp_flags |= (bit); \ else \ in6p->inp_flags &= ~(bit); \ + INP_WUNLOCK(in6p); \ } while (/*CONSTCOND*/ 0) #define OPTSET2292(bit) \ do { \ + INP_WLOCK(in6p); \ in6p->inp_flags |= IN6P_RFC2292; \ if (optval) \ in6p->inp_flags |= (bit); \ else \ in6p->inp_flags &= ~(bit); \ + INP_WUNLOCK(in6p); \ } while (/*CONSTCOND*/ 0) #define OPTBIT(bit) (in6p->inp_flags & (bit) ? 1 : 0) @@ -1720,6 +1743,7 @@ do { \ if (error) break; + INP_WLOCK(in6p); switch (optval) { case IPV6_PORTRANGE_DEFAULT: in6p->inp_flags &= ~(INP_LOWPORT); @@ -1740,6 +1764,7 @@ do { \ error = EINVAL; break; } + INP_WUNLOCK(in6p); break; #ifdef IPSEC @@ -1889,7 +1914,8 @@ do { \ * the outgoing interface. */ error = ip6_getpmtu(&sro, NULL, NULL, - &in6p->in6p_faddr, &pmtu, NULL); + &in6p->in6p_faddr, &pmtu, NULL, + so->so_fibnum); if (sro.ro_rt) RTFREE(sro.ro_rt); if (error) @@ -1989,8 +2015,6 @@ do { \ } break; } - } else { /* level != IPPROTO_IPV6 */ - error = EINVAL; } return (error); } @@ -2312,6 +2336,8 @@ copypktopts(struct ip6_pktopts *dst, struct ip6_pktopts *src, int canwait) dst->ip6po_hlim = src->ip6po_hlim; dst->ip6po_tclass = src->ip6po_tclass; dst->ip6po_flags = src->ip6po_flags; + dst->ip6po_minmtu = src->ip6po_minmtu; + dst->ip6po_prefer_tempaddr = src->ip6po_prefer_tempaddr; if (src->ip6po_pktinfo) { dst->ip6po_pktinfo = malloc(sizeof(*dst->ip6po_pktinfo), M_IP6OPT, canwait); |