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
This commit is contained in:
Mark Johnston 2016-03-17 19:01:44 +00:00
parent 48cc2d5e22
commit ff63037da1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=296991
3 changed files with 39 additions and 54 deletions

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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;
} 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);
}
/* 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);
}
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