Update for IETF draft-ietf-6man-ipv6only-flag.

When we roam between networks and our link-state goes down, automatically remove
the IPv6-Only flag from the interface.  Otherwise we might switch from an
IPv6-only to and IPv4-only network and the flag would stay and we would prevent
IPv4 from working.

While the actual function call to clear the flag is under EXPERIMENTAL,
the eventhandler is not as we might want to re-use it for other
functionality on link-down event (such was re-calculate default routers
for example if there is more than one).

Reviewed by:	hrs
Differential Revision:	https://reviews.freebsd.org/D19487
This commit is contained in:
Bjoern A. Zeeb 2019-03-07 23:03:39 +00:00
parent ede8782611
commit 30b450774e
3 changed files with 30 additions and 1 deletions

View File

@ -113,7 +113,7 @@ VNET_DEFINE(int, nd6_debug) = 1;
VNET_DEFINE(int, nd6_debug) = 0;
#endif
static eventhandler_tag lle_event_eh, iflladdr_event_eh;
static eventhandler_tag lle_event_eh, iflladdr_event_eh, ifnet_link_event_eh;
VNET_DEFINE(struct nd_drhead, nd_defrouter);
VNET_DEFINE(struct nd_prhead, nd_prefix);
@ -233,6 +233,8 @@ nd6_init(void)
NULL, EVENTHANDLER_PRI_ANY);
iflladdr_event_eh = EVENTHANDLER_REGISTER(iflladdr_event,
nd6_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
ifnet_link_event_eh = EVENTHANDLER_REGISTER(ifnet_link_event,
nd6_ifnet_link_event, NULL, EVENTHANDLER_PRI_ANY);
}
}
@ -244,6 +246,7 @@ nd6_destroy()
callout_drain(&V_nd6_slowtimo_ch);
callout_drain(&V_nd6_timer_ch);
if (IS_DEFAULT_VNET(curvnet)) {
EVENTHANDLER_DEREGISTER(ifnet_link_event, ifnet_link_event_eh);
EVENTHANDLER_DEREGISTER(lle_event, lle_event_eh);
EVENTHANDLER_DEREGISTER(iflladdr_event, iflladdr_event_eh);
}

View File

@ -476,6 +476,7 @@ void nd6_dad_stop(struct ifaddr *);
/* nd6_rtr.c */
void nd6_rs_input(struct mbuf *, int, int);
void nd6_ra_input(struct mbuf *, int, int);
void nd6_ifnet_link_event(void *, struct ifnet *, int);
void defrouter_reset(void);
void defrouter_select_fib(int fibnum);
void defrouter_select(void);

View File

@ -285,8 +285,33 @@ defrtr_ipv6_only_ifp(struct ifnet *ifp)
/* Send notification of flag change. */
#endif
}
static void
defrtr_ipv6_only_ipf_down(struct ifnet *ifp)
{
IF_AFDATA_WLOCK(ifp);
ND_IFINFO(ifp)->flags &= ~ND6_IFF_IPV6_ONLY;
IF_AFDATA_WUNLOCK(ifp);
}
#endif /* EXPERIMENTAL */
void
nd6_ifnet_link_event(void *arg __unused, struct ifnet *ifp, int linkstate)
{
/*
* XXX-BZ we might want to trigger re-evaluation of our default router
* availability. E.g., on link down the default router might be
* unreachable but a different interface might still have connectivity.
*/
#ifdef EXPERIMENTAL
if (linkstate == LINK_STATE_DOWN)
defrtr_ipv6_only_ipf_down(ifp);
#endif
}
/*
* Receive Router Advertisement Message.
*