summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2016-03-17 19:01:44 +0000
committermarkj <markj@FreeBSD.org>2016-03-17 19:01:44 +0000
commit8c873a2b1b739e5168f3c8a74fe25a6e5d4c3b04 (patch)
treef1a4a3a309fcccdeeb401a3627f503f301ed4bc2 /sys/netinet6
parent6b1b5da7587e3a6e2aab4f7b06ae87890f52b730 (diff)
downloadFreeBSD-src-8c873a2b1b739e5168f3c8a74fe25a6e5d4c3b04.zip
FreeBSD-src-8c873a2b1b739e5168f3c8a74fe25a6e5d4c3b04.tar.gz
Modify defrouter_remove() to perform the router lookup before removal.
This allows some simplification of its callers. No functional change intended. Tested by: Larry Rosenman (as part of a larger change) MFC after: 1 month
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/nd6.h2
-rw-r--r--sys/netinet6/nd6_nbr.c31
-rw-r--r--sys/netinet6/nd6_rtr.c60
3 files changed, 39 insertions, 54 deletions
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index 4c83467..149e6f5 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -459,7 +459,7 @@ void defrouter_reset(void);
void defrouter_select(void);
void defrouter_ref(struct nd_defrouter *);
void defrouter_rele(struct nd_defrouter *);
-void defrouter_remove(struct nd_defrouter *);
+bool defrouter_remove(struct in6_addr *, struct ifnet *);
void defrouter_unlink(struct nd_defrouter *, struct nd_drhead *);
void defrouter_del(struct nd_defrouter *);
void prelist_remove(struct nd_prefix *);
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index d528575..d621b52 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -857,30 +857,19 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
* Remove the sender from the Default Router List and
* update the Destination Cache entries.
*/
- struct nd_defrouter *dr;
struct ifnet *nd6_ifp;
nd6_ifp = lltable_get_ifp(ln->lle_tbl);
- ND6_WLOCK();
- dr = defrouter_lookup_locked(&ln->r_l3addr.addr6,
- nd6_ifp);
- if (dr != NULL) {
- /* releases the ND lock */
- defrouter_remove(dr);
- dr = NULL;
- } else {
- ND6_WUNLOCK();
- if ((ND_IFINFO(nd6_ifp)->flags & ND6_IFF_ACCEPT_RTADV) != 0) {
- /*
- * Even if the neighbor is not in the default
- * router list, the neighbor may be used
- * as a next hop for some destinations
- * (e.g. redirect case). So we must
- * call rt6_flush explicitly.
- */
- rt6_flush(&ip6->ip6_src, ifp);
- }
- }
+ if (!defrouter_remove(&ln->r_l3addr.addr6, nd6_ifp) &&
+ (ND_IFINFO(nd6_ifp)->flags &
+ ND6_IFF_ACCEPT_RTADV) != 0)
+ /*
+ * Even if the neighbor is not in the default
+ * router list, the neighbor may be used as a
+ * next hop for some destinations (e.g. redirect
+ * case). So we must call rt6_flush explicitly.
+ */
+ rt6_flush(&ip6->ip6_src, ifp);
}
ln->ln_router = is_router;
}
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index 294c90a..6fee830 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -627,22 +627,26 @@ defrouter_reset(void)
}
/*
- * Remove a router from the global list and free it.
- *
- * The ND lock must be held and is released before returning. The caller must
- * hold a reference on the router object.
+ * Look up a matching default router list entry and remove it. Returns true if a
+ * matching entry was found, false otherwise.
*/
-void
-defrouter_remove(struct nd_defrouter *dr)
+bool
+defrouter_remove(struct in6_addr *addr, struct ifnet *ifp)
{
+ struct nd_defrouter *dr;
- ND6_WLOCK_ASSERT();
- KASSERT(dr->refcnt >= 2, ("unexpected refcount 0x%x", dr->refcnt));
+ ND6_WLOCK();
+ dr = defrouter_lookup_locked(addr, ifp);
+ if (dr == NULL) {
+ ND6_WUNLOCK();
+ return (false);
+ }
defrouter_unlink(dr, NULL);
ND6_WUNLOCK();
defrouter_del(dr);
defrouter_rele(dr);
+ return (true);
}
/*
@@ -850,14 +854,14 @@ defrtrlist_update(struct nd_defrouter *new)
struct nd_defrouter *dr, *n;
int oldpref;
- ND6_WLOCK();
- if ((dr = defrouter_lookup_locked(&new->rtaddr, new->ifp)) != NULL) {
- if (new->rtlifetime == 0) {
- /* releases the ND lock */
- defrouter_remove(dr);
- return (NULL);
- }
+ if (new->rtlifetime == 0) {
+ defrouter_remove(&new->rtaddr, new->ifp);
+ return (NULL);
+ }
+ ND6_WLOCK();
+ dr = defrouter_lookup_locked(&new->rtaddr, new->ifp);
+ if (dr != NULL) {
oldpref = rtpref(dr);
/* override */
@@ -881,25 +885,17 @@ defrtrlist_update(struct nd_defrouter *new)
*/
TAILQ_REMOVE(&V_nd_defrouter, dr, dr_entry);
n = dr;
- goto insert;
- }
-
- /* entry does not exist */
- if (new->rtlifetime == 0) {
- ND6_WUNLOCK();
- return (NULL);
- }
-
- n = malloc(sizeof(*n), M_IP6NDP, M_NOWAIT | M_ZERO);
- if (n == NULL) {
- ND6_WUNLOCK();
- return (NULL);
+ } else {
+ n = malloc(sizeof(*n), M_IP6NDP, M_NOWAIT | M_ZERO);
+ if (n == NULL) {
+ ND6_WUNLOCK();
+ return (NULL);
+ }
+ memcpy(n, new, sizeof(*n));
+ /* Initialize with an extra reference for the caller. */
+ refcount_init(&n->refcnt, 2);
}
- memcpy(n, new, sizeof(*n));
- /* Initialize with an extra reference for the caller. */
- refcount_init(&n->refcnt, 2);
-insert:
/*
* Insert the new router in the Default Router List;
* The Default Router List should be in the descending order
OpenPOWER on IntegriCloud