p4-projects@freebsd.org
[Top] [All Lists]

PERFORCE change 153420 for review

Subject: PERFORCE change 153420 for review
From: Qing Li
Date: Mon, 24 Nov 2008 03:02:00 GMT
http://perforce.freebsd.org/chv.cgi?CH=153420

Change 153420 by qingli@FreeBSD-newarp on 2008/11/24 03:01:52

        
        1. removed the unnecessary lle_mtx as noted by Sam
        2. removed the if_lltbls_mtx from the ifnet{}
        3. incorporate previous review comments from Gleb Smirnoff
        4. the L2 tables (for AF_INET and AF_INET6) now
           live under the per ifnet{} if_afdata[] member field
        5. access to the L2 tables is synchronized through
           the IF_AFDATA_LOCK
        6. changed the if_afdata_mtx to a MTX_RECURSE lock
           due to the recursive locking challenges in IPv6
        
        Unit Testing:
                1. ping (x.x.x.255)
                2. ping6
                3. arp (various combo of -an, -s, -d, -ad)
                4. ndp (various combo of -s, -d)
                5. netperf (TCP_STREAM) test
        
        Immediate issue to be resolved:
                Now a global "lltables" is used to track all of
                L2 tables (both AF_INET and AF_INET6) for dumping
                these tables (e.g. for "arp" and "ndp" output).
                Not sure how to synchronize this list.

Affected files ...

.. //depot/projects/arp-v2/src/sys/net/if.c#7 edit
.. //depot/projects/arp-v2/src/sys/net/if_llatbl.c#5 edit
.. //depot/projects/arp-v2/src/sys/net/if_llatbl.h#4 edit
.. //depot/projects/arp-v2/src/sys/net/if_var.h#8 edit
.. //depot/projects/arp-v2/src/sys/netinet/if_ether.c#15 edit
.. //depot/projects/arp-v2/src/sys/netinet/in.c#6 edit
.. //depot/projects/arp-v2/src/sys/netinet/in_proto.c#3 edit
.. //depot/projects/arp-v2/src/sys/netinet/in_var.h#4 edit
.. //depot/projects/arp-v2/src/sys/netinet6/icmp6.c#7 edit
.. //depot/projects/arp-v2/src/sys/netinet6/in6.c#8 edit
.. //depot/projects/arp-v2/src/sys/netinet6/in6_var.h#2 edit
.. //depot/projects/arp-v2/src/sys/netinet6/ip6_forward.c#5 edit
.. //depot/projects/arp-v2/src/sys/netinet6/ip6_input.c#6 edit
.. //depot/projects/arp-v2/src/sys/netinet6/ip6_mroute.c#5 edit
.. //depot/projects/arp-v2/src/sys/netinet6/ip6_output.c#7 edit
.. //depot/projects/arp-v2/src/sys/netinet6/nd6.c#8 edit
.. //depot/projects/arp-v2/src/sys/netinet6/nd6_nbr.c#7 edit
.. //depot/projects/arp-v2/src/sys/netinet6/nd6_rtr.c#6 edit

Differences ...

==== //depot/projects/arp-v2/src/sys/net/if.c#7 (text+ko) ====

@@ -137,7 +137,7 @@
 #endif
 
 extern uma_zone_t llezone;
-extern uma_zone_t lltzone;
+extern struct mtx lltables_mtx;
 
 int    if_index = 0;
 int    ifqmaxlen = IFQ_MAXLEN;
@@ -375,8 +375,6 @@
         */
        llezone = uma_zcreate("llentry", sizeof(struct llentry), NULL, NULL,
                                         NULL, NULL, UMA_ALIGN_PTR, 0);
-       lltzone = uma_zcreate("lltable", sizeof(struct lltable), NULL, NULL,
-                                        NULL, NULL, UMA_ALIGN_PTR, 0);
 }
 
 static void
@@ -518,13 +516,11 @@
        TASK_INIT(&ifp->if_starttask, 0, if_start_deferred, ifp);
        TASK_INIT(&ifp->if_linktask, 0, do_link_state_change, ifp);
        IF_AFDATA_LOCK_INIT(ifp);
-       IF_LLTBLS_LOCK_INIT(ifp);
        ifp->if_afdata_initialized = 0;
 
        TAILQ_INIT(&ifp->if_addrhead);
        TAILQ_INIT(&ifp->if_prefixhead);
        TAILQ_INIT(&ifp->if_multiaddrs);
-       TAILQ_INIT(&ifp->if_lltables);
        TAILQ_INIT(&ifp->if_groups);
 
        if_addgroup(ifp, IFG_ALL);

==== //depot/projects/arp-v2/src/sys/net/if_llatbl.c#5 (text+ko) ====

@@ -22,6 +22,9 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include "opt_inet.h"
 #include "opt_inet6.h"
 
@@ -48,23 +51,27 @@
 #include <netinet6/in6_var.h>
 #include <netinet6/nd6.h>
 
+MALLOC_DEFINE(M_LLTABLE, "lltable", "link level address tables");
 uma_zone_t llezone;
-uma_zone_t lltzone;
+
+SLIST_HEAD(, lltable) lltables = SLIST_HEAD_INITIALIZER(lltables);
 
-static struct lltable *lltable_new(struct ifnet *ifp, int af);
 int sysctl_dumparp(int af, struct sysctl_req *wr);
 extern void arprequest(struct ifnet *, struct in_addr *, struct in_addr *,
        u_char *);
 
+
 static int
-dump_llcache(struct ifnet *ifp, int af, struct llentries *head,
-       struct sysctl_req *wr)
+dump_llcache(struct lltable *llt, int af, struct sysctl_req *wr)
 {
+       struct ifnet *ifp = llt->llt_ifp;
        struct llentry *lle;
-       struct rt_msghdr *rtm;
-       struct sockaddr_dl *sdl;
-       uint8_t *msg;
-       int msgsize, error;
+       struct rt_msghdr *rtm = NULL;
+       struct sockaddr_dl *sdl = NULL;
+       uint8_t *msg = NULL;
+       int msgsize = 0;
+       int error = 0;
+       int i;
 #ifdef INET
        struct {
                struct rt_msghdr        rtm;
@@ -102,63 +109,71 @@
                return EINVAL;
        }
 
-       IF_LLTBLS_LOCK_ASSERT(ifp);
+       /* XXXXX
+        * current IFNET_RLOCK() is mapped to IFNET_WLOCK()
+        * so it is okay to use this ASSERT, change it when
+        * IFNET lock is finalized
+        */
+       IFNET_WLOCK_ASSERT();
+
+       for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
+               LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
+                       if (lle->la_flags & LLE_DELETED) /* skip deleted 
entries */
+                               continue;
+                       /*
+                        * produce a msg made of:
+                        *  struct rt_msghdr;
+                        *  struct sockaddr_inarp; (IPv4) struct sockaddr_in6 
(IPv6)
+                        *  struct sockaddr_dl;
+                        */
+                       bzero(msg, msgsize);
+                       rtm->rtm_msglen = msgsize;
 
-       error = 0;
-       LIST_FOREACH(lle, head, lle_next) {
-               if (lle->la_flags & LLE_DELETED) /* skip deleted entries */
-                       continue;
-               /*
-                * produce a msg made of:
-                *  struct rt_msghdr;
-                *  struct sockaddr_inarp; (IPv4) struct sockaddr_in6 (IPv6)
-                *  struct sockaddr_dl;
-                */
-               bzero(msg, msgsize);
-               rtm->rtm_msglen = msgsize;
-               switch (af) {
+                       switch (af) {
 #ifdef INET
-               case AF_INET:
-                       arpc.sin.sin_family = AF_INET;
-                       arpc.sin.sin_len = sizeof(arpc.sin);
-                       arpc.sin.sin_addr.s_addr = 
lle->l3_addr4.sin_addr.s_addr;
-                       break;
+                       case AF_INET:
+                               arpc.sin.sin_family = AF_INET;
+                               arpc.sin.sin_len = sizeof(arpc.sin);
+                               arpc.sin.sin_addr.s_addr = 
lle->l3_addr4.sin_addr.s_addr;
+                               break;
 #endif
 #ifdef INET6
-               case AF_INET6:
-                       ndpc.sin6.sin6_family = AF_INET6;
-                       ndpc.sin6.sin6_len = sizeof(ndpc.sin6);
-                       bcopy(&lle->l3_addr6, &ndpc.sin6, 
lle->l3_addr6.sin6_len);
-                       break;
+                       case AF_INET6:
+                               ndpc.sin6.sin6_family = AF_INET6;
+                               ndpc.sin6.sin6_len = sizeof(ndpc.sin6);
+                               bcopy(&lle->l3_addr6, &ndpc.sin6, 
lle->l3_addr6.sin6_len);
+                               break;
 #endif
-               }
-               /* publish */
-               if (lle->la_flags & LLE_PUB) {
-                       rtm->rtm_flags |= RTF_ANNOUNCE;
-                       /* proxy only */
-                       if ((af == AF_INET) && (lle->la_flags & LLE_PROXY))
-                               arpc.sin.sin_other = SIN_PROXY;
-               }
+                       }
+                       /* publish */
+                       if (lle->la_flags & LLE_PUB) {
+                               rtm->rtm_flags |= RTF_ANNOUNCE;
+                               /* proxy only */
+                               if ((af == AF_INET) && (lle->la_flags & 
LLE_PROXY))
+                                       arpc.sin.sin_other = SIN_PROXY;
+                       }
 
-               if (lle->la_flags & LLE_VALID) { /* valid MAC */
-                       sdl->sdl_family = AF_LINK;
-                       sdl->sdl_len = sizeof(*sdl);
-                       sdl->sdl_alen = ifp->if_addrlen;
-                       sdl->sdl_index = ifp->if_index;
-                       sdl->sdl_type = ifp->if_type;
-                       bcopy(&lle->ll_addr, LLADDR(sdl), ifp->if_addrlen);
+                       if (lle->la_flags & LLE_VALID) { /* valid MAC */
+                               sdl->sdl_family = AF_LINK;
+                               sdl->sdl_len = sizeof(*sdl);
+                               sdl->sdl_alen = ifp->if_addrlen;
+                               sdl->sdl_index = ifp->if_index;
+                               sdl->sdl_type = ifp->if_type;
+                               bcopy(&lle->ll_addr, LLADDR(sdl), 
ifp->if_addrlen);
+                       }
+                       rtm->rtm_rmx.rmx_expire =
+                           lle->la_flags & LLE_STATIC ? 0 : lle->la_expire;
+                       rtm->rtm_flags |= (RTF_LLINFO | RTF_HOST);
+                       if (lle->la_flags & LLE_STATIC)
+                               rtm->rtm_flags |= RTF_STATIC;
+                       rtm->rtm_index = ifp->if_index;
+                       error = SYSCTL_OUT(wr, msg, msgsize);
+                       if (error)
+                               break;
                }
-               rtm->rtm_rmx.rmx_expire =
-                       lle->la_flags & LLE_STATIC ? 0 : lle->la_expire;
-               rtm->rtm_flags |= (RTF_LLINFO | RTF_HOST);
-               if (lle->la_flags & LLE_STATIC)
-                       rtm->rtm_flags |= RTF_STATIC;
-               rtm->rtm_index = ifp->if_index;
-               error = SYSCTL_OUT(wr, msg, msgsize);
-               if (error)
-                       break;
        }
-       return error;
+
+       return (error);
 }
 
 /*
@@ -168,43 +183,34 @@
 sysctl_dumparp(int af, struct sysctl_req *wr)
 {
        struct lltable *llt;
-       struct ifnet *ifp;
-       int i, error = 0;
+       int error = 0;
 
        IFNET_RLOCK();
-       TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
-               IF_LLTBLS_LOCK(ifp);
-               TAILQ_FOREACH(llt, &ifp->if_lltables, llt_link) {
-                       if (llt->llt_af != af)
-                               continue;
-                       for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
-                               error = dump_llcache(ifp, af,
-                                   &llt->lle_head[i], wr);
-                               if (error) {
-                                       IF_LLTBLS_UNLOCK(ifp);
-                                       goto done;
-                               }
-                       }
+       SLIST_FOREACH(llt, &lltables, llt_link) {
+               if (llt->llt_af == af) {
+                       error = dump_llcache(llt, af, wr);
+                       if (error != 0)
+                               goto done;
                }
-               IF_LLTBLS_UNLOCK(ifp);
        }
 done:
        IFNET_RUNLOCK();
-       return error;
+       return (error);
 }
 
 /*
- * delete an address from the address table
+ * Deletes an address from the address table.
+ * This function is called by the timer functions
+ * such as arptimer() and nd6_llinfo_timer(), and
+ * the caller does the locking.
  */
 int
 llentry_free(struct llentry *lle)
 {
+       KASSERT(lle != NULL, ("%s: lle is NULL", __func__));
 
-       KASSERT(lle != NULL, ("null lle"));
-       IF_LLTBLS_LOCK_ASSERT(lle->lle_tbl->llt_ifp);
+       LIST_REMOVE(lle, lle_next);
 
-       LIST_REMOVE(lle, lle_next);
-       IF_LLE_LOCK_DESTROY(lle);
        if (lle->la_hold != NULL)
                m_freem(lle->la_hold);
        uma_zfree(llezone, lle);
@@ -212,130 +218,111 @@
 }
 
 /*
- * delete an address table from the interface ifp
+ * Free all entries from given table and free itself.
+ * Since lltables collects from all of the intefaces,
+ * the caller of this function must acquire IFNET_WLOCK().
  */
-int
-lltable_free(struct ifnet *ifp, int af)
+void lltable_free(struct lltable *llt)
 {
-       struct lltable *llt;
        struct llentry *lle;
        int i;
 
-       KASSERT(ifp != NULL, ("null ifp"));
+       KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
 
-       IF_LLTBLS_LOCK_ASSERT(ifp);
+       IFNET_WLOCK();
+       SLIST_REMOVE(&lltables, llt, lltable, llt_link);
+       IFNET_WUNLOCK();
 
-       TAILQ_FOREACH(llt, &ifp->if_lltables, llt_link) {
-               if (llt->llt_af != af)
-                       continue;
-               for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
-                       LIST_FOREACH(lle, &llt->lle_head[i], lle_next)
-                               llentry_free(lle);
+       for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
+               LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
+                       callout_drain(&lle->la_timer);
+                       llentry_free(lle);
                }
-               TAILQ_REMOVE(&ifp->if_lltables, llt, llt_link);
-               uma_zfree(lltzone, llt);
-               break;
        }
-       return 0;
+
+       free(llt, M_LLTABLE);
 }
 
 void
 lltable_drain(int af)
 {
-       struct ifnet   *ifp;
-       struct lltable *llt = NULL;
-       struct llentry *lle;
-       int i;
+       struct lltable  *llt;
+       struct llentry  *lle;
+       register int i;
+
+       IFNET_RLOCK();
+       SLIST_FOREACH(llt, &lltables, llt_link) {
+               if (llt->llt_af != af)
+                       continue;
 
-       TAILQ_FOREACH(ifp, &ifnet, if_link) {
-               IF_LLTBLS_LOCK(ifp);
-               TAILQ_FOREACH(llt, &ifp->if_lltables, llt_link) {
-                       if (llt->llt_af != af)
-                               continue;
-                       for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
-                               LIST_FOREACH(lle, &llt->lle_head[i],
-                                   lle_next) {
-                                       if (lle->la_hold != NULL) {
-                                               m_freem(lle->la_hold);
-                                               lle->la_hold = NULL;
-                                       }
+               for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
+                       LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
+                               if (lle->la_hold) {
+                                       m_freem(lle->la_hold);
+                                       lle->la_hold = NULL;
                                }
                        }
-                       break;
                }
-               IF_LLTBLS_LOCK(ifp);
        }
+       IFNET_RUNLOCK();
 }
 
+
 /*
- * Add a new table at the head of the list for interface ifp
+ * Create a new lltable.
  */
-static struct lltable *
-lltable_new(struct ifnet *ifp, int af)
+struct lltable *
+lltable_init(struct ifnet *ifp, int af)
 {
        struct lltable *llt;
-       int i;
+       register int i;
+
+       llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK);
+       if (llt == NULL)
+               return (NULL);
 
-       /* XXX can this happen? */
-       if (ifp == NULL)
-               return NULL;
-       llt = uma_zalloc(lltzone, M_DONTWAIT | M_ZERO);
-       if (llt == NULL) {
-               log(LOG_INFO, "lltable_new: malloc failed for new lla-table\n");
-               return NULL;
-       }
-       llt->llt_af  = af;
+       llt->llt_af = af;
        llt->llt_ifp = ifp;
        for (i = 0; i < LLTBL_HASHTBL_SIZE; i++)
                LIST_INIT(&llt->lle_head[i]);
 
-       IF_LLTBLS_LOCK_ASSERT(ifp);
-       TAILQ_INSERT_HEAD(&ifp->if_lltables, llt, llt_link);
+       IFNET_WLOCK();
+       SLIST_INSERT_HEAD(&lltables, llt, llt_link);
+       IFNET_WUNLOCK();
 
-       return llt;
+       return (llt);
 }
 
+
 /*
  * Generic link layer address lookup function, replacement
  * of the old "arplookup"
  */
 struct llentry *
-lla_lookup(struct ifnet *ifp, u_int flags, struct sockaddr *l3addr)
+lla_lookup(struct lltable *llt, u_int flags, struct sockaddr *l3addr)
 {
-       struct llentry *lle;
+       struct ifnet *ifp;
+       struct llentry   *lle;
        struct llentries *lleh;
-       struct lltable *llt;
-       struct rtentry *rt;
+       struct rtentry   *rt;
        u_int hashkey;
 #ifdef INET6
        char ip6buf[INET6_ADDRSTRLEN];
 #endif
 
-       KASSERT(ifp != NULL, ("null ifp"));
-       KASSERT(l3addr != NULL, ("null L3 address"));
+       KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
+       KASSERT(l3addr != NULL, ("%s: L3 address is NULL", __func__));
 
-       IF_LLTBLS_LOCK_ASSERT(ifp);
-
-       TAILQ_FOREACH(llt, &ifp->if_lltables, llt_link)
-               if (llt->llt_af == l3addr->sa_family)
-                       break;
-       if ((flags & LLE_CREATE) && llt == NULL) {
-               llt = lltable_new(ifp, l3addr->sa_family);
-               if (llt == NULL)
-                       return NULL;
-       }
-
+       ifp = llt->llt_ifp;
        switch (l3addr->sa_family) {
-#ifdef INET
        case AF_INET:
                hashkey = ((struct sockaddr_in *)l3addr)->sin_addr.s_addr;
                break;
-#endif
-#ifdef INET6
+
        case AF_INET6:
                hashkey = ((struct sockaddr_in6 
*)l3addr)->sin6_addr.s6_addr32[3];
                break;
-#endif
+
        default:
                return NULL;
        }
@@ -346,43 +333,40 @@
                        continue;
                if (bcmp((void *)&lle->l3_addr, l3addr, l3addr->sa_len) == 0)
                        break;
-       }
+       }     
 
        if (lle == NULL) {
                if (!(flags & LLE_CREATE))
-                       return NULL;
+                       return (NULL);
 
                /*
-                * A route that covers the given address must have been 
-                * installed 1st because we are doing a resolution.
+                * a route that covers the given address must have been 
+                * installed 1st because we are doing a resolution
                 */
                if (!(flags & LLE_IFADDR)) {
                        rt = rtalloc1(l3addr, 0, 0);
-                       if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) ||
-                           rt->rt_ifp != ifp) {
+                       if ((rt == NULL) || (rt->rt_flags & RTF_GATEWAY) || 
(rt->rt_ifp != ifp)) {
                                if (l3addr->sa_family == AF_INET6) {
                                        /* 
-                                        * Creating an ND6 cache for an IPv6
-                                        * neighbor that is not covered by our
-                                        * own prefix.
+                                        * Creating a ND6 cache for an IPv6 
neighbor 
+                                        * that is not covered by our own 
prefix.
                                         */
-                                       struct ifaddr *ifa = ifaof_ifpforaddr(
-                                           (struct sockaddr *)l3addr, ifp);
-                                       if (ifa != NULL)
+                                       struct ifaddr *ifa =
+                                               ifaof_ifpforaddr((struct 
sockaddr *)l3addr, ifp);
+                                       if (ifa != NULL) {
+                                               if (rt)
+                                                       rtfree(rt);
                                                goto lla_lookup_1;
+                                       }
                                }
                                switch (l3addr->sa_family) {
-#ifdef INET
                                case AF_INET:
-                                       log(LOG_INFO, "IPv4 address: \"%s\" is "
-                                           "not on the network\n",
+                                       log(LOG_INFO, "IPv4 address: \"%s\" is 
not on the network\n", \
                                            inet_ntoa(((struct sockaddr_in 
*)l3addr)->sin_addr));
                                        break;
-#endif
 #ifdef INET6
                                case AF_INET6:
-                                       log(LOG_INFO, "IPv6 address: \"%s\" is "
-                                           "not on the network\n",
+                                       log(LOG_INFO, "IPv6 address: \"%s\" is 
not on the network\n", \
                                            ip6_sprintf(ip6buf, &((struct 
sockaddr_in6 *)l3addr)->sin6_addr));
                                        break;
 #endif
@@ -397,14 +381,13 @@
 lla_lookup_1:
                lle = uma_zalloc(llezone, M_DONTWAIT | M_ZERO);
                if (lle == NULL) {
-                       log(LOG_INFO, "%s: malloc failed\n", __func__);
+                       log(LOG_INFO, "lla_lookup: new lle malloc failed\n");
                        return (NULL);
                }
 
-               IF_LLE_LOCK_INIT(lle);
-               callout_init_mtx(&lle->la_timer, &ifp->if_lltbls_mtx, 0);
+               callout_init(&lle->la_timer, CALLOUT_MPSAFE);
 
-               /*
+               /* qing
                 * For IPv4 this will trigger "arpresolve" to generate
                 * an ARP request 
                 */
@@ -415,9 +398,9 @@
                
                if ((flags & (LLE_CREATE | LLE_IFADDR)) == (LLE_CREATE | 
LLE_IFADDR)) {
                        bcopy(IF_LLADDR(ifp), &lle->ll_addr, ifp->if_addrlen);
-                       lle->la_flags |= LLE_VALID | LLE_STATIC;
+                       lle->la_flags |= (LLE_VALID | LLE_STATIC);
                }
-
+               
                lle->lle_tbl  = llt;
                lle->lle_head = lleh;
                LIST_INSERT_HEAD(lleh, lle, lle_next);
@@ -425,9 +408,11 @@
                if (flags & LLE_DELETE)
                        lle->la_flags = LLE_DELETED;
        }
+       
        return (lle);
 }
 
+
 /*
  * Called in route_output when adding/deleting a route to an interface.
  */
@@ -437,6 +422,7 @@
        struct sockaddr_dl *dl = (struct sockaddr_dl 
*)info->rti_info[RTAX_GATEWAY];
        struct sockaddr *dst = (struct sockaddr *)info->rti_info[RTAX_DST];
        struct ifnet *ifp;
+       struct lltable *llt;
        struct llentry *lle;
        u_int flags = 0;
 
@@ -486,8 +472,22 @@
                return EINVAL; /* XXX not implemented yet */
        }
 
-       IF_LLTBLS_LOCK(ifp);
-       lle = lla_lookup(ifp, flags, dst);
+       /*
+        * XXXXXXXX: A big and ugly hack!
+        * I must redesign this before even committing to perforce. This is
+        * just a hack to make new design working.
+        */
+       IFNET_WLOCK();
+       SLIST_FOREACH(llt, &lltables, llt_link) {
+               if (llt->llt_af == dst->sa_family &&
+                   llt->llt_ifp == ifp)
+                       break;
+       }
+       IFNET_WUNLOCK();
+       KASSERT(llt != NULL, ("Yep, ugly hacks are bad\n"));
+
+       IF_AFDATA_LOCK(ifp);
+       lle = lla_lookup(llt, flags, dst);
        if (lle != NULL) {
                if (flags & LLE_CREATE) {
                        /* qing: if we delay the delete, then if a subsequent 
@@ -527,10 +527,11 @@
                }
        } else {
                if (flags & LLE_DELETE) {
-                       IF_LLTBLS_UNLOCK(ifp);
+                       IF_AFDATA_UNLOCK(ifp);
                        return EINVAL;
                }
        }
-       IF_LLTBLS_UNLOCK(ifp);
+
+       IF_AFDATA_UNLOCK(ifp);
        return 0;
 }

==== //depot/projects/arp-v2/src/sys/net/if_llatbl.h#4 (text+ko) ====

@@ -22,6 +22,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
 #ifndef        _NET_IF_LLATBL_H_
 #define        _NET_IF_LLATBL_H_
@@ -37,9 +39,9 @@
 
 struct llentry {
        LIST_ENTRY(llentry)      lle_next;
-       struct lltable          *lle_tbl;
-       struct llentries        *lle_head;
-       struct mbuf             *la_hold;
+       struct lltable           *lle_tbl;
+       struct llentries         *lle_head;
+       struct mbuf              *la_hold;
        time_t                   la_expire;
        uint16_t                 la_flags;    
        uint16_t                 la_asked;
@@ -60,7 +62,6 @@
                struct callout  ln_timer_ch;
                struct callout  la_timer;
        } lle_timer;
-       struct mtx               lle_mtx;       /* mutex for lle entry */
 };
 
 #define        ln_timer_ch     lle_timer.ln_timer_ch
@@ -78,12 +79,13 @@
 #endif
 
 struct lltable {
-       TAILQ_ENTRY(lltable)     llt_link;
+       SLIST_ENTRY(lltable)     llt_link;
        struct llentries         lle_head[LLTBL_HASHTBL_SIZE];
        int                      llt_af;
-       struct ifnet            *llt_ifp;
+       struct ifnet             *llt_ifp;
 };
 
+
 /*
  * flags to be passed to arplookup.
  */
@@ -99,16 +101,14 @@
 #define LLATBL_HASH(key, mask) \
        (((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask)
 
-#define        IF_LLE_LOCK_INIT(lle) \
-       mtx_init(&(lle)->lle_mtx, "if_llentry_mtx", NULL, MTX_DEF | MTX_RECURSE)
-#define        IF_LLE_LOCK_DESTROY(lle)        mtx_destroy(&(lle)->lle_mtx)
-#define        IF_LLE_LOCK(lle)        mtx_lock(&(lle)->lle_mtx)
-#define        IF_LLE_UNLOCK(lle)      mtx_unlock(&(lle)->lle_mtx)
+struct llentry *lla_lookup(struct lltable *, u_int, struct sockaddr *);
+int            lla_rt_output(struct rt_msghdr *, struct rt_addrinfo *);
+int            llentry_free(struct llentry *);
+
+struct lltable *lltable_init(struct ifnet *, int);
+void           lltable_free(struct lltable *);
+void           lltable_drain(int);
+
+#endif  /* _NET_IF_LLATBL_H_ */
+
 
-struct llentry *lla_lookup(struct ifnet *, u_int flags,
-                   struct sockaddr *l3addr);
-int            lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info);
-int            llentry_free(struct llentry *lle);
-int            lltable_free(struct ifnet *ifp, int af);
-void           lltable_drain(int af);
-#endif /* _NET_IF_LLATBL_H_ */

==== //depot/projects/arp-v2/src/sys/net/if_var.h#8 (text+ko) ====

@@ -93,7 +93,6 @@
 TAILQ_HEAD(ifprefixhead, ifprefix);
 TAILQ_HEAD(ifmultihead, ifmultiaddr);
 TAILQ_HEAD(ifgrouphead, ifg_group);
-TAILQ_HEAD(lltables, lltable);  /* L2/L3 address resolution table */
 
 /*
  * Structure defining a queue for a network interface.
@@ -171,8 +170,6 @@
 
        void    *if_bridge;             /* bridge glue */
 
-       struct  lltables if_lltables;   /* list of L3-L2 resolution tables */
-
        struct  label *if_label;        /* interface MAC label */
 
        /* these are only used by IPv6 */
@@ -183,8 +180,7 @@
        struct  task if_starttask;      /* task for IFF_NEEDSGIANT */
        struct  task if_linktask;       /* task for link change events */
        struct  mtx if_addr_mtx;        /* mutex to protect address lists */
-       struct  mtx if_lltbls_mtx;      /* mutex to protect link-layer 
-                                          address tables */
+
        LIST_ENTRY(ifnet) if_clones;    /* interfaces of a cloner */
        TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */
                                        /* protected by if_addr_mtx */
@@ -239,17 +235,6 @@
 #define        IF_ADDR_LOCK_ASSERT(if) mtx_assert(&(if)->if_addr_mtx, MA_OWNED)
 
 /*
- * Locks for link-layer address tables on the network interface.
- */
-#define        IF_LLTBLS_LOCK_INIT(if) mtx_init(&(if)->if_lltbls_mtx,          
\
-                                   "if_lltbls_mtx", NULL, MTX_DEF | 
MTX_RECURSE)
-#define        IF_LLTBLS_LOCK_DESTROY(if)      
mtx_destroy(&(if)->if_lltbls_mtx)
-#define        IF_LLTBLS_LOCK(if)      mtx_lock(&(if)->if_lltbls_mtx)
-#define        IF_LLTBLS_UNLOCK(if)    mtx_unlock(&(if)->if_lltbls_mtx)
-#define        IF_LLTBLS_LOCK_ASSERT(if)       
mtx_assert(&(if)->if_lltbls_mtx, MA_OWNED)
-
-
-/*
  * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
  * are queues of messages stored on ifqueue structures
  * (defined above).  Entries are added to and deleted from these structures
@@ -370,7 +355,8 @@
 EVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
 
 #define        IF_AFDATA_LOCK_INIT(ifp)        \
-    mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, MTX_DEF)
+    mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, \
+                                   (MTX_DEF | MTX_RECURSE))
 #define        IF_AFDATA_LOCK(ifp)     mtx_lock(&(ifp)->if_afdata_mtx)
 #define        IF_AFDATA_TRYLOCK(ifp)  mtx_trylock(&(ifp)->if_afdata_mtx)
 #define        IF_AFDATA_UNLOCK(ifp)   mtx_unlock(&(ifp)->if_afdata_mtx)

==== //depot/projects/arp-v2/src/sys/netinet/if_ether.c#15 (text+ko) ====

@@ -78,6 +78,7 @@
 
 #define SIN(s) ((struct sockaddr_in *)s)
 #define SDL(s) ((struct sockaddr_dl *)s)
+#define LLTABLE(ifp)   ((struct lltable *)(ifp)->if_afdata[AF_INET])
 
 SYSCTL_DECL(_net_link_ether);
 SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, "");
@@ -130,9 +131,10 @@
        addr4.sin_len    = sizeof(addr4);
        addr4.sin_family = AF_INET;
        addr4.sin_addr.s_addr = addr;
-       IF_LLTBLS_LOCK(ifp);
-       lle = lla_lookup(ifp, (LLE_DELETE | LLE_IFADDR), (struct sockaddr 
*)&addr4);
-       IF_LLTBLS_UNLOCK(ifp);
+       IF_AFDATA_LOCK(ifp);
+       lle = lla_lookup(LLTABLE(ifp), (LLE_DELETE | LLE_IFADDR),
+           (struct sockaddr *)&addr4);
+       IF_AFDATA_UNLOCK(ifp);
 #if 0
        if (lle == NULL)
                log(LOG_INFO, "arp_ifscrub: interface address is missing from 
cache\n");
@@ -150,19 +152,19 @@
        struct llentry   *lle = (struct llentry *)arg;
 
        if (lle == NULL) {
-               panic("arptimer: NULL entry!\n");
+               panic("%s: NULL entry!\n", __func__);
                return;
        }
        ifp = lle->lle_tbl->llt_ifp;
-       IF_LLTBLS_LOCK(ifp);
-       if ((lle->la_flags & LLE_DELETED) &&
-           !(lle->la_flags & LLE_STATIC)) {
+       IF_AFDATA_LOCK(ifp);
+       if ((lle->la_flags & LLE_DELETED) ||
+           (time_second >= lle->la_expire)) {
                if (!callout_pending(&lle->la_timer)  &&
                    (callout_active(&lle->la_timer))) {
                        (void)llentry_free(lle);
                }
        }
-       IF_LLTBLS_UNLOCK(ifp);
+       IF_AFDATA_UNLOCK(ifp);
 }
 
 
@@ -271,11 +273,11 @@
 
        flags = (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) ? 0 : LLE_CREATE;
 
-       /* Qing
-        *   because this function returns an llentry, 
-        *   the IF LLTBLS lock is held by the caller
+       /* XXXXX
+        * Since this function returns an llentry, the 
+        * lock is held by the caller.
         */
-       la = lla_lookup(ifp, flags, dst);
+       la = lla_lookup(LLTABLE(ifp), flags, dst);
        if (la == NULL) {
                if (flags & LLE_CREATE)
                        log(LOG_DEBUG,
@@ -559,8 +561,8 @@
        sin.sin_family = AF_INET;
        sin.sin_addr = isaddr;
        flag = (itaddr.s_addr == myaddr.s_addr) ? LLE_CREATE : 0;
-/*     IF_LLTBLS_LOCK(ifp); */
-       la = lla_lookup(ifp, flag, (struct sockaddr *)&sin);
+/* Qing        IF_AFDATA_LOCK(ifp); */
+       la = lla_lookup(LLTABLE(ifp), flag, (struct sockaddr *)&sin);
        if (la != NULL) {
                /* the following is not an error when doing bridging */
                if (!bridged && la->lle_tbl->llt_ifp != ifp
@@ -693,7 +695,7 @@
                        }
                        (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
                        (void)memcpy(ar_sha(ah), &la->ll_addr, ah->ar_hln);
-/*                     IF_LLTBLS_UNLOCK(ifp);*/
+/* QING                        IF_AFDATA_UNLOCK(ifp); */
                }
        }
 
@@ -722,10 +724,8 @@
        return;
 
 drop:
-/*
-       if (la != NULL)
-               IF_LLTBLS_UNLOCK(ifp);
-*/
+/*     if (la != NULL)
+       IF_AFDATA_UNLOCK(ifp); */
        m_freem(m);
 }
 #endif
@@ -738,13 +738,15 @@
        if (ntohl(IA_SIN(ifa)->sin_addr.s_addr) != INADDR_ANY)
                arprequest(ifp, &IA_SIN(ifa)->sin_addr,
                                &IA_SIN(ifa)->sin_addr, IF_LLADDR(ifp));
-       /* Qing
-        * interface address is considered static entry  (true ??)
+       /* 
+        * interface address is considered static entry
+        * because the output of the arp utility shows
+        * that L2 entry as permanent
         */
-       IF_LLTBLS_LOCK(ifp);
-       lle = lla_lookup(ifp, (LLE_CREATE | LLE_IFADDR | LLE_STATIC),
+       IF_AFDATA_LOCK(ifp);
+       lle = lla_lookup(LLTABLE(ifp), (LLE_CREATE | LLE_IFADDR | LLE_STATIC),
            (struct sockaddr *)IA_SIN(ifa));
-       IF_LLTBLS_UNLOCK(ifp);
+       IF_AFDATA_UNLOCK(ifp);
        if (lle == NULL)
                log(LOG_INFO, "arp_ifinit: cannot create arp "
                    "entry for interface address\n");

==== //depot/projects/arp-v2/src/sys/netinet/in.c#6 (text+ko) ====

@@ -46,6 +46,7 @@
 #include <sys/vimage.h>
 
 #include <net/if.h>
+#include <net/if_llatbl.h>
 #include <net/if_types.h>
 #include <net/route.h>
 
@@ -1017,3 +1018,19 @@
        in_pcbpurgeif0(&V_udbinfo, ifp);
        in_purgemaddrs(ifp);
 }
+
+void *
+in_domifattach(struct ifnet *ifp)
+{   
+       struct lltable *llt = lltable_init(ifp, AF_INET);
+ 
+       return (llt);
+}
+
+void
+in_domifdetach(struct ifnet *ifp __unused, void *aux)
+{
+       struct lltable *llt = (struct lltable *)aux;
+
+       lltable_free(llt);
+}

==== //depot/projects/arp-v2/src/sys/netinet/in_proto.c#3 (text+ko) ====

@@ -362,7 +362,9 @@
        .dom_rtattach =         in_inithead,
 #endif
        .dom_rtoffset =         32,
-       .dom_maxrtkey =         sizeof(struct sockaddr_in)
+       .dom_maxrtkey =         sizeof(struct sockaddr_in),
+       .dom_ifattach =         in_domifattach,
+       .dom_ifdetach =         in_domifdetach
 };
 
 DOMAIN_SET(inet);

==== //depot/projects/arp-v2/src/sys/netinet/in_var.h#4 (text+ko) ====

@@ -305,6 +305,9 @@
 int    in_ifadown(struct ifaddr *ifa, int);
 void   in_ifscrub(struct ifnet *, struct in_ifaddr *);
 struct mbuf    *ip_fastforward(struct mbuf *);
+void   *in_domifattach(struct ifnet *);
+void   in_domifdetach(struct ifnet *, void *);
+
 
 /* XXX */
 void    in_rtalloc_ign(struct route *ro, u_long ignflags, u_int fibnum);

==== //depot/projects/arp-v2/src/sys/netinet6/icmp6.c#7 (text+ko) ====

@@ -2389,10 +2389,10 @@
        }
 
        /* RFC 2461 8.3 */
-       IF_LLTBLS_LOCK(ifp);
+       IF_AFDATA_LOCK(ifp);
        nd6_cache_lladdr(ifp, &redtgt6, lladdr, lladdrlen, ND_REDIRECT,
            is_onlink ? ND_REDIRECT_ONLINK : ND_REDIRECT_ROUTER);
-       IF_LLTBLS_UNLOCK(ifp);
+       IF_AFDATA_UNLOCK(ifp);
 
        if (!is_onlink) {       /* better router case.  perform rtredirect. */
                /* perform rtredirect */
@@ -2573,17 +2573,17 @@
                struct nd_opt_hdr *nd_opt;
                char *lladdr;
 
-               IF_LLTBLS_LOCK(ifp);
+               IF_AFDATA_LOCK(ifp);
                ln = nd6_lookup(router_ll6, 0, ifp);
                if (!ln) {
-                       IF_LLTBLS_UNLOCK(ifp);
+                       IF_AFDATA_UNLOCK(ifp);
                        goto nolladdropt;
                }
                len = sizeof(*nd_opt) + ifp->if_addrlen;
                len = (len + 7) & ~7;   /* round by 8 */
                /* safety check */
                if (len + (p - (u_char *)ip6) > maxlen) {
-                       IF_LLTBLS_UNLOCK(ifp);
+                       IF_AFDATA_UNLOCK(ifp);
                        goto nolladdropt;
                }
                if (ln->la_flags & LLE_VALID) {
@@ -2594,7 +2594,7 @@
                        bcopy(&ln->ll_addr, lladdr, ifp->if_addrlen);
                        p += len;
                }
-               IF_LLTBLS_UNLOCK(ifp);
+               IF_AFDATA_UNLOCK(ifp);
        }
 nolladdropt:;
 


>>> TRUNCATED FOR MAIL (1000 lines) <<<
_______________________________________________
p4-projects@xxxxxxxxxxx mailing list
http://lists.freebsd.org/mailman/listinfo/p4-projects
To unsubscribe, send any mail to "p4-projects-unsubscribe@xxxxxxxxxxx"

<Prev in Thread] Current Thread [Next in Thread>
  • PERFORCE change 153420 for review, Qing Li <=