The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=576ee62dd2e5e0454a5316eb9207f4ebaa543171
commit 576ee62dd2e5e0454a5316eb9207f4ebaa543171 Author: Gleb Smirnoff <[email protected]> AuthorDate: 2026-01-23 22:17:40 +0000 Commit: Gleb Smirnoff <[email protected]> CommitDate: 2026-01-23 22:17:40 +0000 netinet6: store ND context directly in struct in6_ifextra Stop using struct nd_ifinfo for that, because it is an API struct for SIOCGIFINFO_IN6. The functional changes are isolated to the protocol attach and detach: in6_ifarrival(), nd6_ifattach(), in6_ifdeparture(), nd6_ifdetach(), as well as to the nd6_ioctl(), nd6_ra_input(), nd6_slowtimo() and in6_ifmtu(). The dad_failures member was just renamed to match the rest. The M_IP6NDP malloc(9) type declaration moved to files that actually use it. The rest of the changes are mechanical substitution of double pointer dereference via ND_IFINFO() to a single pointer dereference. This was achieved with a sed(1) script: s/ND_IFINFO\(([a-z0-9>_.-]+)\)->(flags|linkmtu|basereachable|reachable|retrans|chlim)/\1->if_inet6->nd_\2/g s/nd_chlim/nd_curhoplimit/g Reviewed by: tuexen, madpilot Differential Revision: https://reviews.freebsd.org/D54725 --- sys/dev/wg/if_wg.c | 4 +- sys/net/if_ethersubr.c | 4 +- sys/netinet/sctp_output.c | 6 +- sys/netinet6/icmp6.c | 3 +- sys/netinet6/in6.c | 32 ++++----- sys/netinet6/in6_ifattach.c | 12 ++-- sys/netinet6/in6_src.c | 6 +- sys/netinet6/in6_var.h | 15 +++- sys/netinet6/ip6_input.c | 2 +- sys/netinet6/ip6_output.c | 2 +- sys/netinet6/nd6.c | 172 ++++++++++++++++++++++---------------------- sys/netinet6/nd6.h | 12 +--- sys/netinet6/nd6_nbr.c | 24 ++++--- sys/netinet6/nd6_rtr.c | 56 ++++++++------- 14 files changed, 177 insertions(+), 173 deletions(-) diff --git a/sys/dev/wg/if_wg.c b/sys/dev/wg/if_wg.c index 17aedee0e6b0..611314883643 100644 --- a/sys/dev/wg/if_wg.c +++ b/sys/dev/wg/if_wg.c @@ -3033,8 +3033,8 @@ wg_clone_create(struct if_clone *ifc, char *name, size_t len, if_attach(ifp); bpfattach(ifp, DLT_NULL, sizeof(uint32_t)); #ifdef INET6 - ND_IFINFO(ifp)->flags &= ~ND6_IFF_AUTO_LINKLOCAL; - ND_IFINFO(ifp)->flags |= ND6_IFF_NO_DAD; + if_getinet6(ifp)->nd_flags &= ~ND6_IFF_AUTO_LINKLOCAL; + if_getinet6(ifp)->nd_flags |= ND6_IFF_NO_DAD; #endif sx_xlock(&wg_sx); LIST_INSERT_HEAD(&wg_list, sc, sc_entry); diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index da9264aa4a23..812a31595df9 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -479,7 +479,7 @@ ether_output_frame(struct ifnet *ifp, struct mbuf *m) #if defined(INET6) && defined(INET) /* draft-ietf-6man-ipv6only-flag */ /* Catch ETHERTYPE_IP, and ETHERTYPE_[REV]ARP if we are v6-only. */ - if ((ND_IFINFO(ifp)->flags & ND6_IFF_IPV6_ONLY_MASK) != 0) { + if ((ifp->if_inet6->nd_flags & ND6_IFF_IPV6_ONLY_MASK) != 0) { struct ether_header *eh; eh = mtod(m, struct ether_header *); @@ -545,7 +545,7 @@ ether_input_internal(struct ifnet *ifp, struct mbuf *m) #if defined(INET6) && defined(INET) /* draft-ietf-6man-ipv6only-flag */ /* Catch ETHERTYPE_IP, and ETHERTYPE_[REV]ARP if we are v6-only. */ - if ((ND_IFINFO(ifp)->flags & ND6_IFF_IPV6_ONLY_MASK) != 0) { + if ((ifp->if_inet6->nd_flags & ND6_IFF_IPV6_ONLY_MASK) != 0) { switch (etype) { case ETHERTYPE_IP: case ETHERTYPE_ARP: diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index e4bdb4291972..4f6fbc6be783 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -4596,9 +4596,9 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, } } } else if (ifp != NULL) { - if ((ND_IFINFO(ifp)->linkmtu > 0) && - (stcb->asoc.smallest_mtu > ND_IFINFO(ifp)->linkmtu)) { - sctp_pathmtu_adjustment(stcb, ND_IFINFO(ifp)->linkmtu, false); + if ((ifp->if_inet6->nd_linkmtu > 0) && + (stcb->asoc.smallest_mtu > ifp->if_inet6->nd_linkmtu)) { + sctp_pathmtu_adjustment(stcb, ifp->if_inet6->nd_linkmtu, false); } } } diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index c05850f1477b..5b5f7b83623e 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -2080,7 +2080,8 @@ icmp6_reflect(struct mbuf *m, size_t off) if (m->m_pkthdr.rcvif != NULL) { /* XXX: This may not be the outgoing interface */ - hlim = ND_IFINFO(m->m_pkthdr.rcvif)->chlim; + hlim = + m->m_pkthdr.rcvif->if_inet6->nd_curhoplimit; } else hlim = V_ip6_defhlim; } diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 07f1198cd283..d283aba62dcc 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1090,7 +1090,7 @@ in6_update_ifa_internal(struct ifnet *ifp, struct in6_aliasreq *ifra, * an interface with ND6_IFF_IFDISABLED. */ if (in6if_do_dad(ifp) && - (hostIsNew || (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED))) + (hostIsNew || (ifp->if_inet6->nd_flags & ND6_IFF_IFDISABLED))) ia->ia6_flags |= IN6_IFF_TENTATIVE; /* notify other subsystems */ @@ -1386,11 +1386,11 @@ aifaddr_out: * Try to clear the flag when a new IPv6 address is added * onto an IFDISABLED interface and it succeeds. */ - if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) { + if (ifp->if_inet6->nd_flags & ND6_IFF_IFDISABLED) { struct in6_ndireq nd; memset(&nd, 0, sizeof(nd)); - nd.ndi.flags = ND_IFINFO(ifp)->flags; + nd.ndi.flags = ifp->if_inet6->nd_flags; nd.ndi.flags &= ~ND6_IFF_IFDISABLED; if (nd6_ioctl(SIOCSIFINFO_FLAGS, (caddr_t)&nd, ifp) < 0) log(LOG_NOTICE, "SIOCAIFADDR_IN6: " @@ -1712,7 +1712,7 @@ in6ifa_llaonifp(struct ifnet *ifp) struct sockaddr_in6 *sin6; struct ifaddr *ifa; - if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) + if (ifp->if_inet6->nd_flags & ND6_IFF_IFDISABLED) return (NULL); NET_EPOCH_ENTER(et); CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { @@ -2136,7 +2136,7 @@ in6if_do_dad(struct ifnet *ifp) return (0); if ((ifp->if_flags & IFF_MULTICAST) == 0) return (0); - if ((ND_IFINFO(ifp)->flags & + if ((ifp->if_inet6->nd_flags & (ND6_IFF_IFDISABLED | ND6_IFF_NO_DAD)) != 0) return (0); return (1); @@ -2607,21 +2607,17 @@ in6_ifarrival(void *arg __unused, struct ifnet *ifp) ifp->if_inet6 = NULL; return; } - ext = (struct in6_ifextra *)malloc(sizeof(*ext), M_IFADDR, M_WAITOK); - bzero(ext, sizeof(*ext)); - + ext = ifp->if_inet6 = malloc(sizeof(*ext), M_IFADDR, M_WAITOK | M_ZERO); COUNTER_ARRAY_ALLOC(ext->in6_ifstat, sizeof(struct in6_ifstat) / sizeof(uint64_t), M_WAITOK); COUNTER_ARRAY_ALLOC(ext->icmp6_ifstat, sizeof(struct icmp6_ifstat) / sizeof(uint64_t), M_WAITOK); + nd6_ifattach(ifp); - ext->nd_ifinfo = nd6_ifattach(ifp); ext->scope6_id = scope6_ifattach(ifp); ext->lltable = in6_lltattach(ifp); ext->mld_ifinfo = mld_domifattach(ifp); - - ifp->if_inet6 = ext; } EVENTHANDLER_DEFINE(ifnet_arrival_event, in6_ifarrival, NULL, EVENTHANDLER_PRI_ANY); @@ -2629,12 +2625,16 @@ EVENTHANDLER_DEFINE(ifnet_arrival_event, in6_ifarrival, NULL, uint32_t in6_ifmtu(const struct ifnet *ifp) { - struct nd_ifinfo *ndi = ND_IFINFO(ifp); + const uint32_t + linkmtu = ifp->if_inet6->nd_linkmtu, + maxmtu = ifp->if_inet6->nd_maxmtu, + ifmtu = ifp->if_mtu; - return ( - (ndi->linkmtu > 0 && ndi->linkmtu < ifp->if_mtu) ? ndi->linkmtu : - ((ndi->maxmtu > 0 && ndi->maxmtu < ifp->if_mtu) ? ndi->maxmtu : - ifp->if_mtu)); + if (linkmtu > 0 && linkmtu < ifmtu) + return (linkmtu); + if (maxmtu > 0 && maxmtu < ifmtu) + return (maxmtu); + return (ifmtu); } /* diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 194033ee7808..f21f96cd86c8 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -465,7 +465,7 @@ in6_get_ifid(struct ifnet *ifp0, struct ifnet *altifp, NET_EPOCH_ASSERT(); /* first, try to get it from the interface itself, with stable algorithm, if configured */ - if ((ND_IFINFO(ifp0)->flags & ND6_IFF_STABLEADDR) && in6_get_stableifid(ifp0, in6, 64) == 0) { + if ((ifp0->if_inet6->nd_flags & ND6_IFF_STABLEADDR) && in6_get_stableifid(ifp0, in6, 64) == 0) { nd6log((LOG_DEBUG, "%s: got interface identifier from itself (stable private)\n", if_name(ifp0))); goto success; @@ -799,8 +799,8 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp) * linklocals for 6to4 interface, but there's no use and * it is rather harmful to have one. */ - ND_IFINFO(ifp)->flags &= ~ND6_IFF_AUTO_LINKLOCAL; - ND_IFINFO(ifp)->flags |= ND6_IFF_NO_DAD; + ifp->if_inet6->nd_flags &= ~ND6_IFF_AUTO_LINKLOCAL; + ifp->if_inet6->nd_flags |= ND6_IFF_NO_DAD; break; default: break; @@ -831,8 +831,8 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *altifp) /* * assign a link-local address, if there's none. */ - if (!(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) && - ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL) { + if (!(ifp->if_inet6->nd_flags & ND6_IFF_IFDISABLED) && + ifp->if_inet6->nd_flags & ND6_IFF_AUTO_LINKLOCAL) { struct epoch_tracker et; NET_EPOCH_ENTER(et); @@ -918,7 +918,7 @@ in6_ifdeparture(void *arg __unused, struct ifnet *ifp) _in6_ifdetach(ifp, 1); mld_domifdetach(ifp); scope6_ifdetach(ext->scope6_id); - nd6_ifdetach(ifp, ext->nd_ifinfo); + nd6_ifdetach(ifp); lltable_free(ext->lltable); COUNTER_ARRAY_FREE(ext->in6_ifstat, sizeof(struct in6_ifstat) / sizeof(uint64_t)); diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index 5171bc1d4ea6..d5e8e0f952c6 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -366,7 +366,7 @@ in6_selectsrc(uint32_t fibnum, struct sockaddr_in6 *dstsock, */ /* Rule 5: Prefer outgoing interface */ - if (!(ND_IFINFO(ifp)->flags & ND6_IFF_NO_PREFER_IFACE)) { + if (!(ifp->if_inet6->nd_flags & ND6_IFF_NO_PREFER_IFACE)) { if (ia_best->ia_ifp == ifp && ia->ia_ifp != ifp) NEXT(5); if (ia_best->ia_ifp != ifp && ia->ia_ifp == ifp) @@ -868,7 +868,7 @@ in6_selecthlim(struct inpcb *inp, struct ifnet *ifp) if (inp && inp->in6p_hops >= 0) return (inp->in6p_hops); else if (ifp) - return (ND_IFINFO(ifp)->chlim); + return (ifp->if_inet6->nd_curhoplimit); else if (inp && !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) { struct nhop_object *nh; struct in6_addr dst; @@ -879,7 +879,7 @@ in6_selecthlim(struct inpcb *inp, struct ifnet *ifp) in6_splitscope(&inp->in6p_faddr, &dst, &scopeid); nh = fib6_lookup(fibnum, &dst, scopeid, 0, 0); if (nh != NULL) { - hlim = ND_IFINFO(nh->nh_ifp)->chlim; + hlim = nh->nh_ifp->if_inet6->nd_curhoplimit; return (hlim); } } diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h index f22b75ce71db..514030ed594d 100644 --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -495,15 +495,24 @@ struct in6_ifextra { counter_u64_t in6_ifstat[sizeof(struct in6_ifstat) / sizeof(uint64_t)]; counter_u64_t icmp6_ifstat[sizeof(struct icmp6_ifstat) / sizeof(uint64_t)]; - struct nd_ifinfo *nd_ifinfo; + /* ND6 */ + uint32_t nd_linkmtu; + uint32_t nd_maxmtu; + uint32_t nd_basereachable; + uint32_t nd_reachable; + uint32_t nd_retrans; + uint32_t nd_flags; + int nd_recalc_timer; + u_int nd_dad_failures; + uint8_t nd_curhoplimit; + struct scope6_id *scope6_id; struct lltable *lltable; struct mld_ifsoftc *mld_ifinfo; - u_int dad_failures; /* DAD failures when using RFC 7217 stable addresses */ }; #define LLTABLE6(ifp) ((ifp)->if_inet6->lltable) -#define DAD_FAILURES(ifp) ((ifp)->if_inet6->dad_failures) +#define DAD_FAILURES(ifp) ((ifp)->if_inet6->nd_dad_failures) VNET_DECLARE(struct in6_ifaddrhead, in6_ifaddrhead); VNET_DECLARE(struct in6_ifaddrlisthead *, in6_ifaddrhashtbl); diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 29fa4741a509..62e03a189650 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -551,7 +551,7 @@ ip6_input(struct mbuf *m) * Drop the packet if IPv6 operation is disabled on the interface. */ rcvif = m->m_pkthdr.rcvif; - if ((ND_IFINFO(rcvif)->flags & ND6_IFF_IFDISABLED)) + if ((rcvif->if_inet6->nd_flags & ND6_IFF_IFDISABLED)) goto bad; #if defined(IPSEC) || defined(IPSEC_SUPPORT) diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 25fe8f347e35..a9b31ac8061f 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -2922,7 +2922,7 @@ ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt, return (ENXIO); } if (ifp != NULL && (ifp->if_inet6 == NULL || - (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) != 0)) + (ifp->if_inet6->nd_flags & ND6_IFF_IFDISABLED) != 0)) return (ENETDOWN); if (ifp != NULL && diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 2e59f96a95c3..969b32032a60 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -88,8 +88,6 @@ #define ND6_SLOWTIMER_INTERVAL (60 * 60) /* 1 hour */ #define ND6_RECALC_REACHTM_INTERVAL (60 * 120) /* 2 hours */ -MALLOC_DEFINE(M_IP6NDP, "ip6ndp", "IPv6 Neighbor Discovery"); - VNET_DEFINE_STATIC(int, nd6_prune) = 1; #define V_nd6_prune VNET(nd6_prune) SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_PRUNE, nd6_prune, @@ -150,7 +148,6 @@ int (*send_sendso_input_hook)(struct mbuf *, struct ifnet *, int, int); static bool nd6_is_new_addr_neighbor(const struct sockaddr_in6 *, struct ifnet *); -static void nd6_setmtu0(struct ifnet *, struct nd_ifinfo *); static void nd6_slowtimo(void *); static int regen_tmpaddr(struct in6_ifaddr *); static void nd6_free(struct llentry **, int); @@ -277,24 +274,30 @@ nd6_destroy(void) } #endif -struct nd_ifinfo * +void nd6_ifattach(struct ifnet *ifp) { - struct nd_ifinfo *nd; - - nd = malloc(sizeof(*nd), M_IP6NDP, M_WAITOK | M_ZERO); - nd->initialized = 1; + struct in6_ifextra *nd = ifp->if_inet6; - nd->chlim = IPV6_DEFHLIM; - nd->basereachable = REACHABLE_TIME; - nd->reachable = ND_COMPUTE_RTIME(nd->basereachable); - nd->retrans = RETRANS_TIMER; + nd->nd_linkmtu = 0; + nd->nd_maxmtu = ifp->if_mtu; + nd->nd_basereachable = REACHABLE_TIME; + nd->nd_reachable = ND_COMPUTE_RTIME(nd->nd_basereachable); + nd->nd_retrans = RETRANS_TIMER; + nd->nd_recalc_timer = 0; + nd->nd_dad_failures = 0; + nd->nd_curhoplimit = IPV6_DEFHLIM; - nd->flags = ND6_IFF_PERFORMNUD; + nd->nd_flags = ND6_IFF_PERFORMNUD; /* Set IPv6 disabled on all interfaces but loopback by default. */ - if ((ifp->if_flags & IFF_LOOPBACK) == 0) - nd->flags |= ND6_IFF_IFDISABLED; + if ((ifp->if_flags & IFF_LOOPBACK) == 0) { + nd->nd_flags |= ND6_IFF_IFDISABLED; + if (V_ip6_no_radr) + nd->nd_flags |= ND6_IFF_NO_RADR; + if (V_ip6_use_stableaddr) + nd->nd_flags |= ND6_IFF_STABLEADDR; + } /* A loopback interface always has ND6_IFF_AUTO_LINKLOCAL. * XXXHRS: Clear ND6_IFF_AUTO_LINKLOCAL on an IFT_BRIDGE interface by @@ -303,7 +306,7 @@ nd6_ifattach(struct ifnet *ifp) */ if ((V_ip6_auto_linklocal && ifp->if_type != IFT_BRIDGE && ifp->if_type != IFT_WIREGUARD) || (ifp->if_flags & IFF_LOOPBACK)) - nd->flags |= ND6_IFF_AUTO_LINKLOCAL; + nd->nd_flags |= ND6_IFF_AUTO_LINKLOCAL; /* * A loopback interface does not need to accept RTADV. * XXXHRS: Clear ND6_IFF_ACCEPT_RTADV on an IFT_BRIDGE interface by @@ -314,26 +317,14 @@ nd6_ifattach(struct ifnet *ifp) if (V_ip6_accept_rtadv && !(ifp->if_flags & IFF_LOOPBACK) && (ifp->if_type != IFT_BRIDGE)) { - nd->flags |= ND6_IFF_ACCEPT_RTADV; + nd->nd_flags |= ND6_IFF_ACCEPT_RTADV; /* If we globally accept rtadv, assume IPv6 on. */ - nd->flags &= ~ND6_IFF_IFDISABLED; + nd->nd_flags &= ~ND6_IFF_IFDISABLED; } - if (V_ip6_no_radr && !(ifp->if_flags & IFF_LOOPBACK)) - nd->flags |= ND6_IFF_NO_RADR; - - /* XXX: we cannot call nd6_setmtu since ifp is not fully initialized */ - nd6_setmtu0(ifp, nd); - - /* Configure default value for stable addresses algorithm, skip loopback interface */ - if (V_ip6_use_stableaddr && !(ifp->if_flags & IFF_LOOPBACK)) { - nd->flags |= ND6_IFF_STABLEADDR; - } - - return nd; } void -nd6_ifdetach(struct ifnet *ifp, struct nd_ifinfo *nd) +nd6_ifdetach(struct ifnet *ifp) { struct epoch_tracker et; struct ifaddr *ifa, *next; @@ -347,32 +338,25 @@ nd6_ifdetach(struct ifnet *ifp, struct nd_ifinfo *nd) nd6_dad_stop(ifa); } NET_EPOCH_EXIT(et); - - free(nd, M_IP6NDP); } /* * Reset ND level link MTU. This function is called when the physical MTU * changes, which means we might have to adjust the ND level MTU. + * XXX todo: do not maintain copy of ifp->if_mtu in if_inet6->nd_maxmtu. */ void nd6_setmtu(struct ifnet *ifp) { - /* XXXGL: ??? */ - if (ifp->if_inet6 == NULL) - return; - - nd6_setmtu0(ifp, ND_IFINFO(ifp)); -} + struct in6_ifextra *ndi = ifp->if_inet6; + uint32_t omaxmtu; -/* XXX todo: do not maintain copy of ifp->if_mtu in ndi->maxmtu */ -void -nd6_setmtu0(struct ifnet *ifp, struct nd_ifinfo *ndi) -{ - u_int32_t omaxmtu; + /* XXXGL: safety against IFT_PFSYNC & IFT_PFLOG */ + if (ndi == NULL) + return; - omaxmtu = ndi->maxmtu; - ndi->maxmtu = ifp->if_mtu; + omaxmtu = ndi->nd_maxmtu; + ndi->nd_maxmtu = ifp->if_mtu; /* * Decreasing the interface MTU under IPV6 minimum MTU may cause @@ -380,10 +364,10 @@ nd6_setmtu0(struct ifnet *ifp, struct nd_ifinfo *ndi) * explicitly. The check for omaxmtu is necessary to restrict the * log to the case of changing the MTU, not initializing it. */ - if (omaxmtu >= IPV6_MMTU && ndi->maxmtu < IPV6_MMTU) { - log(LOG_NOTICE, "nd6_setmtu0: " + if (omaxmtu >= IPV6_MMTU && ndi->nd_maxmtu < IPV6_MMTU) { + log(LOG_NOTICE, "%s: " "new link MTU on %s (%lu) is too small for IPv6\n", - if_name(ifp), (unsigned long)ndi->maxmtu); + __func__, if_name(ifp), (unsigned long)ndi->nd_maxmtu); } } @@ -714,12 +698,12 @@ nd6_llinfo_setstate(struct llentry *lle, int newstate) switch (newstate) { case ND6_LLINFO_INCOMPLETE: ifp = lle->lle_tbl->llt_ifp; - delay = (long)ND_IFINFO(ifp)->retrans * hz / 1000; + delay = (long)ifp->if_inet6->nd_retrans * hz / 1000; break; case ND6_LLINFO_REACHABLE: if (!ND6_LLINFO_PERMANENT(lle)) { ifp = lle->lle_tbl->llt_ifp; - delay = (long)ND_IFINFO(ifp)->reachable * hz; + delay = (long)ifp->if_inet6->nd_reachable * hz; } break; case ND6_LLINFO_STALE: @@ -756,7 +740,7 @@ nd6_llinfo_timer(void *arg) struct llentry *ln; struct in6_addr *dst, *pdst, *psrc, src; struct ifnet *ifp; - struct nd_ifinfo *ndi; + struct in6_ifextra *ndi; int do_switch, send_ns; long delay; @@ -790,7 +774,7 @@ nd6_llinfo_timer(void *arg) return; } NET_EPOCH_ENTER(et); - ndi = ND_IFINFO(ifp); + ndi = ifp->if_inet6; send_ns = 0; dst = &ln->r_l3addr.addr6; pdst = dst; @@ -892,7 +876,7 @@ nd6_llinfo_timer(void *arg) /* FALLTHROUGH */ case ND6_LLINFO_DELAY: - if (ndi && (ndi->flags & ND6_IFF_PERFORMNUD) != 0) { + if ((ndi->nd_flags & ND6_IFF_PERFORMNUD) != 0) { /* We need NUD */ ln->la_asked = 1; nd6_llinfo_setstate(ln, ND6_LLINFO_PROBE); @@ -916,7 +900,8 @@ done: if (ln != NULL) ND6_RUNLOCK(); if (send_ns != 0) { - nd6_llinfo_settimer_locked(ln, (long)ndi->retrans * hz / 1000); + nd6_llinfo_settimer_locked(ln, + (long)ndi->nd_retrans * hz / 1000); psrc = nd6_llinfo_get_holdsrc(ln, &src); LLE_FREE_LOCKED(ln); ln = NULL; @@ -1027,10 +1012,10 @@ nd6_timer(void *arg) * mark the address as tentative for future DAD. */ ifp = ia6->ia_ifp; - if ((ND_IFINFO(ifp)->flags & ND6_IFF_NO_DAD) == 0 && + if ((ifp->if_inet6->nd_flags & ND6_IFF_NO_DAD) == 0 && ((ifp->if_flags & IFF_UP) == 0 || (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || - (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) != 0)){ + (ifp->if_inet6->nd_flags & ND6_IFF_IFDISABLED))){ ia6->ia6_flags &= ~IN6_IFF_DUPLICATED; ia6->ia6_flags |= IN6_IFF_TENTATIVE; } @@ -1198,7 +1183,7 @@ nd6_purge(struct ifnet *ifp) if (V_nd6_defifindex == ifp->if_index) nd6_setdefaultiface(0); - if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV) { + if (ifp->if_inet6->nd_flags & ND6_IFF_ACCEPT_RTADV) { /* Refresh default router list. */ defrouter_select_fib(ifp->if_fib); } @@ -1324,7 +1309,7 @@ nd6_is_new_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp) * If the default router list is empty, all addresses are regarded * as on-link, and thus, as a neighbor. */ - if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && + if (ifp->if_inet6->nd_flags & ND6_IFF_ACCEPT_RTADV && nd6_defrouter_list_empty() && V_nd6_defifindex == ifp->if_index) { return (1); @@ -1448,7 +1433,7 @@ nd6_free(struct llentry **lnp, int gc) KASSERT((ln->la_flags & LLE_CHILD) == 0, ("child lle")); ifp = lltable_get_ifp(ln->lle_tbl); - if ((ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV) != 0) + if ((ifp->if_inet6->nd_flags & ND6_IFF_ACCEPT_RTADV) != 0) dr = defrouter_lookup_locked(&ln->r_l3addr.addr6, ifp); else dr = NULL; @@ -1465,7 +1450,7 @@ nd6_free(struct llentry **lnp, int gc) /* cancel timer */ nd6_llinfo_settimer_locked(ln, -1); - if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV) { + if (ifp->if_inet6->nd_flags & ND6_IFF_ACCEPT_RTADV) { if (dr != NULL && dr->expire && ln->ln_state == ND6_LLINFO_STALE && gc) { /* @@ -1640,19 +1625,30 @@ nd6_subscription_cb(struct rib_head *rnh, struct rib_cmd_info *rc, void *arg) int nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) { + struct epoch_tracker et; struct in6_ndireq *ndi = (struct in6_ndireq *)data; struct in6_nbrinfo *nbi = (struct in6_nbrinfo *)data; struct in6_ndifreq *ndif = (struct in6_ndifreq *)data; - struct epoch_tracker et; + struct in6_ifextra *ext = ifp->if_inet6; int error = 0; - /* XXXGL: ??? */ - if (ifp->if_inet6 == NULL) + /* XXXGL: safety against IFT_PFSYNC & IFT_PFLOG */ + if (ext == NULL) return (EPFNOSUPPORT); #define ND ndi->ndi switch (cmd) { case SIOCGIFINFO_IN6: - ND = *ND_IFINFO(ifp); + ND = (struct nd_ifinfo){ + .linkmtu = ext->nd_linkmtu, + .maxmtu = ext->nd_maxmtu, + .basereachable = ext->nd_basereachable, + .reachable = ext->nd_reachable, + .retrans = ext->nd_retrans, + .flags = ext->nd_flags, + .recalctm = ext->nd_recalc_timer, + .chlim = ext->nd_curhoplimit, + .initialized = 1, + }; break; case SIOCSIFINFO_IN6: /* @@ -1666,28 +1662,28 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) error = EINVAL; break; } - ND_IFINFO(ifp)->linkmtu = ND.linkmtu; + ext->nd_linkmtu = ND.linkmtu; } if (ND.basereachable != 0) { - int obasereachable = ND_IFINFO(ifp)->basereachable; + uint32_t obasereachable = ext->nd_basereachable; - ND_IFINFO(ifp)->basereachable = ND.basereachable; + ext->nd_basereachable = ND.basereachable; if (ND.basereachable != obasereachable) - ND_IFINFO(ifp)->reachable = + ext->nd_reachable = ND_COMPUTE_RTIME(ND.basereachable); } if (ND.retrans != 0) - ND_IFINFO(ifp)->retrans = ND.retrans; + ext->nd_retrans = ND.retrans; if (ND.chlim != 0) - ND_IFINFO(ifp)->chlim = ND.chlim; + ext->nd_curhoplimit = ND.chlim; /* FALLTHROUGH */ case SIOCSIFINFO_FLAGS: { struct ifaddr *ifa; struct in6_ifaddr *ia; - if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) && + if ((ext->nd_flags & ND6_IFF_IFDISABLED) && !(ND.flags & ND6_IFF_IFDISABLED)) { /* ifdisabled 1->0 transision */ @@ -1715,18 +1711,18 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) " with a link-local address marked" " duplicate.\n"); } else { - ND_IFINFO(ifp)->flags &= ~ND6_IFF_IFDISABLED; + ext->nd_flags &= ~ND6_IFF_IFDISABLED; if (ifp->if_flags & IFF_UP) in6_if_up(ifp); } - } else if (!(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) && + } else if (!(ext->nd_flags & ND6_IFF_IFDISABLED) && (ND.flags & ND6_IFF_IFDISABLED)) { /* ifdisabled 0->1 transision */ /* Mark all IPv6 address as tentative. */ - ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED; + ext->nd_flags |= ND6_IFF_IFDISABLED; if (V_ip6_dad_count > 0 && - (ND_IFINFO(ifp)->flags & ND6_IFF_NO_DAD) == 0) { + (ext->nd_flags & ND6_IFF_NO_DAD) == 0) { NET_EPOCH_ENTER(et); CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { @@ -1741,11 +1737,11 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) } if (ND.flags & ND6_IFF_AUTO_LINKLOCAL) { - if (!(ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL)) { + if (!(ext->nd_flags & ND6_IFF_AUTO_LINKLOCAL)) { /* auto_linklocal 0->1 transision */ /* If no link-local address on ifp, configure */ - ND_IFINFO(ifp)->flags |= ND6_IFF_AUTO_LINKLOCAL; + ext->nd_flags |= ND6_IFF_AUTO_LINKLOCAL; in6_ifattach(ifp, NULL); } else if (!(ND.flags & ND6_IFF_IFDISABLED) && ifp->if_flags & IFF_UP) { @@ -1771,7 +1767,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) in6_ifattach(ifp, NULL); } } - ND_IFINFO(ifp)->flags = ND.flags; + ext->nd_flags = ND.flags; break; } #undef ND @@ -2108,7 +2104,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr, * cases for safety. */ if ((do_update || is_newentry) && router && - ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV) { + ifp->if_inet6->nd_flags & ND6_IFF_ACCEPT_RTADV) { /* * guaranteed recursion */ @@ -2121,26 +2117,26 @@ nd6_slowtimo(void *arg) { struct epoch_tracker et; CURVNET_SET((struct vnet *) arg); - struct nd_ifinfo *nd6if; + struct in6_ifextra *nd6if; struct ifnet *ifp; callout_reset(&V_nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz, nd6_slowtimo, curvnet); NET_EPOCH_ENTER(et); CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { - if (ifp->if_inet6 == NULL) + if ((nd6if = ifp->if_inet6) == NULL) continue; - nd6if = ND_IFINFO(ifp); - if (nd6if->basereachable && /* already initialized */ - (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) { + if (nd6if->nd_basereachable && /* already initialized */ + (nd6if->nd_recalc_timer -= ND6_SLOWTIMER_INTERVAL) <= 0) { /* * Since reachable time rarely changes by router * advertisements, we SHOULD insure that a new random * value gets recomputed at least once every few hours. * (RFC 2461, 6.3.4) */ - nd6if->recalctm = V_nd6_recalc_reachtm_interval; - nd6if->reachable = ND_COMPUTE_RTIME(nd6if->basereachable); + nd6if->nd_recalc_timer = V_nd6_recalc_reachtm_interval; + nd6if->nd_reachable = + ND_COMPUTE_RTIME(nd6if->nd_basereachable); } } NET_EPOCH_EXIT(et); @@ -2248,7 +2244,7 @@ nd6_resolve(struct ifnet *ifp, int gw_flags, struct mbuf *m, dst6 = (const struct sockaddr_in6 *)sa_dst; /* discard the packet if IPv6 operation is disabled on the interface */ - if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) { + if ((ifp->if_inet6->nd_flags & ND6_IFF_IFDISABLED)) { m_freem(m); return (ENETDOWN); /* better error? */ } diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index c500f236d6ff..a22a0e24735b 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -81,10 +81,6 @@ struct llentry; #define ND6_IFF_IPV6_ONLY_MASK (ND6_IFF_IPV6_ONLY|ND6_IFF_IPV6_ONLY_MANUAL) #endif -#ifdef _KERNEL -#define ND_IFINFO(ifp) ((if_getinet6(ifp))->nd_ifinfo) -#endif - struct in6_nbrinfo { char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */ struct in6_addr addr; /* IPv6 address of the neighbor */ @@ -235,10 +231,6 @@ struct nd_pfxrouter { struct nd_defrouter *router; }; -#ifdef MALLOC_DECLARE -MALLOC_DECLARE(M_IP6NDP); -#endif - /* nd6.c */ VNET_DECLARE(int, nd6_mmaxtries); VNET_DECLARE(struct nd_prhead, nd_prefix); @@ -331,8 +323,8 @@ void nd6_init(void); #ifdef VIMAGE void nd6_destroy(void); #endif -struct nd_ifinfo *nd6_ifattach(struct ifnet *); -void nd6_ifdetach(struct ifnet *, struct nd_ifinfo *); +void nd6_ifattach(struct ifnet *); +void nd6_ifdetach(struct ifnet *); int nd6_is_addr_neighbor(const struct sockaddr_in6 *, struct ifnet *); void nd6_option_init(void *, int, union nd_opts *); struct nd_opt_hdr *nd6_option(union nd_opts *); diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index aa7cb3b41973..4da62575eaac 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -80,6 +80,8 @@ #define SDL(s) ((struct sockaddr_dl *)s) +MALLOC_DECLARE(M_IP6NDP); + struct dadq; static struct dadq *nd6_dad_find(struct ifaddr *, struct nd_opt_nonce *); static void nd6_dad_add(struct dadq *dp); @@ -173,7 +175,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) goto bad; rflag = (V_ip6_forwarding) ? ND_NA_FLAG_ROUTER : 0; - if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && V_ip6_norbit_raif) + if (ifp->if_inet6->nd_flags & ND6_IFF_ACCEPT_RTADV && V_ip6_norbit_raif) rflag = 0; if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) { @@ -910,7 +912,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) nd6_ifp = lltable_get_ifp(ln->lle_tbl); if (!defrouter_remove(&ln->r_l3addr.addr6, nd6_ifp) && - (ND_IFINFO(nd6_ifp)->flags & + (nd6_ifp->if_inet6->nd_flags & ND6_IFF_ACCEPT_RTADV) != 0) /* * Even if the neighbor is not in the default @@ -1281,13 +1283,13 @@ nd6_dad_start(struct ifaddr *ifa, int delay) */ if ((ia->ia6_flags & IN6_IFF_ANYCAST) != 0 || V_ip6_dad_count == 0 || - (ND_IFINFO(ifa->ifa_ifp)->flags & ND6_IFF_NO_DAD) != 0) { + (ifa->ifa_ifp->if_inet6->nd_flags & ND6_IFF_NO_DAD) != 0) { ia->ia6_flags &= ~IN6_IFF_TENTATIVE; return; } if ((ifa->ifa_ifp->if_flags & IFF_UP) == 0 || (ifa->ifa_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || - (ND_IFINFO(ifa->ifa_ifp)->flags & ND6_IFF_IFDISABLED) != 0) + (ifa->ifa_ifp->if_inet6->nd_flags & ND6_IFF_IFDISABLED) != 0) return; DADQ_WLOCK(); @@ -1377,7 +1379,7 @@ nd6_dad_timer(void *arg) KASSERT(ia != NULL, ("DAD entry %p with no address", dp)); NET_EPOCH_ENTER(et); - if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) { + if (ifp->if_inet6->nd_flags & ND6_IFF_IFDISABLED) { /* Do not need DAD for ifdisabled interface. */ log(LOG_ERR, "nd6_dad_timer: cancel DAD on %s because of " "ND6_IFF_IFDISABLED.\n", ifp->if_xname); @@ -1414,7 +1416,7 @@ nd6_dad_timer(void *arg) * We have more NS to go. Send NS packet for DAD. */ nd6_dad_starttimer(dp, - (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); + (long)ifa->ifa_ifp->if_inet6->nd_retrans * hz / 1000); nd6_dad_ns_output(dp); goto done; } else { @@ -1446,7 +1448,7 @@ nd6_dad_timer(void *arg) dp->dad_count = dp->dad_ns_ocount + V_nd6_mmaxtries - 1; nd6_dad_starttimer(dp, - (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000); + (long)ifa->ifa_ifp->if_inet6->nd_retrans * hz / 1000); nd6_dad_ns_output(dp); goto done; } else { @@ -1458,9 +1460,9 @@ nd6_dad_timer(void *arg) * * Reset DAD failures counter if using stable addresses. */ - if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) == 0) { + if ((ifp->if_inet6->nd_flags & ND6_IFF_IFDISABLED) == 0) { ia->ia6_flags &= ~IN6_IFF_TENTATIVE; - if ((ND_IFINFO(ifp)->flags & ND6_IFF_STABLEADDR) && !(ia->ia6_flags & IN6_IFF_TEMPORARY)) + if ((ifp->if_inet6->nd_flags & ND6_IFF_STABLEADDR) && !(ia->ia6_flags & IN6_IFF_TEMPORARY)) atomic_store_int(&DAD_FAILURES(ifp), 0); } @@ -1509,7 +1511,7 @@ nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp) * For RFC 7217 stable addresses, increment failure counter here if we still have retries. * More addresses will be generated as long as retries are not exhausted. */ - if ((ND_IFINFO(ifp)->flags & ND6_IFF_STABLEADDR) && !(ia->ia6_flags & IN6_IFF_TEMPORARY)) { + if ((ifp->if_inet6->nd_flags & ND6_IFF_STABLEADDR) && !(ia->ia6_flags & IN6_IFF_TEMPORARY)) { u_int dad_failures = atomic_load_int(&DAD_FAILURES(ifp)); if (dad_failures <= V_ip6_stableaddr_maxretries) { @@ -1547,7 +1549,7 @@ nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp) in6 = ia->ia_addr.sin6_addr; if (in6_get_hw_ifid(ifp, &in6) == 0 && IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, &in6)) { - ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED; + ifp->if_inet6->nd_flags |= ND6_IFF_IFDISABLED; log(LOG_ERR, "%s: possible hardware address " "duplication detected, disable IPv6\n", if_name(ifp)); diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index 821d6b27bc43..0ca97125110c 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -75,6 +75,8 @@ #include <machine/atomic.h> +MALLOC_DEFINE(M_IP6NDP, "ip6ndp", "IPv6 Neighbor Discovery"); + static struct nd_defrouter *defrtrlist_update(struct nd_defrouter *); static int prelist_update(struct nd_prefixctl *, struct nd_defrouter *, struct mbuf *, int); @@ -175,7 +177,7 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len) * Accept RS only when V_ip6_forwarding=1 and the interface has * no ND6_IFF_ACCEPT_RTADV. */ - if (!V_ip6_forwarding || ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV) + if (!V_ip6_forwarding || ifp->if_inet6->nd_flags & ND6_IFF_ACCEPT_RTADV) goto freeit; /* RFC 6980: Nodes MUST silently ignore fragments */ @@ -280,7 +282,7 @@ defrtr_ipv6_only_ifp(struct ifnet *ifp) ND6_RUNLOCK(); IF_ADDR_WLOCK(ifp); - ipv6_only_old = ND_IFINFO(ifp)->flags & ND6_IFF_IPV6_ONLY; + ipv6_only_old = ifp->if_inet6->nd_flags & ND6_IFF_IPV6_ONLY; IF_ADDR_WUNLOCK(ifp); /* If nothing changed, we have an early exit. */ @@ -317,9 +319,9 @@ defrtr_ipv6_only_ifp(struct ifnet *ifp) IF_ADDR_WLOCK(ifp); if (ipv6_only) - ND_IFINFO(ifp)->flags |= ND6_IFF_IPV6_ONLY; + ifp->if_inet6->nd_flags |= ND6_IFF_IPV6_ONLY; else - ND_IFINFO(ifp)->flags &= ~ND6_IFF_IPV6_ONLY; + ifp->if_inet6->nd_flags &= ~ND6_IFF_IPV6_ONLY; IF_ADDR_WUNLOCK(ifp); #ifdef notyet @@ -332,7 +334,7 @@ defrtr_ipv6_only_ipf_down(struct ifnet *ifp) { IF_ADDR_WLOCK(ifp); - ND_IFINFO(ifp)->flags &= ~ND6_IFF_IPV6_ONLY; + ifp->if_inet6->nd_flags &= ~ND6_IFF_IPV6_ONLY; IF_ADDR_WUNLOCK(ifp); } #endif /* EXPERIMENTAL */ @@ -364,7 +366,7 @@ void nd6_ra_input(struct mbuf *m, int off, int icmp6len) { struct ifnet *ifp; - struct nd_ifinfo *ndi; + struct in6_ifextra *ndi; struct ip6_hdr *ip6; struct nd_router_advert *nd_ra; struct in6_addr saddr6; @@ -378,8 +380,8 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len) * ND6_IFF_ACCEPT_RTADV is on the receiving interface. */ ifp = m->m_pkthdr.rcvif; - ndi = ND_IFINFO(ifp); - if (!(ndi->flags & ND6_IFF_ACCEPT_RTADV)) + ndi = ifp->if_inet6; + if (!(ndi->nd_flags & ND6_IFF_ACCEPT_RTADV)) goto freeit; /* RFC 6980: Nodes MUST silently ignore fragments */ @@ -441,7 +443,7 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len) * ND6_IFF_NO_RADR enabled on the receiving interface or * (ip6.forwarding == 1 && ip6.rfc6204w3 != 1). */ - if (ndi->flags & ND6_IFF_NO_RADR) + if (ndi->nd_flags & ND6_IFF_NO_RADR) dr0.rtlifetime = 0; *** 88 LINES SKIPPED ***
