PERFORCE change 153420 for review

Qing Li qingli at FreeBSD.org
Sun Nov 23 19:02:01 PST 2008


http://perforce.freebsd.org/chv.cgi?CH=153420

Change 153420 by qingli at 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) <<<


More information about the p4-projects mailing list