Index: head/sys/netinet6/nd6.h =================================================================== --- head/sys/netinet6/nd6.h +++ head/sys/netinet6/nd6.h @@ -476,6 +476,7 @@ /* 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); Index: head/sys/netinet6/nd6.c =================================================================== --- head/sys/netinet6/nd6.c +++ head/sys/netinet6/nd6.c @@ -113,7 +113,7 @@ 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 @@ 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 @@ 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); } Index: head/sys/netinet6/nd6_rtr.c =================================================================== --- head/sys/netinet6/nd6_rtr.c +++ head/sys/netinet6/nd6_rtr.c @@ -285,7 +285,32 @@ /* 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.