summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet6/nd6.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netinet6/nd6.c')
-rw-r--r--freebsd/sys/netinet6/nd6.c138
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), "");