Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 30 Nov 2014 14:35:02 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r275334 - in projects/routing/sys: net netinet netinet6
Message-ID:  <201411301435.sAUEZ2F7002543@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Sun Nov 30 14:35:01 2014
New Revision: 275334
URL: https://svnweb.freebsd.org/changeset/base/275334

Log:
  * Unify lle table dump/prefix removal code.
  * Rename lla_XXX -> lltable_XXX_lle to reduce number of name prefixes
    used by lltable code.

Modified:
  projects/routing/sys/net/if_llatbl.c
  projects/routing/sys/net/if_llatbl.h
  projects/routing/sys/net/rt_nhops.c
  projects/routing/sys/netinet/if_ether.c
  projects/routing/sys/netinet/in.c
  projects/routing/sys/netinet/toecore.c
  projects/routing/sys/netinet6/in6.c
  projects/routing/sys/netinet6/nd6.c

Modified: projects/routing/sys/net/if_llatbl.c
==============================================================================
--- projects/routing/sys/net/if_llatbl.c	Sun Nov 30 13:43:52 2014	(r275333)
+++ projects/routing/sys/net/if_llatbl.c	Sun Nov 30 14:35:01 2014	(r275334)
@@ -72,8 +72,33 @@ struct rwlock lltable_rwlock;
 RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock");
 
 /*
- * Dump arp state for a specific address family.
+ * Dump lle state for a specific address family.
  */
+static int
+lltable_dump_af(struct lltable *llt, struct sysctl_req *wr)
+{
+	struct llentry *lle;
+	int i, error;
+
+	LLTABLE_LOCK_ASSERT();
+
+	if (llt->llt_ifp->if_flags & IFF_LOOPBACK)
+		return (0);
+	error = 0;
+
+	IF_AFDATA_CFG_RLOCK(llt->llt_ifp);
+	for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
+		LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
+			error = llt->llt_dump_entry(llt, lle, wr);
+			if (error != 0)
+				break;
+		}
+	}
+	IF_AFDATA_CFG_RUNLOCK(llt->llt_ifp);
+
+	return (error);
+}
+
 int
 lltable_sysctl_dumparp(int af, struct sysctl_req *wr)
 {
@@ -83,7 +108,7 @@ lltable_sysctl_dumparp(int af, struct sy
 	LLTABLE_RLOCK();
 	SLIST_FOREACH(llt, &V_lltables, llt_link) {
 		if (llt->llt_af == af) {
-			error = llt->llt_dump(llt, wr);
+			error = lltable_dump_af(llt, wr);
 			if (error != 0)
 				goto done;
 		}
@@ -186,12 +211,12 @@ llentry_alloc(struct ifnet *ifp, struct 
 	struct llentry *la;
 
 	IF_AFDATA_RLOCK(ifp);
-	la = lla_lookup(lt, LLE_EXCLUSIVE, (struct sockaddr *)dst);
+	la = lt->llt_lookup(lt, LLE_EXCLUSIVE, (struct sockaddr *)dst);
 	IF_AFDATA_RUNLOCK(ifp);
 	if ((la == NULL) &&
 	    (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
 		IF_AFDATA_CFG_WLOCK(ifp);
-		la = lla_create(lt, 0, (struct sockaddr *)dst);
+		la = lt->llt_create(lt, 0, (struct sockaddr *)dst);
 		if (la != NULL) {
 			IF_AFDATA_RUN_WLOCK(ifp);
 			llentry_link(lt, la);
@@ -229,10 +254,7 @@ lltable_free(struct lltable *llt)
 	for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
 		LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
 			LLE_WLOCK(lle);
-			if (callout_stop(&lle->la_timer)) {
-				LLE_REMREF(lle);
-				lle->la_flags &= ~LLE_CALLOUTREF;
-			}
+			llt->llt_stop_timers(lle);
 			LIST_INSERT_HEAD(&dchain, lle, lle_chain);
 		}
 	}
@@ -246,6 +268,33 @@ lltable_free(struct lltable *llt)
 	free(llt, M_LLTABLE);
 }
 
+static void
+lltable_prefix_free_af(struct lltable *llt, const struct sockaddr *prefix,
+    const struct sockaddr *mask, u_int flags)
+{
+	struct llentries dchain;
+	struct llentry *lle, *next;
+	int i;
+
+	LIST_INIT(&dchain);
+	IF_AFDATA_CFG_WLOCK(llt->llt_ifp);
+	for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
+		LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
+			if (llt->llt_match_prefix(prefix, mask, flags, lle)) {
+				LLE_WLOCK(lle);
+				llt->llt_stop_timers(lle);
+				LIST_INSERT_HEAD(&dchain, lle, lle_chain);
+			}
+		}
+	}
+	IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
+	llentries_unlink(&dchain);
+	IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
+	LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next)
+		llentry_free(lle);
+	IF_AFDATA_CFG_WUNLOCK(llt->llt_ifp);
+}
+
 #if 0
 void
 lltable_drain(int af)
@@ -285,7 +334,7 @@ lltable_prefix_free(int af, struct socka
 		if (llt->llt_af != af)
 			continue;
 
-		llt->llt_prefix_free(llt, prefix, mask, flags);
+		lltable_prefix_free_af(llt, prefix, mask, flags);
 	}
 	LLTABLE_RUNLOCK();
 }
@@ -356,7 +405,7 @@ lla_rt_output(struct rt_msghdr *rtm, str
 	case RTM_ADD:
 		/* Add static LLE */
 		IF_AFDATA_CFG_WLOCK(ifp);
-		lle = lla_create(llt, 0, dst);
+		lle = llt->llt_create(llt, 0, dst);
 		if (lle == NULL) {
 			IF_AFDATA_CFG_WUNLOCK(ifp);
 			return (ENOMEM);
@@ -403,7 +452,7 @@ lla_rt_output(struct rt_msghdr *rtm, str
 
 	case RTM_DELETE:
 		IF_AFDATA_CFG_WLOCK(ifp);
-		error = lla_delete(llt, 0, dst);
+		error = (llt->llt_delete(llt, 0, dst));
 		IF_AFDATA_CFG_WUNLOCK(ifp);
 		return (error == 0 ? 0 : ENOENT);
 

Modified: projects/routing/sys/net/if_llatbl.h
==============================================================================
--- projects/routing/sys/net/if_llatbl.h	Sun Nov 30 13:43:52 2014	(r275333)
+++ projects/routing/sys/net/if_llatbl.h	Sun Nov 30 14:35:01 2014	(r275334)
@@ -153,10 +153,12 @@ typedef	struct llentry *(llt_create_t)(s
     const struct sockaddr *l3addr);
 typedef	int (llt_delete_t)(struct lltable *, u_int flags,
     const struct sockaddr *l3addr);
-typedef void (llt_prefix_free_t)(struct lltable *,
-    const struct sockaddr *prefix, const struct sockaddr *mask, u_int flags);
-typedef int (llt_dump_t)(struct lltable *, struct sysctl_req *);
+typedef int (llt_dump_entry_t)(struct lltable *, struct llentry *,
+    struct sysctl_req *);
 typedef uint32_t (llt_hash_t)(const struct llentry *);
+typedef int (llt_match_prefix_t)(const struct sockaddr *,
+    const struct sockaddr *, u_int, struct llentry *);
+typedef void (llt_stop_timers_t)(struct llentry *lle);
 
 struct lltable {
 	SLIST_ENTRY(lltable)	llt_link;
@@ -167,9 +169,10 @@ struct lltable {
 	llt_lookup_t		*llt_lookup;
 	llt_create_t		*llt_create;
 	llt_delete_t		*llt_delete;
-	llt_prefix_free_t	*llt_prefix_free;
-	llt_dump_t		*llt_dump;
+	llt_dump_entry_t	*llt_dump_entry;
 	llt_hash_t		*llt_hash;
+	llt_match_prefix_t	*llt_match_prefix;
+	llt_stop_timers_t	*llt_stop_timers;
 };
 
 MALLOC_DECLARE(M_LLTABLE);
@@ -216,21 +219,24 @@ struct llentry  *llentry_alloc(struct if
  * Generic link layer address lookup function.
  */
 static __inline struct llentry *
-lla_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
+lltable_lookup_lle(struct lltable *llt, u_int flags,
+    const struct sockaddr *l3addr)
 {
 
 	return llt->llt_lookup(llt, flags, l3addr);
 }
 
 static __inline struct llentry *
-lla_create(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
+lltable_create_lle(struct lltable *llt, u_int flags,
+    const struct sockaddr *l3addr)
 {
 
 	return llt->llt_create(llt, flags, l3addr);
 }
 
 static __inline int
-lla_delete(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
+lltable_delete_lle(struct lltable *llt, u_int flags,
+    const struct sockaddr *l3addr)
 {
 
 	return llt->llt_delete(llt, flags, l3addr);

Modified: projects/routing/sys/net/rt_nhops.c
==============================================================================
--- projects/routing/sys/net/rt_nhops.c	Sun Nov 30 13:43:52 2014	(r275333)
+++ projects/routing/sys/net/rt_nhops.c	Sun Nov 30 14:35:01 2014	(r275334)
@@ -699,7 +699,8 @@ fib6_storelladdr(struct ifnet *ifp, stru
 	 * the entry should have been created in nd6_store_lladdr
 	 */
 	IF_AFDATA_RUN_RLOCK(ifp);
-	ln = lla_lookup(LLTABLE6(ifp), LLE_UNLOCKED, (struct sockaddr *)&dst_sa);
+	ln = lltable_lookup_lle(LLTABLE6(ifp), LLE_UNLOCKED,
+	    (struct sockaddr *)&dst_sa);
 
 	/*
 	 * Perform fast path for the following cases:

Modified: projects/routing/sys/netinet/if_ether.c
==============================================================================
--- projects/routing/sys/netinet/if_ether.c	Sun Nov 30 13:43:52 2014	(r275333)
+++ projects/routing/sys/netinet/if_ether.c	Sun Nov 30 14:35:01 2014	(r275334)
@@ -164,7 +164,8 @@ arp_ifscrub(struct ifnet *ifp, uint32_t 
 	addr4.sin_family = AF_INET;
 	addr4.sin_addr.s_addr = addr;
 	IF_AFDATA_CFG_WLOCK(ifp);
-	lla_delete(LLTABLE(ifp), LLE_IFADDR, (struct sockaddr *)&addr4);
+	lltable_delete_lle(LLTABLE(ifp), LLE_IFADDR,
+	    (struct sockaddr *)&addr4);
 	IF_AFDATA_CFG_WUNLOCK(ifp);
 }
 #endif
@@ -258,6 +259,11 @@ arptimer(void *arg)
 		lle->la_flags &= ~LLE_CALLOUTREF;
 	}
 
+	/* Unlink entry */
+	IF_AFDATA_RUN_WLOCK(ifp);
+	llentry_unlink(lle);
+	IF_AFDATA_RUN_WUNLOCK(ifp);
+
 	pkts_dropped = llentry_free(lle);
 	ARPSTAT_ADD(dropped, pkts_dropped);
 
@@ -373,7 +379,7 @@ arpresolve_fast(struct ifnet *ifp, struc
 	sa_dst = (const struct sockaddr *)&sin;
 
 	IF_AFDATA_RUN_RLOCK(ifp);
-	la = lla_lookup(LLTABLE(ifp), LLE_UNLOCKED, sa_dst);
+	la = lltable_lookup_lle(LLTABLE(ifp), LLE_UNLOCKED, sa_dst);
 	if (la != NULL && (la->r_flags & RLLE_VALID) != 0) {
 		/* Entry found, let's copy lle info */
 		bcopy(&la->ll_addr, dst_addr, ifp->if_addrlen);
@@ -458,7 +464,7 @@ arpresolve(struct ifnet *ifp, struct rte
 	}
 
 	IF_AFDATA_RUN_RLOCK(ifp);
-	la = lla_lookup(LLTABLE(ifp), LLE_UNLOCKED, dst);
+	la = lltable_lookup_lle(LLTABLE(ifp), LLE_UNLOCKED, dst);
 	if (la != NULL && (la->r_flags & RLLE_VALID) != 0) {
 		/* Entry found, let's copy lle info */
 		bcopy(&la->ll_addr, desten, ifp->if_addrlen);
@@ -487,12 +493,12 @@ arpresolve_slow(struct ifnet *ifp, int i
 	*lle = NULL;
 
 	IF_AFDATA_RLOCK(ifp);
-	la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
+	la = lltable_lookup_lle(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
 	IF_AFDATA_RUNLOCK(ifp);
 	if (la == NULL && (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
 		create = 1;
 		IF_AFDATA_CFG_WLOCK(ifp);
-		la = lla_create(LLTABLE(ifp), 0, dst);
+		la = lltable_create_lle(LLTABLE(ifp), 0, dst);
 		if (la != NULL) {
 			IF_AFDATA_RUN_WLOCK(ifp);
 			llentry_link(LLTABLE(ifp), la);
@@ -858,9 +864,11 @@ match:
 	flags = LLE_EXCLUSIVE;
 	IF_AFDATA_CFG_WLOCK(ifp);
 	if (create != 0) {
-		la = lla_create(LLTABLE(ifp), 0, (struct sockaddr *)&sin);
+		la = lltable_create_lle(LLTABLE(ifp), 0,
+		    (struct sockaddr *)&sin);
 	} else
-		la = lla_lookup(LLTABLE(ifp), flags, (struct sockaddr *)&sin);
+		la = lltable_lookup_lle(LLTABLE(ifp), flags,
+		    (struct sockaddr *)&sin);
 	IF_AFDATA_CFG_WUNLOCK(ifp);
 	if (la != NULL) {
 		/* the following is not an error when doing bridging */
@@ -989,7 +997,8 @@ reply:
 
 		sin.sin_addr = itaddr;
 		IF_AFDATA_RLOCK(ifp);
-		lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin);
+		lle = lltable_lookup_lle(LLTABLE(ifp), 0,
+		    (struct sockaddr *)&sin);
 		IF_AFDATA_RUNLOCK(ifp);
 
 		if ((lle != NULL) && (lle->la_flags & LLE_PUB)) {
@@ -1093,7 +1102,7 @@ arp_ifinit(struct ifnet *ifp, struct ifa
 		 * that L2 entry as permanent
 		 */
 		IF_AFDATA_CFG_WLOCK(ifp);
-		lle = lla_create(LLTABLE(ifp), LLE_IFADDR | LLE_STATIC,
+		lle = lltable_create_lle(LLTABLE(ifp), LLE_IFADDR | LLE_STATIC,
 				 (struct sockaddr *)IA_SIN(ifa));
 		if (lle != NULL) {
 			IF_AFDATA_RUN_WLOCK(ifp);

Modified: projects/routing/sys/netinet/in.c
==============================================================================
--- projects/routing/sys/netinet/in.c	Sun Nov 30 13:43:52 2014	(r275333)
+++ projects/routing/sys/netinet/in.c	Sun Nov 30 14:35:01 2014	(r275334)
@@ -1035,51 +1035,37 @@ in_lltable_new(const struct sockaddr *l3
 	return (&lle->base);
 }
 
+static void
+in_lltable_stop_timers(struct  llentry *lle)
+{
+
+	LLE_WLOCK_ASSERT(lle);
+	if (callout_stop(&lle->la_timer)) {
+		LLE_REMREF(lle);
+		lle->la_flags &= ~LLE_CALLOUTREF;
+	}
+}
+
 #define IN_ARE_MASKED_ADDR_EQUAL(d, a, m)	(			\
 	    (((ntohl((d)->sin_addr.s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 )
 
-static void
-in_lltable_prefix_free(struct lltable *llt, const struct sockaddr *prefix,
-    const struct sockaddr *mask, u_int flags)
+static int
+in_lltable_match_prefix(const struct sockaddr *prefix,
+    const struct sockaddr *mask, u_int flags, struct llentry *lle)
 {
 	const struct sockaddr_in *pfx = (const struct sockaddr_in *)prefix;
 	const struct sockaddr_in *msk = (const struct sockaddr_in *)mask;
-	struct llentry *lle, *next;
-	struct llentries dchain;
-	int i;
-	size_t pkts_dropped;
-
-	LIST_INIT(&dchain);
-	IF_AFDATA_CFG_WLOCK(llt->llt_ifp);
-	for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
-		LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
-			/*
-			 * (flags & LLE_STATIC) means deleting all entries
-			 * including static ARP entries.
-			 */
-			if (IN_ARE_MASKED_ADDR_EQUAL(satosin(L3_ADDR(lle)),
-			    pfx, msk) && ((flags & LLE_STATIC) ||
-			    !(lle->la_flags & LLE_STATIC))) {
-				LLE_WLOCK(lle);
-				if (callout_stop(&lle->la_timer)) {
-					LLE_REMREF(lle);
-					lle->la_flags &= ~LLE_CALLOUTREF;
-				}
-				LIST_INSERT_HEAD(&dchain, lle, lle_chain);
-			}
-		}
-	}
-	/* Unlink chain */
-	IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
-	llentries_unlink(&dchain);
-	IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
-	LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) {
-		pkts_dropped = llentry_free(lle);
-		ARPSTAT_ADD(dropped, pkts_dropped);
-	}
-	IF_AFDATA_CFG_WUNLOCK(llt->llt_ifp);
-}
 
+	/*
+	 * (flags & LLE_STATIC) means deleting all entries
+	 * including static ARP entries.
+	 */
+	if (IN_ARE_MASKED_ADDR_EQUAL(satosin(L3_ADDR(lle)), pfx, msk) &&
+	    ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)))
+		return (1);
+
+	return (0);
+}
 
 static int
 in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
@@ -1265,29 +1251,22 @@ in_lltable_lookup(struct lltable *llt, u
 }
 
 static int
-in_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
+in_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
+    struct sysctl_req *wr)
 {
-#define	SIN(lle)	((struct sockaddr_in *) L3_ADDR(lle))
 	struct ifnet *ifp = llt->llt_ifp;
-	struct llentry *lle;
 	/* XXX stack use */
 	struct {
 		struct rt_msghdr	rtm;
 		struct sockaddr_in	sin;
 		struct sockaddr_dl	sdl;
 	} arpc;
-	int error, i;
-
-	LLTABLE_LOCK_ASSERT();
-
-	error = 0;
-	for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
-		LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
-			struct sockaddr_dl *sdl;
+	struct sockaddr_dl *sdl;
+	int error;
 
 			/* Skip if jailed and not a valid IP of the prison. */
 			if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0)
-				continue;
+				return (0);
 			/*
 			 * produce a msg made of:
 			 *  struct rt_msghdr;
@@ -1302,7 +1281,7 @@ in_lltable_dump(struct lltable *llt, str
 			arpc.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
 			arpc.sin.sin_family = AF_INET;
 			arpc.sin.sin_len = sizeof(arpc.sin);
-			arpc.sin.sin_addr.s_addr = SIN(lle)->sin_addr.s_addr;
+			arpc.sin.sin_addr.s_addr = lle->r_l3addr.addr4.s_addr;
 
 			/* publish */
 			if (lle->la_flags & LLE_PUB)
@@ -1328,12 +1307,8 @@ in_lltable_dump(struct lltable *llt, str
 				arpc.rtm.rtm_flags |= RTF_STATIC;
 			arpc.rtm.rtm_index = ifp->if_index;
 			error = SYSCTL_OUT(wr, &arpc, sizeof(arpc));
-			if (error)
-				break;
-		}
-	}
-	return error;
-#undef SIN
+
+	return (error);
 }
 
 void *
@@ -1346,12 +1321,13 @@ in_domifattach(struct ifnet *ifp)
 
 	llt = lltable_init(ifp, AF_INET);
 	if (llt != NULL) {
-		llt->llt_prefix_free = in_lltable_prefix_free;
 		llt->llt_lookup = in_lltable_lookup;
 		llt->llt_create = in_lltable_create;
 		llt->llt_delete = in_lltable_delete;
-		llt->llt_dump = in_lltable_dump;
+		llt->llt_dump_entry = in_lltable_dump_entry;
 		llt->llt_hash = in_lltable_hash;
+		llt->llt_stop_timers = in_lltable_stop_timers;
+		llt->llt_match_prefix = in_lltable_match_prefix;
 	}
 	ii->ii_llt = llt;
 

Modified: projects/routing/sys/netinet/toecore.c
==============================================================================
--- projects/routing/sys/netinet/toecore.c	Sun Nov 30 13:43:52 2014	(r275333)
+++ projects/routing/sys/netinet/toecore.c	Sun Nov 30 14:35:01 2014	(r275334)
@@ -459,7 +459,7 @@ toe_nd6_resolve(struct ifnet *ifp, struc
 
 restart:
 	IF_AFDATA_RLOCK(ifp);
-	lle = lla_lookup(LLTABLE6(ifp), flags, sa);
+	lle = lltable_lookup_lle(LLTABLE6(ifp), flags, sa);
 	IF_AFDATA_RUNLOCK(ifp);
 	if (lle == NULL) {
 		IF_AFDATA_CFG_WLOCK(ifp);

Modified: projects/routing/sys/netinet6/in6.c
==============================================================================
--- projects/routing/sys/netinet6/in6.c	Sun Nov 30 13:43:52 2014	(r275333)
+++ projects/routing/sys/netinet6/in6.c	Sun Nov 30 14:35:01 2014	(r275334)
@@ -2088,43 +2088,29 @@ in6_lltable_new(const struct sockaddr *l
 }
 
 static void
-in6_lltable_prefix_free(struct lltable *llt, const struct sockaddr *prefix,
-    const struct sockaddr *mask, u_int flags)
+in6_lltable_stop_timers(struct llentry *lle)
+{
+
+	LLE_WLOCK_ASSERT(lle);
+	if (callout_stop(&lle->la_timer)) {
+		LLE_REMREF(lle);
+		lle->la_flags &= ~LLE_CALLOUTREF;
+	}
+}
+
+static int
+in6_lltable_match_prefix(const struct sockaddr *prefix,
+    const struct sockaddr *mask, u_int flags, struct llentry *lle)
 {
 	const struct sockaddr_in6 *pfx = (const struct sockaddr_in6 *)prefix;
 	const struct sockaddr_in6 *msk = (const struct sockaddr_in6 *)mask;
-	struct llentries dchain;
-	struct llentry *lle, *next;
-	int i;
 
-	/*
-	 * (flags & LLE_STATIC) means deleting all entries
-	 * including static ND6 entries.
-	 */
-	LIST_INIT(&dchain);
-	IF_AFDATA_CFG_WLOCK(llt->llt_ifp);
-	for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
-		LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
-			if (IN6_ARE_MASKED_ADDR_EQUAL(
-			    &satosin6(L3_ADDR(lle))->sin6_addr,
-			    &pfx->sin6_addr, &msk->sin6_addr) &&
-			    ((flags & LLE_STATIC) ||
-			    !(lle->la_flags & LLE_STATIC))) {
-				LLE_WLOCK(lle);
-				if (callout_stop(&lle->la_timer)) {
-					LLE_REMREF(lle);
-					lle->la_flags &= ~LLE_CALLOUTREF;
-				}
-				LIST_INSERT_HEAD(&dchain, lle, lle_chain);
-			}
-		}
-	}
-	IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
-	llentries_unlink(&dchain);
-	IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
-	LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next)
-		llentry_free(lle);
-	IF_AFDATA_CFG_WUNLOCK(llt->llt_ifp);
+	if (IN6_ARE_MASKED_ADDR_EQUAL(&satosin6(L3_ADDR(lle))->sin6_addr,
+	    &pfx->sin6_addr, &msk->sin6_addr) &&
+	    ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)))
+		return (1);
+
+	return (0);
 }
 
 static int
@@ -2296,10 +2282,10 @@ in6_lltable_lookup(struct lltable *llt, 
 }
 
 static int
-in6_lltable_dump(struct lltable *llt, struct sysctl_req *wr)
+in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
+    struct sysctl_req *wr)
 {
 	struct ifnet *ifp = llt->llt_ifp;
-	struct llentry *lle;
 	/* XXX stack use */
 	struct {
 		struct rt_msghdr	rtm;
@@ -2312,24 +2298,15 @@ in6_lltable_dump(struct lltable *llt, st
 #endif
 		struct sockaddr_dl	sdl;
 	} ndpc;
-	int i, error;
-
-	if (ifp->if_flags & IFF_LOOPBACK)
-		return 0;
-
-	LLTABLE_LOCK_ASSERT();
-
-	error = 0;
-	for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
-		LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
-			struct sockaddr_dl *sdl;
+	struct sockaddr_dl *sdl;
+	int error;
 
 			/* skip invalid entries */
 			if ((lle->la_flags & LLE_VALID) == 0)
-				continue;
+				return (0);
 			/* Skip if jailed and not a valid IP of the prison. */
 			if (prison_if(wr->td->td_ucred, L3_ADDR(lle)) != 0)
-				continue;
+				return (0);
 			/*
 			 * produce a msg made of:
 			 *  struct rt_msghdr;
@@ -2366,11 +2343,8 @@ in6_lltable_dump(struct lltable *llt, st
 				ndpc.rtm.rtm_flags |= RTF_STATIC;
 			ndpc.rtm.rtm_index = ifp->if_index;
 			error = SYSCTL_OUT(wr, &ndpc, sizeof(ndpc));
-			if (error)
-				break;
-		}
-	}
-	return error;
+
+	return (error);
 }
 
 void *
@@ -2403,12 +2377,13 @@ in6_domifattach(struct ifnet *ifp)
 	ext->scope6_id = scope6_ifattach(ifp);
 	ext->lltable = lltable_init(ifp, AF_INET6);
 	if (ext->lltable != NULL) {
-		ext->lltable->llt_prefix_free = in6_lltable_prefix_free;
 		ext->lltable->llt_lookup = in6_lltable_lookup;
 		ext->lltable->llt_create = in6_lltable_create;
 		ext->lltable->llt_delete = in6_lltable_delete;
-		ext->lltable->llt_dump = in6_lltable_dump;
+		ext->lltable->llt_dump_entry = in6_lltable_dump_entry;
 		ext->lltable->llt_hash = in6_lltable_hash;
+		ext->lltable->llt_stop_timers = in6_lltable_stop_timers;
+		ext->lltable->llt_match_prefix = in6_lltable_match_prefix;
 	}
 
 	ext->mld_ifinfo = mld_domifattach(ifp);

Modified: projects/routing/sys/netinet6/nd6.c
==============================================================================
--- projects/routing/sys/netinet6/nd6.c	Sun Nov 30 13:43:52 2014	(r275333)
+++ projects/routing/sys/netinet6/nd6.c	Sun Nov 30 14:35:01 2014	(r275334)
@@ -860,7 +860,8 @@ nd6_lookup(struct in6_addr *addr6, int f
 	*/
 
 	llflags = (flags & ND6_EXCLUSIVE) ? LLE_EXCLUSIVE : 0;
-	ln = lla_lookup(LLTABLE6(ifp), llflags, (struct sockaddr *)&sin6);
+	ln = lltable_lookup_lle(LLTABLE6(ifp), llflags,
+	    (struct sockaddr *)&sin6);
 	
 	return (ln);
 }
@@ -882,7 +883,7 @@ nd6_create(struct in6_addr *addr6, int f
 
 	IF_AFDATA_CFG_WLOCK_ASSERT(ifp);
 
-	ln = lla_create(LLTABLE6(ifp), 0, (struct sockaddr *)&sin6);
+	ln = lltable_create_lle(LLTABLE6(ifp), 0, (struct sockaddr *)&sin6);
 	if (ln != NULL) {
 		IF_AFDATA_RUN_WLOCK(ifp);
 		ln->ln_state = ND6_LLINFO_NOSTATE;
@@ -2269,7 +2270,7 @@ nd6_add_ifa_lle(struct in6_ifaddr *ia)
 
 	ifp = ia->ia_ifa.ifa_ifp;
 	IF_AFDATA_CFG_WLOCK(ifp);
-	ln = lla_create(LLTABLE6(ifp), LLE_IFADDR,
+	ln = lltable_create_lle(LLTABLE6(ifp), LLE_IFADDR,
 	    (struct sockaddr *)&ia->ia_addr);
 	if (ln != NULL) {
 		IF_AFDATA_RUN_WLOCK(ifp);
@@ -2366,7 +2367,7 @@ nd6_storelladdr(struct ifnet *ifp, struc
 	 * the entry should have been created in nd6_store_lladdr
 	 */
 	IF_AFDATA_RLOCK(ifp);
-	ln = lla_lookup(LLTABLE6(ifp), 0, dst);
+	ln = lltable_lookup_lle(LLTABLE6(ifp), 0, dst);
 	IF_AFDATA_RUNLOCK(ifp);
 	if ((ln == NULL) || !(ln->la_flags & LLE_VALID)) {
 		if (ln != NULL)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201411301435.sAUEZ2F7002543>