Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Aug 2015 09:26:12 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r286624 - in head/sys: net netinet netinet6
Message-ID:  <201508110926.t7B9QCIx043317@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Tue Aug 11 09:26:11 2015
New Revision: 286624
URL: https://svnweb.freebsd.org/changeset/base/286624

Log:
  Store addresses instead of sockaddrs inside llentry.
  This permits us having all (not fully true yet) all the info
  needed in lookup process in first 64 bytes of 'struct llentry'.
  
  struct llentry layout:
  BEFORE:
  [rwlock .. state .. state .. MAC ] (lle+1) [sockaddr_in[6]]
  AFTER
  [ in[6]_addr MAC .. state .. rwlock ]
  
  Currently, address part of struct llentry has only 16 bytes for the key.
  However, lltable does not restrict any custom lltable consumers with long
  keys use the previous approach (store key at (lle+1)).
  
  Sponsored by:	Yandex LLC

Modified:
  head/sys/net/if_llatbl.h
  head/sys/netinet/if_ether.c
  head/sys/netinet/in.c
  head/sys/netinet/toecore.c
  head/sys/netinet6/in6.c
  head/sys/netinet6/nd6.c
  head/sys/netinet6/nd6_nbr.c

Modified: head/sys/net/if_llatbl.h
==============================================================================
--- head/sys/net/if_llatbl.h	Tue Aug 11 09:18:51 2015	(r286623)
+++ head/sys/net/if_llatbl.h	Tue Aug 11 09:26:11 2015	(r286624)
@@ -54,7 +54,18 @@ extern struct rwlock lltable_rwlock;
  */
 struct llentry {
 	LIST_ENTRY(llentry)	 lle_next;
-	struct rwlock		 lle_lock;
+	union {
+		struct in_addr	addr4;
+		struct in6_addr	addr6;
+	} r_l3addr;
+	union {
+		uint64_t	mac_aligned;
+		uint16_t	mac16[3];
+		uint8_t		mac8[20];	/* IB needs 20 bytes. */
+	} ll_addr;
+	uint32_t		spare0;
+	uint64_t		spare1;
+
 	struct lltable		 *lle_tbl;
 	struct llentries	 *lle_head;
 	void			(*lle_free)(struct llentry *);
@@ -70,19 +81,13 @@ struct llentry {
 	time_t			 ln_ntick;
 	int			 lle_refcnt;
 
-	union {
-		uint64_t	mac_aligned;
-		uint16_t	mac16[3];
-		uint8_t		mac8[20];	/* IB needs 20 bytes. */
-	} ll_addr;
-
 	LIST_ENTRY(llentry)	lle_chain;	/* chain of deleted items */
 	/* XXX af-private? */
 	union {
 		struct callout	ln_timer_ch;
 		struct callout  la_timer;
 	} lle_timer;
-	/* NB: struct sockaddr must immediately follow */
+	struct rwlock		 lle_lock;
 };
 
 #define	LLE_WLOCK(lle)		rw_wlock(&(lle)->lle_lock)
@@ -133,11 +138,6 @@ struct llentry {
 #define	ln_timer_ch	lle_timer.ln_timer_ch
 #define	la_timer	lle_timer.la_timer
 
-/* XXX bad name */
-#define	L3_CADDR(lle)	((const struct sockaddr *)(&lle[1]))
-#define	L3_ADDR(lle)	((struct sockaddr *)(&lle[1]))
-#define	L3_ADDR_LEN(lle)	(((struct sockaddr *)(&lle[1]))->sa_len)
-
 typedef	struct llentry *(llt_lookup_t)(struct lltable *, u_int flags,
     const struct sockaddr *l3addr);
 typedef	struct llentry *(llt_create_t)(struct lltable *, u_int flags,

Modified: head/sys/netinet/if_ether.c
==============================================================================
--- head/sys/netinet/if_ether.c	Tue Aug 11 09:18:51 2015	(r286623)
+++ head/sys/netinet/if_ether.c	Tue Aug 11 09:26:11 2015	(r286624)
@@ -813,7 +813,7 @@ match:
 			m_hold = la->la_hold;
 			la->la_hold = NULL;
 			la->la_numheld = 0;
-			memcpy(&sa, L3_ADDR(la), sizeof(sa));
+			lltable_fill_sa_entry(la, (struct sockaddr *)&sa);
 			LLE_WUNLOCK(la);
 			for (; m_hold != NULL; m_hold = m_hold_next) {
 				m_hold_next = m_hold->m_nextpkt;

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Tue Aug 11 09:18:51 2015	(r286623)
+++ head/sys/netinet/in.c	Tue Aug 11 09:26:11 2015	(r286624)
@@ -958,7 +958,6 @@ in_purgemaddrs(struct ifnet *ifp)
 
 struct in_llentry {
 	struct llentry		base;
-	struct sockaddr_in	l3_addr4;
 };
 
 #define	IN_LLTBL_DEFAULT_HSIZE	32
@@ -980,7 +979,7 @@ in_lltable_destroy_lle(struct llentry *l
 }
 
 static struct llentry *
-in_lltable_new(const struct sockaddr *l3addr, u_int flags)
+in_lltable_new(struct in_addr addr4, u_int flags)
 {
 	struct in_llentry *lle;
 
@@ -993,7 +992,7 @@ in_lltable_new(const struct sockaddr *l3
 	 * an ARP request.
 	 */
 	lle->base.la_expire = time_uptime; /* mark expired */
-	lle->l3_addr4 = *(const struct sockaddr_in *)l3addr;
+	lle->base.r_l3addr.addr4 = addr4;
 	lle->base.lle_refcnt = 1;
 	lle->base.lle_free = in_lltable_destroy_lle;
 	LLE_LOCK_INIT(&lle->base);
@@ -1003,7 +1002,7 @@ in_lltable_new(const struct sockaddr *l3
 }
 
 #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 )
+	    (((ntohl((d).s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 )
 
 static int
 in_lltable_match_prefix(const struct sockaddr *prefix,
@@ -1016,7 +1015,7 @@ in_lltable_match_prefix(const struct soc
 	 * (flags & LLE_STATIC) means deleting all entries
 	 * including static ARP entries.
 	 */
-	if (IN_ARE_MASKED_ADDR_EQUAL(satosin(L3_ADDR(lle)), pfx, msk) &&
+	if (IN_ARE_MASKED_ADDR_EQUAL(lle->r_l3addr.addr4, pfx, msk) &&
 	    ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)))
 		return (1);
 
@@ -1132,11 +1131,8 @@ in_lltable_hash_dst(const struct in_addr
 static uint32_t
 in_lltable_hash(const struct llentry *lle, uint32_t hsize)
 {
-	const struct sockaddr_in *sin;
 
-	sin = (const struct sockaddr_in *)(L3_CADDR(lle));
-
-	return (in_lltable_hash_dst(sin->sin_addr, hsize));
+	return (in_lltable_hash_dst(lle->r_l3addr.addr4, hsize));
 }
 
 static void
@@ -1148,7 +1144,7 @@ in_lltable_fill_sa_entry(const struct ll
 	bzero(sin, sizeof(*sin));
 	sin->sin_family = AF_INET;
 	sin->sin_len = sizeof(*sin);
-	sin->sin_addr = ((const struct sockaddr_in *)(L3_CADDR(lle)))->sin_addr;
+	sin->sin_addr = lle->r_l3addr.addr4;
 }
 
 static inline struct llentry *
@@ -1156,16 +1152,14 @@ in_lltable_find_dst(struct lltable *llt,
 {
 	struct llentry *lle;
 	struct llentries *lleh;
-	struct sockaddr_in *sin;
 	u_int hashidx;
 
 	hashidx = in_lltable_hash_dst(dst, llt->llt_hsize);
 	lleh = &llt->lle_head[hashidx];
 	LIST_FOREACH(lle, lleh, lle_next) {
-		sin = satosin(L3_ADDR(lle));
 		if (lle->la_flags & LLE_DELETED)
 			continue;
-		if (sin->sin_addr.s_addr == dst.s_addr)
+		if (lle->r_l3addr.addr4.s_addr == dst.s_addr)
 			break;
 	}
 
@@ -1236,7 +1230,7 @@ in_lltable_create(struct lltable *llt, u
 	    in_lltable_rtcheck(ifp, flags, l3addr) != 0)
 		return (NULL);
 
-	lle = in_lltable_new(l3addr, flags);
+	lle = in_lltable_new(sin->sin_addr, flags);
 	if (lle == NULL) {
 		log(LOG_INFO, "lla_lookup: new lle malloc failed\n");
 		return (NULL);

Modified: head/sys/netinet/toecore.c
==============================================================================
--- head/sys/netinet/toecore.c	Tue Aug 11 09:18:51 2015	(r286623)
+++ head/sys/netinet/toecore.c	Tue Aug 11 09:26:11 2015	(r286624)
@@ -390,27 +390,30 @@ toe_lle_event(void *arg __unused, struct
 	struct sockaddr *sa;
 	uint8_t *lladdr;
 	uint16_t vtag;
+	int family;
+	struct sockaddr_in6 sin6;
 
 	LLE_WLOCK_ASSERT(lle);
 
-	ifp = lle->lle_tbl->llt_ifp;
-	sa = L3_ADDR(lle);
-
-	KASSERT(sa->sa_family == AF_INET || sa->sa_family == AF_INET6,
-	    ("%s: lle_event %d for lle %p but sa %p !INET && !INET6",
-	    __func__, evt, lle, sa));
+	ifp = lltable_get_ifp(lle->lle_tbl);
+	family = lltable_get_af(lle->lle_tbl);
 
+	if (family != AF_INET && family != AF_INET6)
+		return;
 	/*
 	 * Not interested if the interface's TOE capability is not enabled.
 	 */
-	if ((sa->sa_family == AF_INET && !(ifp->if_capenable & IFCAP_TOE4)) ||
-	    (sa->sa_family == AF_INET6 && !(ifp->if_capenable & IFCAP_TOE6)))
+	if ((family == AF_INET && !(ifp->if_capenable & IFCAP_TOE4)) ||
+	    (family == AF_INET6 && !(ifp->if_capenable & IFCAP_TOE6)))
 		return;
 
 	tod = TOEDEV(ifp);
 	if (tod == NULL)
 		return;
 
+	sa = (struct sockaddr *)&sin6;
+	lltable_fill_sa_entry(lle, sa);
+
 	vtag = 0xfff;
 	if (evt != LLENTRY_RESOLVED) {
 

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c	Tue Aug 11 09:18:51 2015	(r286623)
+++ head/sys/netinet6/in6.c	Tue Aug 11 09:26:11 2015	(r286624)
@@ -2047,7 +2047,6 @@ in6_if2idlen(struct ifnet *ifp)
 
 struct in6_llentry {
 	struct llentry		base;
-	struct sockaddr_in6	l3_addr6;
 };
 
 #define	IN6_LLTBL_DEFAULT_HSIZE	32
@@ -2069,7 +2068,7 @@ in6_lltable_destroy_lle(struct llentry *
 }
 
 static struct llentry *
-in6_lltable_new(const struct sockaddr *l3addr, u_int flags)
+in6_lltable_new(const struct in6_addr *addr6, u_int flags)
 {
 	struct in6_llentry *lle;
 
@@ -2077,7 +2076,7 @@ in6_lltable_new(const struct sockaddr *l
 	if (lle == NULL)		/* NB: caller generates msg */
 		return NULL;
 
-	lle->l3_addr6 = *(const struct sockaddr_in6 *)l3addr;
+	lle->base.r_l3addr.addr6 = *addr6;
 	lle->base.lle_refcnt = 1;
 	lle->base.lle_free = in6_lltable_destroy_lle;
 	LLE_LOCK_INIT(&lle->base);
@@ -2093,7 +2092,7 @@ in6_lltable_match_prefix(const struct so
 	const struct sockaddr_in6 *pfx = (const struct sockaddr_in6 *)prefix;
 	const struct sockaddr_in6 *msk = (const struct sockaddr_in6 *)mask;
 
-	if (IN6_ARE_MASKED_ADDR_EQUAL(&satosin6(L3_ADDR(lle))->sin6_addr,
+	if (IN6_ARE_MASKED_ADDR_EQUAL(&lle->r_l3addr.addr6,
 	    &pfx->sin6_addr, &msk->sin6_addr) &&
 	    ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)))
 		return (1);
@@ -2172,11 +2171,8 @@ in6_lltable_hash_dst(const struct in6_ad
 static uint32_t
 in6_lltable_hash(const struct llentry *lle, uint32_t hsize)
 {
-	const struct sockaddr_in6 *sin6;
 
-	sin6 = (const struct sockaddr_in6 *)L3_CADDR(lle);
-
-	return (in6_lltable_hash_dst(&sin6->sin6_addr, hsize));
+	return (in6_lltable_hash_dst(&lle->r_l3addr.addr6, hsize));
 }
 
 static void
@@ -2188,7 +2184,7 @@ in6_lltable_fill_sa_entry(const struct l
 	bzero(sin6, sizeof(*sin6));
 	sin6->sin6_family = AF_INET6;
 	sin6->sin6_len = sizeof(*sin6);
-	sin6->sin6_addr =((const struct sockaddr_in6*)L3_CADDR(lle))->sin6_addr;
+	sin6->sin6_addr = lle->r_l3addr.addr6;
 }
 
 static inline struct llentry *
@@ -2196,16 +2192,14 @@ in6_lltable_find_dst(struct lltable *llt
 {
 	struct llentry *lle;
 	struct llentries *lleh;
-	const struct sockaddr_in6 *sin6;
 	u_int hashidx;
 
 	hashidx = in6_lltable_hash_dst(dst, llt->llt_hsize);
 	lleh = &llt->lle_head[hashidx];
 	LIST_FOREACH(lle, lleh, lle_next) {
-		sin6 = (const struct sockaddr_in6 *)L3_CADDR(lle);
 		if (lle->la_flags & LLE_DELETED)
 			continue;
-		if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, dst))
+		if (IN6_ARE_ADDR_EQUAL(&lle->r_l3addr.addr6, dst))
 			break;
 	}
 
@@ -2272,7 +2266,7 @@ in6_lltable_create(struct lltable *llt, 
 	    in6_lltable_rtcheck(ifp, flags, l3addr) != 0)
 		return (NULL);
 
-	lle = in6_lltable_new(l3addr, flags);
+	lle = in6_lltable_new(&sin6->sin6_addr, flags);
 	if (lle == NULL) {
 		log(LOG_INFO, "lla_lookup: new lle malloc failed\n");
 		return (NULL);

Modified: head/sys/netinet6/nd6.c
==============================================================================
--- head/sys/netinet6/nd6.c	Tue Aug 11 09:18:51 2015	(r286623)
+++ head/sys/netinet6/nd6.c	Tue Aug 11 09:26:11 2015	(r286624)
@@ -66,7 +66,6 @@ __FBSDID("$FreeBSD$");
 #include <netinet/in.h>
 #include <netinet/in_kdtrace.h>
 #include <net/if_llatbl.h>
-#define	L3_ADDR_SIN6(le)	((struct sockaddr_in6 *) L3_ADDR(le))
 #include <netinet/if_ether.h>
 #include <netinet6/in6_var.h>
 #include <netinet/ip6.h>
@@ -150,13 +149,16 @@ static void
 nd6_lle_event(void *arg __unused, struct llentry *lle, int evt)
 {
 	struct rt_addrinfo rtinfo;
-	struct sockaddr_in6 dst, *sa6;
+	struct sockaddr_in6 dst;
 	struct sockaddr_dl gw;
 	struct ifnet *ifp;
 	int type;
 
 	LLE_WLOCK_ASSERT(lle);
 
+	if (lltable_get_af(lle->lle_tbl) != AF_INET6)
+		return;
+
 	switch (evt) {
 	case LLENTRY_RESOLVED:
 		type = RTM_ADD;
@@ -170,20 +172,14 @@ nd6_lle_event(void *arg __unused, struct
 		return;
 	}
 
-	sa6 = L3_ADDR_SIN6(lle);
-	if (sa6->sin6_family != AF_INET6)
-		return;
-	ifp = lle->lle_tbl->llt_ifp;
+	ifp = lltable_get_ifp(lle->lle_tbl);
 
 	bzero(&dst, sizeof(dst));
 	bzero(&gw, sizeof(gw));
 	bzero(&rtinfo, sizeof(rtinfo));
-	dst.sin6_len = sizeof(struct sockaddr_in6);
-	dst.sin6_family = AF_INET6;
-	dst.sin6_addr = sa6->sin6_addr;
+	lltable_fill_sa_entry(lle, (struct sockaddr *)&dst);
 	dst.sin6_scope_id = in6_getscopezone(ifp,
-	    in6_addrscope(&sa6->sin6_addr));
-	in6_clearscope(&dst.sin6_addr); /* XXX */
+	    in6_addrscope(&dst.sin6_addr));
 	gw.sdl_len = sizeof(struct sockaddr_dl);
 	gw.sdl_family = AF_LINK;
 	gw.sdl_alen = ifp->if_addrlen;
@@ -569,7 +565,7 @@ nd6_llinfo_timer(void *arg)
 	}
 
 	ndi = ND_IFINFO(ifp);
-	dst = &L3_ADDR_SIN6(ln)->sin6_addr;
+	dst = &ln->r_l3addr.addr6;
 	if (ln->la_flags & LLE_STATIC) {
 		goto done;
 	}
@@ -1122,7 +1118,7 @@ nd6_free(struct llentry *ln, int gc)
 	ifp = ln->lle_tbl->llt_ifp;
 
 	if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV) {
-		dr = defrouter_lookup(&L3_ADDR_SIN6(ln)->sin6_addr, ifp);
+		dr = defrouter_lookup(&ln->r_l3addr.addr6, ifp);
 
 		if (dr != NULL && dr->expire &&
 		    ln->ln_state == ND6_LLINFO_STALE && gc) {
@@ -1183,7 +1179,7 @@ nd6_free(struct llentry *ln, int gc)
 			 * is in the Default Router List.
 			 * See a corresponding comment in nd6_na_input().
 			 */
-			rt6_flush(&L3_ADDR_SIN6(ln)->sin6_addr, ifp);
+			rt6_flush(&ln->r_l3addr.addr6, ifp);
 		}
 
 		if (dr) {
@@ -1907,7 +1903,7 @@ nd6_grab_holdchain(struct llentry *ln, s
 
 	*chain = ln->la_hold;
 	ln->la_hold = NULL;
-	memcpy(sin6, L3_ADDR_SIN6(ln), sizeof(*sin6));
+	lltable_fill_sa_entry(ln, (struct sockaddr *)sin6);
 
 	if (ln->ln_state == ND6_LLINFO_STALE) {
 

Modified: head/sys/netinet6/nd6_nbr.c
==============================================================================
--- head/sys/netinet6/nd6_nbr.c	Tue Aug 11 09:18:51 2015	(r286623)
+++ head/sys/netinet6/nd6_nbr.c	Tue Aug 11 09:26:11 2015	(r286624)
@@ -68,7 +68,6 @@ __FBSDID("$FreeBSD$");
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <net/if_llatbl.h>
-#define	L3_ADDR_SIN6(le)	((struct sockaddr_in6 *) L3_ADDR(le))
 #include <netinet6/in6_var.h>
 #include <netinet6/in6_ifattach.h>
 #include <netinet/ip6.h>
@@ -898,7 +897,7 @@ nd6_na_input(struct mbuf *m, int off, in
 			struct nd_defrouter *dr;
 			struct in6_addr *in6;
 
-			in6 = &L3_ADDR_SIN6(ln)->sin6_addr;
+			in6 = &ln->r_l3addr.addr6;
 
 			/*
 			 * Lock to protect the default router list.



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