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
This commit is contained in:
+2
-2
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+16
-16
@@ -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 @@ in6_addifaddr(struct ifnet *ifp, struct in6_aliasreq *ifra, struct in6_ifaddr *i
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-3
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
+84
-88
@@ -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;
|
||||
struct in6_ifextra *nd = ifp->if_inet6;
|
||||
|
||||
nd = malloc(sizeof(*nd), M_IP6NDP, M_WAITOK | M_ZERO);
|
||||
nd->initialized = 1;
|
||||
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->chlim = IPV6_DEFHLIM;
|
||||
nd->basereachable = REACHABLE_TIME;
|
||||
nd->reachable = ND_COMPUTE_RTIME(nd->basereachable);
|
||||
nd->retrans = RETRANS_TIMER;
|
||||
|
||||
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)
|
||||
struct in6_ifextra *ndi = ifp->if_inet6;
|
||||
uint32_t omaxmtu;
|
||||
|
||||
/* XXXGL: safety against IFT_PFSYNC & IFT_PFLOG */
|
||||
if (ndi == NULL)
|
||||
return;
|
||||
|
||||
nd6_setmtu0(ifp, ND_IFINFO(ifp));
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
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 @@ nd6_llinfo_timer(void *arg)
|
||||
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? */
|
||||
}
|
||||
|
||||
+2
-10
@@ -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 *);
|
||||
|
||||
+13
-11
@@ -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));
|
||||
|
||||
+30
-26
@@ -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;
|
||||
else if (V_ip6_forwarding && !V_ip6_rfc6204w3)
|
||||
dr0.rtlifetime = 0;
|
||||
@@ -453,22 +455,24 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
|
||||
if (advreachable) {
|
||||
advreachable = ntohl(advreachable);
|
||||
if (advreachable <= MAX_REACHABLE_TIME &&
|
||||
ndi->basereachable != advreachable) {
|
||||
ndi->basereachable = advreachable;
|
||||
ndi->reachable = ND_COMPUTE_RTIME(ndi->basereachable);
|
||||
ndi->recalctm = V_nd6_recalc_reachtm_interval; /* reset */
|
||||
ndi->nd_basereachable != advreachable) {
|
||||
ndi->nd_basereachable = advreachable;
|
||||
ndi->nd_reachable =
|
||||
ND_COMPUTE_RTIME(ndi->nd_basereachable);
|
||||
ndi->nd_recalc_timer = V_nd6_recalc_reachtm_interval;
|
||||
}
|
||||
}
|
||||
if (nd_ra->nd_ra_retransmit)
|
||||
ndi->retrans = ntohl(nd_ra->nd_ra_retransmit);
|
||||
ndi->nd_retrans = ntohl(nd_ra->nd_ra_retransmit);
|
||||
if (nd_ra->nd_ra_curhoplimit) {
|
||||
if (ndi->chlim < nd_ra->nd_ra_curhoplimit)
|
||||
ndi->chlim = nd_ra->nd_ra_curhoplimit;
|
||||
else if (ndi->chlim != nd_ra->nd_ra_curhoplimit) {
|
||||
if (ndi->nd_curhoplimit < nd_ra->nd_ra_curhoplimit)
|
||||
ndi->nd_curhoplimit = nd_ra->nd_ra_curhoplimit;
|
||||
else if (ndi->nd_curhoplimit != nd_ra->nd_ra_curhoplimit) {
|
||||
log(LOG_ERR, "RA with a lower CurHopLimit sent from "
|
||||
"%s on %s (current = %d, received = %d). "
|
||||
"Ignored.\n", ip6_sprintf(ip6bufs, &ip6->ip6_src),
|
||||
if_name(ifp), ndi->chlim, nd_ra->nd_ra_curhoplimit);
|
||||
if_name(ifp), ndi->nd_curhoplimit,
|
||||
nd_ra->nd_ra_curhoplimit);
|
||||
}
|
||||
}
|
||||
dr = defrtrlist_update(&dr0);
|
||||
@@ -557,11 +561,11 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
|
||||
}
|
||||
|
||||
/* upper bound */
|
||||
maxmtu = (ndi->maxmtu && ndi->maxmtu < ifp->if_mtu)
|
||||
? ndi->maxmtu : ifp->if_mtu;
|
||||
maxmtu = (ndi->nd_maxmtu && ndi->nd_maxmtu < ifp->if_mtu)
|
||||
? ndi->nd_maxmtu : ifp->if_mtu;
|
||||
if (mtu <= maxmtu) {
|
||||
if (ndi->linkmtu != mtu) {
|
||||
ndi->linkmtu = mtu;
|
||||
if (ndi->nd_linkmtu != mtu) {
|
||||
ndi->nd_linkmtu = mtu;
|
||||
rt_updatemtu(ifp);
|
||||
}
|
||||
} else {
|
||||
@@ -751,7 +755,7 @@ defrouter_del(struct nd_defrouter *dr)
|
||||
* Flush all the routing table entries that use the router
|
||||
* as a next hop.
|
||||
*/
|
||||
if (ND_IFINFO(dr->ifp)->flags & ND6_IFF_ACCEPT_RTADV)
|
||||
if (dr->ifp->if_inet6->nd_flags & ND6_IFF_ACCEPT_RTADV)
|
||||
rt6_flush(&dr->rtaddr, dr->ifp);
|
||||
|
||||
#ifdef EXPERIMENTAL
|
||||
@@ -1202,7 +1206,7 @@ in6_ifadd(struct nd_prefixctl *pr, int mcast)
|
||||
/* make ifaddr */
|
||||
in6_prepare_ifra(&ifra, &pr->ndpr_prefix.sin6_addr, &mask);
|
||||
|
||||
if (ND_IFINFO(ifp)->flags & ND6_IFF_STABLEADDR) {
|
||||
if (ifp->if_inet6->nd_flags & ND6_IFF_STABLEADDR) {
|
||||
memcpy(&newaddr, &pr->ndpr_prefix.sin6_addr, sizeof(pr->ndpr_prefix.sin6_addr));
|
||||
|
||||
if(!in6_get_stableifid(ifp, &newaddr, prefixlen))
|
||||
@@ -1693,7 +1697,7 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
|
||||
* if stable addresses (RFC 7217) are enabled, mark that a temporary address has been found
|
||||
* to avoid generating uneeded extra ones.
|
||||
*/
|
||||
if (ND_IFINFO(ifp)->flags & ND6_IFF_STABLEADDR)
|
||||
if (ifp->if_inet6->nd_flags & ND6_IFF_STABLEADDR)
|
||||
has_temporary = true;
|
||||
|
||||
if (V_ip6_temp_valid_lifetime >
|
||||
@@ -1735,7 +1739,7 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
|
||||
* between here and when a new address is generated, but this will cause that generation
|
||||
* to fail and no further retries should happen.
|
||||
*/
|
||||
if (ND_IFINFO(ifp)->flags & ND6_IFF_STABLEADDR &&
|
||||
if (ifp->if_inet6->nd_flags & ND6_IFF_STABLEADDR &&
|
||||
atomic_load_int(&DAD_FAILURES(ifp)) <= V_ip6_stableaddr_maxretries &&
|
||||
ifa6->ia6_flags & (IN6_IFF_DUPLICATED | IN6_IFF_TEMPORARY))
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user