diff options
Diffstat (limited to 'freebsd/sys/netinet6/nd6.c')
-rw-r--r-- | freebsd/sys/netinet6/nd6.c | 138 |
1 files changed, 20 insertions, 118 deletions
diff --git a/freebsd/sys/netinet6/nd6.c b/freebsd/sys/netinet6/nd6.c index 140dde59..aea8168e 100644 --- a/freebsd/sys/netinet6/nd6.c +++ b/freebsd/sys/netinet6/nd6.c @@ -117,7 +117,6 @@ VNET_DEFINE(int, nd6_debug) = 0; static eventhandler_tag lle_event_eh, iflladdr_event_eh; -VNET_DEFINE(struct nd_drhead, nd_defrouter); VNET_DEFINE(struct nd_prhead, nd_prefix); VNET_DEFINE(struct rwlock, nd6_lock); VNET_DEFINE(uint64_t, nd6_list_genid); @@ -147,9 +146,11 @@ static int nd6_need_cache(struct ifnet *); VNET_DEFINE_STATIC(struct callout, nd6_slowtimo_ch); #define V_nd6_slowtimo_ch VNET(nd6_slowtimo_ch) -VNET_DEFINE(struct callout, nd6_timer_ch); +VNET_DEFINE_STATIC(struct callout, nd6_timer_ch); #define V_nd6_timer_ch VNET(nd6_timer_ch) +SYSCTL_DECL(_net_inet6_icmp6); + static void nd6_lle_event(void *arg __unused, struct llentry *lle, int evt) { @@ -219,7 +220,7 @@ nd6_init(void) rw_init(&V_nd6_lock, "nd6 list"); LIST_INIT(&V_nd_prefix); - TAILQ_INIT(&V_nd_defrouter); + nd6_defrouter_init(); /* Start timers. */ callout_init(&V_nd6_slowtimo_ch, 0); @@ -894,27 +895,15 @@ void nd6_timer(void *arg) { CURVNET_SET((struct vnet *) arg); - struct nd_drhead drq; struct nd_prhead prl; - struct nd_defrouter *dr, *ndr; struct nd_prefix *pr, *npr; struct ifnet *ifp; struct in6_ifaddr *ia6, *nia6; uint64_t genid; - TAILQ_INIT(&drq); LIST_INIT(&prl); - ND6_WLOCK(); - TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, ndr) - if (dr->expire && dr->expire < time_uptime) - defrouter_unlink(dr, &drq); - ND6_WUNLOCK(); - - while ((dr = TAILQ_FIRST(&drq)) != NULL) { - TAILQ_REMOVE(&drq, dr, dr_entry); - defrouter_del(dr); - } + nd6_defrouter_timer(); /* * expire interface addresses. @@ -1137,34 +1126,15 @@ regen_tmpaddr(struct in6_ifaddr *ia6) void nd6_purge(struct ifnet *ifp) { - struct nd_drhead drq; struct nd_prhead prl; - struct nd_defrouter *dr, *ndr; struct nd_prefix *pr, *npr; - TAILQ_INIT(&drq); LIST_INIT(&prl); - /* - * Nuke default router list entries toward ifp. - * We defer removal of default router list entries that is installed - * in the routing table, in order to keep additional side effects as - * small as possible. - */ - ND6_WLOCK(); - TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, ndr) { - if (dr->installed) - continue; - if (dr->ifp == ifp) - defrouter_unlink(dr, &drq); - } - TAILQ_FOREACH_SAFE(dr, &V_nd_defrouter, dr_entry, ndr) { - if (!dr->installed) - continue; - if (dr->ifp == ifp) - defrouter_unlink(dr, &drq); - } + /* Purge default router list entries toward ifp. */ + nd6_defrouter_purge(ifp); + ND6_WLOCK(); /* * Remove prefixes on ifp. We should have already removed addresses on * this interface, so no addresses should be referencing these prefixes. @@ -1175,11 +1145,7 @@ nd6_purge(struct ifnet *ifp) } ND6_WUNLOCK(); - /* Delete the unlinked router and prefix objects. */ - while ((dr = TAILQ_FIRST(&drq)) != NULL) { - TAILQ_REMOVE(&drq, dr, dr_entry); - defrouter_del(dr); - } + /* Delete the unlinked prefix objects. */ while ((pr = LIST_FIRST(&prl)) != NULL) { LIST_REMOVE(pr, ndpr_entry); nd6_prefix_del(pr); @@ -1365,7 +1331,7 @@ restart: * as on-link, and thus, as a neighbor. */ if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && - TAILQ_EMPTY(&V_nd_defrouter) && + nd6_defrouter_list_empty() && V_nd6_defifindex == ifp->if_index) { return (1); } @@ -1808,22 +1774,9 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) case SIOCSRTRFLUSH_IN6: { /* flush all the default routers */ - struct nd_drhead drq; - struct nd_defrouter *dr; - - TAILQ_INIT(&drq); defrouter_reset(); - - ND6_WLOCK(); - while ((dr = TAILQ_FIRST(&V_nd_defrouter)) != NULL) - defrouter_unlink(dr, &drq); - ND6_WUNLOCK(); - while ((dr = TAILQ_FIRST(&drq)) != NULL) { - TAILQ_REMOVE(&drq, dr, dr_entry); - defrouter_del(dr); - } - + nd6_defrouter_flush_all(); defrouter_select(); break; } @@ -2367,13 +2320,7 @@ nd6_resolve_slow(struct ifnet *ifp, int flags, struct mbuf *m, } } if (lle == NULL) { - if (!(ND_IFINFO(ifp)->flags & ND6_IFF_PERFORMNUD)) { - m_freem(m); - return (ENOBUFS); - } - - if (m != NULL) - m_freem(m); + m_freem(m); return (ENOBUFS); } @@ -2616,59 +2563,6 @@ clear_llinfo_pqueue(struct llentry *ln) ln->la_hold = NULL; } -static int nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS); -static int nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS); - -SYSCTL_DECL(_net_inet6_icmp6); -SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_DRLIST, nd6_drlist, - CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, - NULL, 0, nd6_sysctl_drlist, "S,in6_defrouter", - "NDP default router list"); -SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_PRLIST, nd6_prlist, - CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, - NULL, 0, nd6_sysctl_prlist, "S,in6_prefix", - "NDP prefix list"); -SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXQLEN, nd6_maxqueuelen, - CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_maxqueuelen), 1, ""); -SYSCTL_INT(_net_inet6_icmp6, OID_AUTO, nd6_gctimer, - CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_gctimer), (60 * 60 * 24), ""); - -static int -nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS) -{ - struct in6_defrouter d; - struct nd_defrouter *dr; - int error; - - if (req->newptr != NULL) - return (EPERM); - - error = sysctl_wire_old_buffer(req, 0); - if (error != 0) - return (error); - - bzero(&d, sizeof(d)); - d.rtaddr.sin6_family = AF_INET6; - d.rtaddr.sin6_len = sizeof(d.rtaddr); - - ND6_RLOCK(); - TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) { - d.rtaddr.sin6_addr = dr->rtaddr; - error = sa6_recoverscope(&d.rtaddr); - if (error != 0) - break; - d.flags = dr->raflags; - d.rtlifetime = dr->rtlifetime; - d.expire = dr->expire + (time_second - time_uptime); - d.if_index = dr->ifp->if_index; - error = SYSCTL_OUT(req, &d, sizeof(d)); - if (error != 0) - break; - } - ND6_RUNLOCK(); - return (error); -} - static int nd6_sysctl_prlist(SYSCTL_HANDLER_ARGS) { @@ -2742,3 +2636,11 @@ out: ND6_RUNLOCK(); return (error); } +SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_PRLIST, nd6_prlist, + CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE, + NULL, 0, nd6_sysctl_prlist, "S,in6_prefix", + "NDP prefix list"); +SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXQLEN, nd6_maxqueuelen, + CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_maxqueuelen), 1, ""); +SYSCTL_INT(_net_inet6_icmp6, OID_AUTO, nd6_gctimer, + CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(nd6_gctimer), (60 * 60 * 24), ""); |