Date: Sun, 23 Nov 2008 18:29:12 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 153400 for review Message-ID: <200811231829.mANITCTu000112@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=153400 Change 153400 by sam@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_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200811231829.mANITCTu000112>