PERFORCE change 153400 for review
Sam Leffler
sam at FreeBSD.org
Sun Nov 23 10:29:13 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=153400
Change 153400 by sam at sam_ebb on 2008/11/23 18:29:01
First pass of mostly style cleanups:
o honor INET and INET6
o fix vimage
o don't panic unless necessary
o add locking assertions (breaks use as lla_lookup is not
properly locked in in_arpinput)
o lock ifnet list walks
o check ptr's against NULL instead of zero
o fix af matching in lltable_drain
o be consistent with return (e) vs return e
o kill trailing whitespace at EOL
Note this compiles but is untested.
Approved by: qingli
Affected files ...
.. //depot/projects/arp-v2/src/sys/net/if_llatbl.c#4 edit
.. //depot/projects/arp-v2/src/sys/net/if_llatbl.h#3 edit
Differences ...
==== //depot/projects/arp-v2/src/sys/net/if_llatbl.c#4 (text+ko) ====
@@ -22,6 +22,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+#include "opt_inet.h"
+#include "opt_inet6.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -32,6 +34,7 @@
#include <sys/socket.h>
#include <sys/kernel.h>
#include <sys/mutex.h>
+#include <sys/vimage.h>
#include <vm/uma.h>
@@ -45,56 +48,63 @@
#include <netinet6/in6_var.h>
#include <netinet6/nd6.h>
-
uma_zone_t llezone;
uma_zone_t lltzone;
-
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 *);
-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 ifnet *ifp, int af, struct llentries *head,
+ struct sysctl_req *wr)
{
struct llentry *lle;
- int error = 0;
- struct rt_msghdr *rtm=NULL;
- struct sockaddr_dl *sdl=NULL;
- uint8_t *msg=NULL;
- int msgsize=0;
-
+ struct rt_msghdr *rtm;
+ struct sockaddr_dl *sdl;
+ uint8_t *msg;
+ int msgsize, error;
+#ifdef INET
struct {
struct rt_msghdr rtm;
struct sockaddr_inarp sin;
struct sockaddr_dl sdl;
} arpc;
-
+#endif
+#ifdef INET6
struct {
struct rt_msghdr rtm;
struct sockaddr_in6 sin6;
struct sockaddr_dl sdl;
} ndpc;
+#endif
- if (af == AF_INET) {
+ switch (af) {
+#ifdef INET
+ case AF_INET:
rtm = &arpc.rtm;
sdl = &arpc.sdl;
msgsize = sizeof(arpc);
msg = (uint8_t *)&arpc;
- }
- else if (af == AF_INET6) {
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
rtm = &ndpc.rtm;
sdl = &ndpc.sdl;
msgsize = sizeof(ndpc);
msg = (uint8_t *)&ndpc;
+ break;
+#endif
+ default:
+ printf("%s: unknown address family", __func__);
+ return EINVAL;
}
- else
- panic("%s: unknown address family", __func__);
+
+ IF_LLTBLS_LOCK_ASSERT(ifp);
+ error = 0;
LIST_FOREACH(lle, head, lle_next) {
if (lle->la_flags & LLE_DELETED) /* skip deleted entries */
continue;
@@ -106,22 +116,28 @@
*/
bzero(msg, msgsize);
rtm->rtm_msglen = msgsize;
- if (af == AF_INET) {
+ 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;
- }
- else if (af == AF_INET6) {
+ 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;
+#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;
+ if ((af == AF_INET) && (lle->la_flags & LLE_PROXY))
+ arpc.sin.sin_other = SIN_PROXY;
}
if (lle->la_flags & LLE_VALID) { /* valid MAC */
@@ -145,7 +161,6 @@
return error;
}
-
/*
* glue to dump arp tables
*/
@@ -154,16 +169,17 @@
{
struct lltable *llt;
struct ifnet *ifp;
- register int i;
- int error = 0;
+ int i, error = 0;
- TAILQ_FOREACH(ifp, &ifnet, if_link) {
+ 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);
+ 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;
@@ -173,102 +189,112 @@
IF_LLTBLS_UNLOCK(ifp);
}
done:
- return (error);
+ IFNET_RUNLOCK();
+ return error;
}
-
/*
* delete an address from the address table
*/
-int llentry_free(struct llentry *lle)
+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);
IF_LLE_LOCK_DESTROY(lle);
- if (lle->la_hold)
+ if (lle->la_hold != NULL)
m_freem(lle->la_hold);
uma_zfree(llezone, lle);
return 0;
}
-
/*
* delete an address table from the interface ifp
*/
-int lltable_free(struct ifnet *ifp, int af)
+int
+lltable_free(struct ifnet *ifp, int af)
{
struct lltable *llt;
struct llentry *lle;
- register int i;
+ int i;
+
+ KASSERT(ifp != NULL, ("null ifp"));
- KASSERT(ifp != NULL, ("%s: ifp is NULL", __func__));
+ IF_LLTBLS_LOCK_ASSERT(ifp);
- TAILQ_FOREACH(llt, &ifp->if_lltables, llt_link)
+ 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);
- TAILQ_REMOVE(&ifp->if_lltables, llt, llt_link);
- uma_zfree(lltzone, llt);
+ for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
+ LIST_FOREACH(lle, &llt->lle_head[i], lle_next)
+ llentry_free(lle);
+ }
+ TAILQ_REMOVE(&ifp->if_lltables, llt, llt_link);
+ uma_zfree(lltzone, llt);
+ break;
+ }
return 0;
}
-
-void lltable_drain(int af)
+void
+lltable_drain(int af)
{
struct ifnet *ifp;
struct lltable *llt = NULL;
struct llentry *lle;
- register int i;
+ int i;
TAILQ_FOREACH(ifp, &ifnet, if_link) {
IF_LLTBLS_LOCK(ifp);
TAILQ_FOREACH(llt, &ifp->if_lltables, llt_link) {
- if (llt->llt_af != af) {
- IF_LLTBLS_UNLOCK(ifp);
+ 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;
+ }
+ }
}
+ break;
}
-
- 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;
- }
- }
IF_LLTBLS_LOCK(ifp);
}
}
-
/*
- * Add a new table at the head of the list for interface ifp
+ * Add a new table at the head of the list for interface ifp
*/
static struct lltable *
lltable_new(struct ifnet *ifp, int af)
{
struct lltable *llt;
- register int i;
+ int i;
+ /* XXX can this happen? */
if (ifp == NULL)
- return (NULL);
+ return NULL;
llt = uma_zalloc(lltzone, M_DONTWAIT | M_ZERO);
- if (llt != NULL) {
- llt->llt_af = af;
- llt->llt_ifp = ifp;
- TAILQ_INSERT_HEAD(&ifp->if_lltables, llt, llt_link);
- for (i=0; i < LLTBL_HASHTBL_SIZE; i++)
- LIST_INIT(&llt->lle_head[i]);
+ if (llt == NULL) {
+ log(LOG_INFO, "lltable_new: malloc failed for new lla-table\n");
+ return NULL;
}
- else
- log(LOG_INFO, "lltable_new: malloc failed for new lla-table\n");
- return (llt);
+ 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);
+
+ return llt;
}
-
/*
* Generic link layer address lookup function, replacement
* of the old "arplookup"
@@ -276,35 +302,40 @@
struct llentry *
lla_lookup(struct ifnet *ifp, u_int flags, struct sockaddr *l3addr)
{
- struct llentry *lle;
+ struct llentry *lle;
struct llentries *lleh;
- struct lltable *llt;
- struct rtentry *rt;
+ struct lltable *llt;
+ struct rtentry *rt;
u_int hashkey;
#ifdef INET6
char ip6buf[INET6_ADDRSTRLEN];
#endif
- KASSERT(ifp != NULL, ("%s: ifp is NULL", __func__));
- KASSERT(l3addr != NULL, ("%s: L3 address is NULL", __func__));
+ KASSERT(ifp != NULL, ("null ifp"));
+ KASSERT(l3addr != NULL, ("null L3 address"));
+
+ 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))
+ if ((flags & LLE_CREATE) && llt == NULL) {
llt = lltable_new(ifp, l3addr->sa_family);
- if (llt == NULL)
- return (NULL);
+ if (llt == NULL)
+ return NULL;
+ }
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;
}
@@ -315,37 +346,43 @@
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 a ND6 cache for an IPv6 neighbor
- * that is not covered by our own prefix.
+ * Creating an ND6 cache for an IPv6
+ * neighbor that is not covered by our
+ * own prefix.
*/
- struct ifaddr *ifa =
- ifaof_ifpforaddr((struct sockaddr *)l3addr, ifp);
+ struct ifaddr *ifa = ifaof_ifpforaddr(
+ (struct sockaddr *)l3addr, ifp);
if (ifa != NULL)
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
@@ -360,14 +397,14 @@
lla_lookup_1:
lle = uma_zalloc(llezone, M_DONTWAIT | M_ZERO);
if (lle == NULL) {
- log(LOG_INFO, "lla_lookup: new lle malloc failed\n");
+ log(LOG_INFO, "%s: malloc failed\n", __func__);
return (NULL);
}
IF_LLE_LOCK_INIT(lle);
- callout_init_mtx(&lle->la_timer, &lle->lle_mtx, 0);
+ callout_init_mtx(&lle->la_timer, &ifp->if_lltbls_mtx, 0);
- /* qing
+ /*
* For IPv4 this will trigger "arpresolve" to generate
* an ARP request
*/
@@ -378,9 +415,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);
@@ -391,7 +428,6 @@
return (lle);
}
-
/*
* Called in route_output when adding/deleting a route to an interface.
*/
@@ -404,33 +440,37 @@
struct llentry *lle;
u_int flags = 0;
- if ((dl == NULL) || (dl->sdl_family != AF_LINK)) {
- log(LOG_INFO, "invalid dl in lla_rt_output\n");
+ if (dl == NULL || dl->sdl_family != AF_LINK) {
+ log(LOG_INFO, "%s: invalid dl\n", __func__);
return EINVAL;
}
ifp = ifnet_byindex(dl->sdl_index);
if (ifp == NULL) {
- log(LOG_INFO, "invalid ifp in lla_rt_output\n");
+ log(LOG_INFO, "%s: invalid ifp (sdl_index %d)\n",
+ __func__, dl->sdl_index);
return EINVAL;
}
switch (rtm->rtm_type) {
case RTM_ADD:
if (rtm->rtm_flags & RTF_ANNOUNCE) {
- struct rtentry *rt;
-
flags |= LLE_PUB;
- if ((dst->sa_family == AF_INET) &&
- (((struct sockaddr_inarp *)dst)->sin_other != 0)) {
- flags |= LLE_PROXY;
- rt = rtalloc1(dst, 0, 0);
- if ((rt == NULL) || !(rt->rt_flags & RTF_HOST)) {
- log(LOG_INFO, "lla_rt_output: RTM_ADD publish (proxy only) is invalid\n");
+#ifdef INET
+ if (dst->sa_family == AF_INET &&
+ ((struct sockaddr_inarp *)dst)->sin_other != 0) {
+ struct rtentry *rt = rtalloc1(dst, 0, 0);
+ if (rt == NULL || !(rt->rt_flags & RTF_HOST)) {
+ log(LOG_INFO, "%s: RTM_ADD publish "
+ "(proxy only) is invalid\n",
+ __func__);
rtfree(rt);
return EINVAL;
}
rtfree(rt);
+
+ flags |= LLE_PROXY;
}
+#endif
}
flags |= LLE_CREATE;
break;
@@ -457,29 +497,33 @@
bcopy(LLADDR(dl), &lle->ll_addr, ifp->if_addrlen);
lle->la_flags |= LLE_VALID;
lle->la_flags &= ~LLE_DELETED;
+#ifdef INET6
/*
* ND6
*/
if (dst->sa_family == AF_INET6)
lle->ln_state = ND6_LLINFO_REACHABLE;
+#endif
/*
* "arp" and "ndp" always sets the (RTF_STATIC | RTF_HOST) flags
*/
if (rtm->rtm_rmx.rmx_expire == 0) {
lle->la_flags |= LLE_STATIC;
lle->la_expire = 0;
- }
- else
+ } else
lle->la_expire = rtm->rtm_rmx.rmx_expire;
+#ifdef INET
/* gratuious ARP */
- if (lle->la_flags & LLE_PUB) {
- if (dst->sa_family == AF_INET)
- arprequest(ifp,
- &((struct sockaddr_in *)dst)->sin_addr,
- &((struct sockaddr_in *)dst)->sin_addr,
- ((lle->la_flags & LLE_PROXY) ? (u_char *)IF_LLADDR(ifp) :
- (u_char *)LLADDR(dl)));
+ if ((lle->la_flags & LLE_PUB) &&
+ dst->sa_family == AF_INET) {
+ arprequest(ifp,
+ &((struct sockaddr_in *)dst)->sin_addr,
+ &((struct sockaddr_in *)dst)->sin_addr,
+ ((lle->la_flags & LLE_PROXY) ?
+ (u_char *)IF_LLADDR(ifp) :
+ (u_char *)LLADDR(dl)));
}
+#endif
}
} else {
if (flags & LLE_DELETE) {
@@ -490,5 +534,3 @@
IF_LLTBLS_UNLOCK(ifp);
return 0;
}
-
-
==== //depot/projects/arp-v2/src/sys/net/if_llatbl.h#3 (text+ko) ====
@@ -45,7 +45,7 @@
uint16_t la_asked;
uint16_t la_preempt;
uint16_t ln_byhint;
- int16_t ln_state; /* IPv6 has ND6_LLINFO_NOSTATE == -2 */
+ int16_t ln_state; /* IPv6 has ND6_LLINFO_NOSTATE == -2 */
uint16_t ln_router;
time_t ln_ntick;
union {
@@ -63,18 +63,18 @@
struct mtx lle_mtx; /* mutex for lle entry */
};
-#define ln_timer_ch lle_timer.ln_timer_ch
-#define la_timer lle_timer.la_timer
+#define ln_timer_ch lle_timer.ln_timer_ch
+#define la_timer lle_timer.la_timer
-#define l3_addr4 l3_addr.addr4
-#define l3_addr6 l3_addr.addr6
+#define l3_addr4 l3_addr.addr4
+#define l3_addr6 l3_addr.addr6
#ifndef LLTBL_HASHTBL_SIZE
-#define LLTBL_HASHTBL_SIZE 32 /* default 32 ? */
+#define LLTBL_HASHTBL_SIZE 32 /* default 32 ? */
#endif
#ifndef LLTBL_HASHMASK
-#define LLTBL_HASHMASK (LLTBL_HASHTBL_SIZE - 1)
+#define LLTBL_HASHMASK (LLTBL_HASHTBL_SIZE - 1)
#endif
struct lltable {
@@ -87,29 +87,28 @@
/*
* flags to be passed to arplookup.
*/
-#define LLE_DELETED 0x0001 /* entry must be deleted */
-#define LLE_STATIC 0x0002 /* entry is static */
-#define LLE_IFADDR 0x0004 /* entry is interface addr */
-#define LLE_VALID 0x0008 /* ll_addr is valid */
-#define LLE_PROXY 0x0010 /* proxy entry ??? */
-#define LLE_PUB 0x0020 /* publish entry ??? */
-#define LLE_CREATE 0x8000 /* create on a lookup miss */
-#define LLE_DELETE 0x4000 /* delete on a lookup - match LLE_IFADDR */
+#define LLE_DELETED 0x0001 /* entry must be deleted */
+#define LLE_STATIC 0x0002 /* entry is static */
+#define LLE_IFADDR 0x0004 /* entry is interface addr */
+#define LLE_VALID 0x0008 /* ll_addr is valid */
+#define LLE_PROXY 0x0010 /* proxy entry ??? */
+#define LLE_PUB 0x0020 /* publish entry ??? */
+#define LLE_CREATE 0x8000 /* create on a lookup miss */
+#define LLE_DELETE 0x4000 /* delete on a lookup - match LLE_IFADDR */
-#define LLATBL_HASH(key, mask) (((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask)
+#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_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)
-extern struct llentry *lla_lookup(struct ifnet *ifp, u_int flags, struct sockaddr *l3addr);
-extern int lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info);
-extern int llentry_free(struct llentry *lle);
-extern int lltable_free(struct ifnet *ifp, int af);
-extern void lltable_drain(int af);
-
-#endif
-
-
+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_ */
More information about the p4-projects
mailing list