Author: markj
Date: Thu Mar 17 19:01:44 2016
New Revision: 296991
URL: https://svnweb.freebsd.org/changeset/base/296991

Log:
  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

Modified:
  head/sys/netinet6/nd6.h
  head/sys/netinet6/nd6_nbr.c
  head/sys/netinet6/nd6_rtr.c

Modified: head/sys/netinet6/nd6.h
==============================================================================
--- head/sys/netinet6/nd6.h     Thu Mar 17 18:55:54 2016        (r296990)
+++ head/sys/netinet6/nd6.h     Thu Mar 17 19:01:44 2016        (r296991)
@@ -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 *);

Modified: head/sys/netinet6/nd6_nbr.c
==============================================================================
--- head/sys/netinet6/nd6_nbr.c Thu Mar 17 18:55:54 2016        (r296990)
+++ head/sys/netinet6/nd6_nbr.c Thu Mar 17 19:01:44 2016        (r296991)
@@ -857,30 +857,19 @@ nd6_na_input(struct mbuf *m, int off, in
                         * 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;
        }

Modified: head/sys/netinet6/nd6_rtr.c
==============================================================================
--- head/sys/netinet6/nd6_rtr.c Thu Mar 17 18:55:54 2016        (r296990)
+++ head/sys/netinet6/nd6_rtr.c Thu Mar 17 19:01:44 2016        (r296991)
@@ -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 *n
        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 *n
                 */
                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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to