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