diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-11-06 15:42:44 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-11-15 10:56:14 +0100 |
commit | e0b4edbdcc3558d3f38af8398f995c2e9f019f07 (patch) | |
tree | ea91a5fcfb9b6a66a8c0b74cf68ff8d450ce17e0 /freebsd/sys/netinet6 | |
parent | Disable or make static kern_* functions (diff) | |
download | rtems-libbsd-e0b4edbdcc3558d3f38af8398f995c2e9f019f07.tar.bz2 |
Update to FreeBSD head 2018-11-15
Git mirror commit a18b0830c4be01b39489a891b63d6023ada6358a.
Update #3472.
Diffstat (limited to 'freebsd/sys/netinet6')
-rw-r--r-- | freebsd/sys/netinet6/in6_gif.c | 5 | ||||
-rw-r--r-- | freebsd/sys/netinet6/in6_ifattach.c | 13 | ||||
-rw-r--r-- | freebsd/sys/netinet6/in6_pcb.c | 6 | ||||
-rw-r--r-- | freebsd/sys/netinet6/nd6.h | 3 | ||||
-rw-r--r-- | freebsd/sys/netinet6/nd6_rtr.c | 38 | ||||
-rw-r--r-- | freebsd/sys/netinet6/raw_ip6.c | 86 |
6 files changed, 102 insertions, 49 deletions
diff --git a/freebsd/sys/netinet6/in6_gif.c b/freebsd/sys/netinet6/in6_gif.c index 66c2cfb4..d7396bb1 100644 --- a/freebsd/sys/netinet6/in6_gif.c +++ b/freebsd/sys/netinet6/in6_gif.c @@ -155,7 +155,8 @@ in6_gif_srcaddr(void *arg __unused, const struct sockaddr *sa, int event) const struct sockaddr_in6 *sin; struct gif_softc *sc; - if (V_ipv6_srchashtbl == NULL) + /* Check that VNET is ready */ + if (V_ipv6_hashtbl == NULL) return; MPASS(in_epoch(net_epoch_preempt)); @@ -482,6 +483,8 @@ in6_gif_uninit(void) } if (V_ipv6_hashtbl != NULL) { gif_hashdestroy(V_ipv6_hashtbl); + V_ipv6_hashtbl = NULL; + GIF_WAIT(); gif_hashdestroy(V_ipv6_srchashtbl); } } diff --git a/freebsd/sys/netinet6/in6_ifattach.c b/freebsd/sys/netinet6/in6_ifattach.c index 1cab31d1..6af4b557 100644 --- a/freebsd/sys/netinet6/in6_ifattach.c +++ b/freebsd/sys/netinet6/in6_ifattach.c @@ -487,9 +487,16 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp) return (-1); } - ia = in6ifa_ifpforlinklocal(ifp, 0); /* ia must not be NULL */ - KASSERT(ia != NULL, ("%s: ia == NULL, ifp=%p", __func__, ifp)); - + ia = in6ifa_ifpforlinklocal(ifp, 0); + if (ia == NULL) { + /* + * Another thread removed the address that we just added. + * This should be rare, but it happens. + */ + nd6log((LOG_NOTICE, "%s: %s: new link-local address " + "disappeared\n", __func__, if_name(ifp))); + return (-1); + } ifa_free(&ia->ia_ifa); /* diff --git a/freebsd/sys/netinet6/in6_pcb.c b/freebsd/sys/netinet6/in6_pcb.c index 53102764..f5b22db7 100644 --- a/freebsd/sys/netinet6/in6_pcb.c +++ b/freebsd/sys/netinet6/in6_pcb.c @@ -1175,13 +1175,11 @@ in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, /* * Then look in lb group (for wildcard match). */ - if (pcbinfo->ipi_lbgrouphashbase != NULL && - (lookupflags & INPLOOKUP_WILDCARD)) { + if ((lookupflags & INPLOOKUP_WILDCARD) != 0) { inp = in6_pcblookup_lbgroup(pcbinfo, laddr, lport, faddr, fport, lookupflags); - if (inp != NULL) { + if (inp != NULL) return (inp); - } } /* diff --git a/freebsd/sys/netinet6/nd6.h b/freebsd/sys/netinet6/nd6.h index cabfeec0..7544d23c 100644 --- a/freebsd/sys/netinet6/nd6.h +++ b/freebsd/sys/netinet6/nd6.h @@ -90,6 +90,9 @@ struct nd_ifinfo { #define ND6_IFF_NO_RADR 0x40 #define ND6_IFF_NO_PREFER_IFACE 0x80 /* XXX: not related to ND. */ #define ND6_IFF_NO_DAD 0x100 +#ifdef EXPERIMENTAL +#define ND6_IFF_IPV6_ONLY 0x200 /* draft-ietf-6man-ipv6only-flag */ +#endif #ifdef _KERNEL #define ND_IFINFO(ifp) \ diff --git a/freebsd/sys/netinet6/nd6_rtr.c b/freebsd/sys/netinet6/nd6_rtr.c index a60e7c66..59868383 100644 --- a/freebsd/sys/netinet6/nd6_rtr.c +++ b/freebsd/sys/netinet6/nd6_rtr.c @@ -206,6 +206,37 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len) m_freem(m); } +#ifdef EXPERIMENTAL +/* + * An initial update routine for draft-ietf-6man-ipv6only-flag. + * We need to iterate over all default routers for the given + * interface to see whether they are all advertising the "6" + * (IPv6-Only) flag. If they do set, otherwise unset, the + * interface flag we later use to filter on. + */ +static void +defrtr_ipv6_only_ifp(struct ifnet *ifp) +{ + struct nd_defrouter *dr; + bool ipv6_only; + + ipv6_only = true; + ND6_RLOCK(); + TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) + if (dr->ifp == ifp && + (dr->raflags & ND_RA_FLAG_IPV6_ONLY) == 0) + ipv6_only = false; + ND6_RUNLOCK(); + + IF_AFDATA_WLOCK(ifp); + if (ipv6_only) + ND_IFINFO(ifp)->flags |= ND6_IFF_IPV6_ONLY; + else + ND_IFINFO(ifp)->flags &= ~ND6_IFF_IPV6_ONLY; + IF_AFDATA_WUNLOCK(ifp); +} +#endif + /* * Receive Router Advertisement Message. * @@ -321,6 +352,9 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len) } } dr = defrtrlist_update(&dr0); +#ifdef EXPERIMENTAL + defrtr_ipv6_only_ifp(ifp); +#endif } /* @@ -694,6 +728,10 @@ defrouter_del(struct nd_defrouter *dr) if (ND_IFINFO(dr->ifp)->flags & ND6_IFF_ACCEPT_RTADV) rt6_flush(&dr->rtaddr, dr->ifp); +#ifdef EXPERIMENTAL + defrtr_ipv6_only_ifp(dr->ifp); +#endif + if (dr->installed) { deldr = dr; defrouter_delreq(dr); diff --git a/freebsd/sys/netinet6/raw_ip6.c b/freebsd/sys/netinet6/raw_ip6.c index 9c3d7a61..73d0832a 100644 --- a/freebsd/sys/netinet6/raw_ip6.c +++ b/freebsd/sys/netinet6/raw_ip6.c @@ -189,6 +189,45 @@ rip6_input(struct mbuf **mp, int *offp, int proto) if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) && !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src)) continue; + if (last != NULL) { + struct mbuf *n = m_copym(m, 0, M_COPYALL, M_NOWAIT); + +#if defined(IPSEC) || defined(IPSEC_SUPPORT) + /* + * Check AH/ESP integrity. + */ + 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 || + last->inp_socket->so_options & SO_TIMESTAMP) + ip6_savecontrol(last, n, &opts); + /* strip intermediate headers */ + m_adj(n, *offp); + if (sbappendaddr(&last->inp_socket->so_rcv, + (struct sockaddr *)&fromsa, + n, opts) == 0) { + m_freem(n); + if (opts) + m_freem(opts); + RIP6STAT_INC(rip6s_fullsock); + } else + sorwakeup(last->inp_socket); + opts = NULL; + } + INP_RUNLOCK(last); + last = NULL; + } + INP_RLOCK(in6p); + if (__predict_false(in6p->inp_flags2 & INP_FREED)) + goto skip_2; if (jailed_without_vnet(in6p->inp_cred)) { /* * Allow raw socket in jail to receive multicast; @@ -198,16 +237,14 @@ rip6_input(struct mbuf **mp, int *offp, int proto) if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) && prison_check_ip6(in6p->inp_cred, &ip6->ip6_dst) != 0) - continue; + goto skip_2; } - INP_RLOCK(in6p); if (in6p->in6p_cksum != -1) { RIP6STAT_INC(rip6s_isum); if (in6_cksum(m, proto, *offp, m->m_pkthdr.len - *offp)) { - INP_RUNLOCK(in6p); RIP6STAT_INC(rip6s_badsum); - continue; + goto skip_2; } } /* @@ -253,46 +290,13 @@ rip6_input(struct mbuf **mp, int *offp, int proto) } if (blocked != MCAST_PASS) { IP6STAT_INC(ip6s_notmember); - INP_RUNLOCK(in6p); - continue; - } - } - if (last != NULL) { - struct mbuf *n = m_copym(m, 0, M_COPYALL, M_NOWAIT); - -#if defined(IPSEC) || defined(IPSEC_SUPPORT) - /* - * Check AH/ESP integrity. - */ - 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 || - last->inp_socket->so_options & SO_TIMESTAMP) - ip6_savecontrol(last, n, &opts); - /* strip intermediate headers */ - m_adj(n, *offp); - if (sbappendaddr(&last->inp_socket->so_rcv, - (struct sockaddr *)&fromsa, - n, opts) == 0) { - m_freem(n); - if (opts) - m_freem(opts); - RIP6STAT_INC(rip6s_fullsock); - } else - sorwakeup(last->inp_socket); - opts = NULL; + goto skip_2; } - INP_RUNLOCK(last); } last = in6p; + continue; +skip_2: + INP_RUNLOCK(in6p); } INP_INFO_RUNLOCK_ET(&V_ripcbinfo, et); #if defined(IPSEC) || defined(IPSEC_SUPPORT) |