Date: Thu, 4 Dec 2008 02:23:02 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r185598 - in user/kmacy/head_arpv2: lib/libstand sys/conf sys/contrib/rdma sys/dev/cxgb/ulp/tom sys/net sys/netinet sys/netinet6 usr.sbin/arp usr.sbin/ndp Message-ID: <200812040223.mB42N2UU007804@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kmacy Date: Thu Dec 4 02:23:01 2008 New Revision: 185598 URL: http://svn.freebsd.org/changeset/base/185598 Log: Integrate arp-v2 patch along with a few compile fixes Added: user/kmacy/head_arpv2/sys/net/if_llatbl.c (contents, props changed) user/kmacy/head_arpv2/sys/net/if_llatbl.h (contents, props changed) Modified: user/kmacy/head_arpv2/lib/libstand/if_ether.h user/kmacy/head_arpv2/sys/conf/files user/kmacy/head_arpv2/sys/contrib/rdma/rdma_addr.c user/kmacy/head_arpv2/sys/dev/cxgb/ulp/tom/cxgb_l2t.c user/kmacy/head_arpv2/sys/net/if.c user/kmacy/head_arpv2/sys/net/if_arcsubr.c user/kmacy/head_arpv2/sys/net/if_ethersubr.c user/kmacy/head_arpv2/sys/net/if_fddisubr.c user/kmacy/head_arpv2/sys/net/if_fwsubr.c user/kmacy/head_arpv2/sys/net/if_iso88025subr.c user/kmacy/head_arpv2/sys/net/if_var.h user/kmacy/head_arpv2/sys/net/route.c user/kmacy/head_arpv2/sys/net/rtsock.c user/kmacy/head_arpv2/sys/netinet/if_ether.c user/kmacy/head_arpv2/sys/netinet/if_ether.h user/kmacy/head_arpv2/sys/netinet/in.c user/kmacy/head_arpv2/sys/netinet/in_proto.c user/kmacy/head_arpv2/sys/netinet/in_var.h user/kmacy/head_arpv2/sys/netinet/ip_output.c user/kmacy/head_arpv2/sys/netinet6/icmp6.c user/kmacy/head_arpv2/sys/netinet6/in6.c user/kmacy/head_arpv2/sys/netinet6/in6_var.h user/kmacy/head_arpv2/sys/netinet6/ip6_forward.c user/kmacy/head_arpv2/sys/netinet6/ip6_input.c user/kmacy/head_arpv2/sys/netinet6/ip6_mroute.c user/kmacy/head_arpv2/sys/netinet6/ip6_output.c user/kmacy/head_arpv2/sys/netinet6/nd6.c user/kmacy/head_arpv2/sys/netinet6/nd6.h user/kmacy/head_arpv2/sys/netinet6/nd6_nbr.c user/kmacy/head_arpv2/sys/netinet6/nd6_rtr.c user/kmacy/head_arpv2/sys/netinet6/vinet6.h user/kmacy/head_arpv2/usr.sbin/arp/arp.c user/kmacy/head_arpv2/usr.sbin/ndp/ndp.c Modified: user/kmacy/head_arpv2/lib/libstand/if_ether.h ============================================================================== --- user/kmacy/head_arpv2/lib/libstand/if_ether.h Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/lib/libstand/if_ether.h Thu Dec 4 02:23:01 2008 (r185598) @@ -156,7 +156,7 @@ struct ifqueue arpintrq; void arpwhohas(struct arpcom *, struct in_addr *); void arpintr(void); int arpresolve(struct arpcom *, - struct rtentry *, struct mbuf *, struct sockaddr *, u_char *); + struct rtentry *, struct mbuf *, struct sockaddr *, u_char *, struct llentry **); void arp_ifinit(struct arpcom *, struct ifaddr *); void arp_rtrequest(int, struct rtentry *, struct sockaddr *); @@ -233,7 +233,7 @@ struct ether_multistep { #ifdef _KERNEL void arp_rtrequest(int, struct rtentry *, struct sockaddr *); int arpresolve(struct arpcom *, struct rtentry *, struct mbuf *, - struct sockaddr *, u_char *); + struct sockaddr *, u_char *, struct llentry **); void arpintr(void); int arpioctl(u_long, caddr_t); void arp_ifinit(struct arpcom *, struct ifaddr *); Modified: user/kmacy/head_arpv2/sys/conf/files ============================================================================== --- user/kmacy/head_arpv2/sys/conf/files Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/conf/files Thu Dec 4 02:23:01 2008 (r185598) @@ -2171,6 +2171,7 @@ net/if_gre.c optional gre net/if_iso88025subr.c optional token net/if_lagg.c optional lagg net/if_loop.c optional loop +net/if_llatbl.c standard net/if_media.c standard net/if_mib.c standard net/if_ppp.c optional ppp Modified: user/kmacy/head_arpv2/sys/contrib/rdma/rdma_addr.c ============================================================================== --- user/kmacy/head_arpv2/sys/contrib/rdma/rdma_addr.c Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/contrib/rdma/rdma_addr.c Thu Dec 4 02:23:01 2008 (r185598) @@ -163,6 +163,7 @@ static void addr_send_arp(struct sockadd struct route iproute; struct sockaddr_in *dst = (struct sockaddr_in *)&iproute.ro_dst; char dmac[ETHER_ADDR_LEN]; + struct llentry *lle; bzero(&iproute, sizeof iproute); *dst = *dst_in; @@ -172,7 +173,7 @@ static void addr_send_arp(struct sockadd return; arpresolve(iproute.ro_rt->rt_ifp, iproute.ro_rt, NULL, - rt_key(iproute.ro_rt), dmac); + rt_key(iproute.ro_rt), dmac, &lle); RTFREE(iproute.ro_rt); } @@ -186,6 +187,7 @@ static int addr_resolve_remote(struct so struct route iproute; struct sockaddr_in *dst = (struct sockaddr_in *)&iproute.ro_dst; char dmac[ETHER_ADDR_LEN]; + struct llentry *lle; bzero(&iproute, sizeof iproute); *dst = *dst_in; @@ -202,7 +204,7 @@ static int addr_resolve_remote(struct so goto put; } ret = arpresolve(iproute.ro_rt->rt_ifp, iproute.ro_rt, NULL, - rt_key(iproute.ro_rt), dmac); + rt_key(iproute.ro_rt), dmac, &lle); if (ret) { goto put; } Modified: user/kmacy/head_arpv2/sys/dev/cxgb/ulp/tom/cxgb_l2t.c ============================================================================== --- user/kmacy/head_arpv2/sys/dev/cxgb/ulp/tom/cxgb_l2t.c Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/dev/cxgb/ulp/tom/cxgb_l2t.c Thu Dec 4 02:23:01 2008 (r185598) @@ -166,6 +166,7 @@ t3_l2t_send_slow(struct t3cdev *dev, str { struct rtentry *rt = e->neigh; struct sockaddr_in sin; + struct llentry *lle; bzero(&sin, sizeof(struct sockaddr_in)); sin.sin_family = AF_INET; @@ -177,7 +178,7 @@ again: switch (e->state) { case L2T_STATE_STALE: /* entry is stale, kick off revalidation */ arpresolve(rt->rt_ifp, rt, NULL, - (struct sockaddr *)&sin, e->dmac); + (struct sockaddr *)&sin, e->dmac, &lle); mtx_lock(&e->lock); if (e->state == L2T_STATE_STALE) e->state = L2T_STATE_VALID; @@ -201,7 +202,7 @@ again: * entries when there's no memory. */ if (arpresolve(rt->rt_ifp, rt, NULL, - (struct sockaddr *)&sin, e->dmac) == 0) { + (struct sockaddr *)&sin, e->dmac, &lle) == 0) { CTR6(KTR_CXGB, "mac=%x:%x:%x:%x:%x:%x\n", e->dmac[0], e->dmac[1], e->dmac[2], e->dmac[3], e->dmac[4], e->dmac[5]); @@ -228,6 +229,7 @@ t3_l2t_send_event(struct t3cdev *dev, st sin.sin_family = AF_INET; sin.sin_len = sizeof(struct sockaddr_in); sin.sin_addr.s_addr = e->addr; + struct llentry *lle; if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL) return; @@ -237,7 +239,7 @@ again: switch (e->state) { case L2T_STATE_STALE: /* entry is stale, kick off revalidation */ arpresolve(rt->rt_ifp, rt, NULL, - (struct sockaddr *)&sin, e->dmac); + (struct sockaddr *)&sin, e->dmac, &lle); mtx_lock(&e->lock); if (e->state == L2T_STATE_STALE) { e->state = L2T_STATE_VALID; @@ -263,7 +265,7 @@ again: * entries when there's no memory. */ arpresolve(rt->rt_ifp, rt, NULL, - (struct sockaddr *)&sin, e->dmac); + (struct sockaddr *)&sin, e->dmac, &lle); } return; Modified: user/kmacy/head_arpv2/sys/net/if.c ============================================================================== --- user/kmacy/head_arpv2/sys/net/if.c Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/net/if.c Thu Dec 4 02:23:01 2008 (r185598) @@ -58,6 +58,7 @@ #include <sys/jail.h> #include <sys/vimage.h> #include <machine/stdarg.h> +#include <vm/uma.h> #include <net/if.h> #include <net/if_arp.h> @@ -1342,6 +1343,7 @@ done: } #include <net/route.h> +#include <net/if_llatbl.h> /* * Default action when installing a route with a Link Level gateway. Modified: user/kmacy/head_arpv2/sys/net/if_arcsubr.c ============================================================================== --- user/kmacy/head_arpv2/sys/net/if_arcsubr.c Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/net/if_arcsubr.c Thu Dec 4 02:23:01 2008 (r185598) @@ -64,6 +64,7 @@ #include <net/if_arc.h> #include <net/if_arp.h> #include <net/bpf.h> +#include <net/if_llatbl.h> #if defined(INET) || defined(INET6) #include <netinet/in.h> @@ -108,6 +109,7 @@ arc_output(struct ifnet *ifp, struct mbu u_int8_t atype, adst; int loop_copy = 0; int isphds; + struct llentry *lle; if (!((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))) @@ -127,7 +129,7 @@ arc_output(struct ifnet *ifp, struct mbu else if (ifp->if_flags & IFF_NOARP) adst = ntohl(SIN(dst)->sin_addr.s_addr) & 0xFF; else { - error = arpresolve(ifp, rt0, m, dst, &adst); + error = arpresolve(ifp, rt0, m, dst, &adst, &lle); if (error) return (error == EWOULDBLOCK ? 0 : error); } @@ -165,7 +167,7 @@ arc_output(struct ifnet *ifp, struct mbu #endif #ifdef INET6 case AF_INET6: - error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)&adst); + error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)&adst, &lle); if (error) return (error); atype = ARCTYPE_INET6; Modified: user/kmacy/head_arpv2/sys/net/if_ethersubr.c ============================================================================== --- user/kmacy/head_arpv2/sys/net/if_ethersubr.c Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/net/if_ethersubr.c Thu Dec 4 02:23:01 2008 (r185598) @@ -62,6 +62,7 @@ #include <net/ethernet.h> #include <net/if_bridgevar.h> #include <net/if_vlan_var.h> +#include <net/if_llatbl.h> #include <net/pf_mtag.h> #include <net/vnet.h> @@ -148,6 +149,8 @@ static int ether_ipfw; #endif #endif +extern int useloopback; + /* * Ethernet output routine. * Encapsulate a packet of type family for the local net. @@ -161,6 +164,7 @@ ether_output(struct ifnet *ifp, struct m short type; int error, hdrcmplt = 0; u_char esrc[ETHER_ADDR_LEN], edst[ETHER_ADDR_LEN]; + struct llentry *lle = NULL; struct ether_header *eh; struct pf_mtag *t; int loop_copy = 1; @@ -183,7 +187,7 @@ ether_output(struct ifnet *ifp, struct m switch (dst->sa_family) { #ifdef INET case AF_INET: - error = arpresolve(ifp, rt0, m, dst, edst); + error = arpresolve(ifp, rt0, m, dst, edst, &lle); if (error) return (error == EWOULDBLOCK ? 0 : error); type = htons(ETHERTYPE_IP); @@ -218,7 +222,7 @@ ether_output(struct ifnet *ifp, struct m #endif #ifdef INET6 case AF_INET6: - error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst); + error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst, &lle); if (error) return error; type = htons(ETHERTYPE_IPV6); @@ -286,6 +290,9 @@ ether_output(struct ifnet *ifp, struct m senderr(EAFNOSUPPORT); } + if (lle && (lle->la_flags & LLE_IFADDR) && useloopback) + return (if_simloop(ifp, m, dst->sa_family, 0)); + /* * Add local net header. If no space in first mbuf, * allocate another. Modified: user/kmacy/head_arpv2/sys/net/if_fddisubr.c ============================================================================== --- user/kmacy/head_arpv2/sys/net/if_fddisubr.c Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/net/if_fddisubr.c Thu Dec 4 02:23:01 2008 (r185598) @@ -55,6 +55,7 @@ #include <net/if_dl.h> #include <net/if_llc.h> #include <net/if_types.h> +#include <net/if_llatbl.h> #include <net/ethernet.h> #include <net/netisr.h> @@ -120,6 +121,7 @@ fddi_output(ifp, m, dst, rt0) int loop_copy = 0, error = 0, hdrcmplt = 0; u_char esrc[FDDI_ADDR_LEN], edst[FDDI_ADDR_LEN]; struct fddi_header *fh; + struct llentry *lle; #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); @@ -137,7 +139,7 @@ fddi_output(ifp, m, dst, rt0) switch (dst->sa_family) { #ifdef INET case AF_INET: { - error = arpresolve(ifp, rt0, m, dst, edst); + error = arpresolve(ifp, rt0, m, dst, edst, &lle); if (error) return (error == EWOULDBLOCK ? 0 : error); type = htons(ETHERTYPE_IP); @@ -173,7 +175,7 @@ fddi_output(ifp, m, dst, rt0) #endif /* INET */ #ifdef INET6 case AF_INET6: - error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst); + error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst, &lle); if (error) return (error); /* Something bad happened */ type = htons(ETHERTYPE_IPV6); Modified: user/kmacy/head_arpv2/sys/net/if_fwsubr.c ============================================================================== --- user/kmacy/head_arpv2/sys/net/if_fwsubr.c Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/net/if_fwsubr.c Thu Dec 4 02:23:01 2008 (r185598) @@ -51,6 +51,7 @@ #include <net/if_types.h> #include <net/bpf.h> #include <net/firewire.h> +#include <net/if_llatbl.h> #if defined(INET) || defined(INET6) #include <netinet/in.h> @@ -89,6 +90,7 @@ firewire_output(struct ifnet *ifp, struc struct mbuf *mtail; int unicast, dgl, foff; static int next_dgl; + struct llentry *lle; #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); @@ -144,7 +146,7 @@ firewire_output(struct ifnet *ifp, struc * doesn't fit into the arp model. */ if (unicast) { - error = arpresolve(ifp, rt, m, dst, (u_char *) destfw); + error = arpresolve(ifp, rt, m, dst, (u_char *) destfw, &lle); if (error) return (error == EWOULDBLOCK ? 0 : error); } @@ -174,7 +176,7 @@ firewire_output(struct ifnet *ifp, struc case AF_INET6: if (unicast) { error = nd6_storelladdr(fc->fc_ifp, rt, m, dst, - (u_char *) destfw); + (u_char *) destfw, &lle); if (error) return (error); } Modified: user/kmacy/head_arpv2/sys/net/if_iso88025subr.c ============================================================================== --- user/kmacy/head_arpv2/sys/net/if_iso88025subr.c Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/net/if_iso88025subr.c Thu Dec 4 02:23:01 2008 (r185598) @@ -59,6 +59,7 @@ #include <net/if_dl.h> #include <net/if_llc.h> #include <net/if_types.h> +#include <net/if_llatbl.h> #include <net/ethernet.h> #include <net/netisr.h> @@ -244,6 +245,7 @@ iso88025_output(ifp, m, dst, rt0) struct iso88025_header gen_th; struct sockaddr_dl *sdl = NULL; struct rtentry *rt = NULL; + struct llentry *lle; #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); @@ -289,7 +291,7 @@ iso88025_output(ifp, m, dst, rt0) switch (dst->sa_family) { #ifdef INET case AF_INET: - error = arpresolve(ifp, rt0, m, dst, edst); + error = arpresolve(ifp, rt0, m, dst, edst, &lle); if (error) return (error == EWOULDBLOCK ? 0 : error); snap_type = ETHERTYPE_IP; @@ -324,7 +326,7 @@ iso88025_output(ifp, m, dst, rt0) #endif /* INET */ #ifdef INET6 case AF_INET6: - error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst); + error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst, &lle); if (error) return (error); snap_type = ETHERTYPE_IPV6; Added: user/kmacy/head_arpv2/sys/net/if_llatbl.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/kmacy/head_arpv2/sys/net/if_llatbl.c Thu Dec 4 02:23:01 2008 (r185598) @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2007 Qing Li, Luigi Rizzo, Alessandro Cerri. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * 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" + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/malloc.h> +#include <sys/mbuf.h> +#include <sys/syslog.h> +#include <sys/sysctl.h> +#include <sys/socket.h> +#include <sys/kernel.h> +#include <sys/mutex.h> +#include <sys/vimage.h> + +#include <vm/uma.h> + +#include <netinet/in.h> +#include <net/if_llatbl.h> +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_var.h> +#include <net/route.h> +#include <netinet/if_ether.h> +#include <netinet6/in6_var.h> +#include <netinet6/nd6.h> + +MALLOC_DEFINE(M_LLTABLE, "lltable", "link level address tables"); + +static SLIST_HEAD(, lltable) lltables = SLIST_HEAD_INITIALIZER(lltables); + +extern void arprequest(struct ifnet *, struct in_addr *, struct in_addr *, + u_char *); + +/* + * Dump arp state for a specific address family. + */ +int +lltable_sysctl_dumparp(int af, struct sysctl_req *wr) +{ + struct lltable *llt; + int error = 0; + + IFNET_RLOCK(); + SLIST_FOREACH(llt, &lltables, llt_link) { + if (llt->llt_af == af) { + error = llt->llt_dump(llt, wr); + if (error != 0) + goto done; + } + } +done: + IFNET_RUNLOCK(); + return (error); +} + +/* + * 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. + */ +void +llentry_free(struct llentry *lle) +{ + struct lltable *llt = lle->lle_tbl; + + LIST_REMOVE(lle, lle_next); + + if (lle->la_hold != NULL) + m_freem(lle->la_hold); + llt->llt_free(llt, lle); +} + +/* + * 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(). + */ +void +lltable_free(struct lltable *llt) +{ + struct llentry *lle, *next; + int i; + + KASSERT(llt != NULL, ("%s: llt is NULL", __func__)); + + IFNET_WLOCK(); + SLIST_REMOVE(&lltables, llt, lltable, llt_link); + IFNET_WUNLOCK(); + + for (i=0; i < LLTBL_HASHTBL_SIZE; i++) { + LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) { + callout_drain(&lle->la_timer); + llentry_free(lle); + } + } + + free(llt, M_LLTABLE); +} + +void +lltable_drain(int af) +{ + struct lltable *llt; + struct llentry *lle; + register int i; + + IFNET_RLOCK(); + SLIST_FOREACH(llt, &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) { + m_freem(lle->la_hold); + lle->la_hold = NULL; + } + } + } + } + IFNET_RUNLOCK(); +} + +/* + * Create a new lltable. + */ +struct lltable * +lltable_init(struct ifnet *ifp, int af) +{ + struct lltable *llt; + register int i; + + llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK); + if (llt == NULL) + return (NULL); + + llt->llt_af = af; + llt->llt_ifp = ifp; + for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) + LIST_INIT(&llt->lle_head[i]); + + IFNET_WLOCK(); + SLIST_INSERT_HEAD(&lltables, llt, llt_link); + IFNET_WUNLOCK(); + + return (llt); +} + +/* + * Called in route_output when adding/deleting a route to an interface. + */ +int +lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info) +{ + 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; + + 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, "%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) { + flags |= LLE_PUB; +#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; + + case RTM_DELETE: + flags |= LLE_DELETE; + break; + + case RTM_CHANGE: + break; + + default: + return EINVAL; /* XXX not implemented yet */ + } + + /* + * XXXXXXXX: + * REVISE this approach if possible. + */ + 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 + * "arp add" on the same host should look up this entry, + * reset the LLE_DELETED flag, and reset the expiration timer + */ + 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 + lle->la_expire = rtm->rtm_rmx.rmx_expire; +#ifdef INET + /* gratuious ARP */ + 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) { + IF_AFDATA_UNLOCK(ifp); + return EINVAL; + } + } + + IF_AFDATA_UNLOCK(ifp); + return 0; +} Added: user/kmacy/head_arpv2/sys/net/if_llatbl.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/kmacy/head_arpv2/sys/net/if_llatbl.h Thu Dec 4 02:23:01 2008 (r185598) @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2007 Qing Li, Luigi Rizzo, Alessandro Cerri. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * 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_ + +#include <netinet/in.h> + +struct ifnet; +struct sysctl_req; +struct rt_msghdr; +struct rt_addrinfo; + +struct llentry; +LIST_HEAD(llentries, llentry); + +struct llentry { + LIST_ENTRY(llentry) lle_next; + struct lltable *lle_tbl; + struct llentries *lle_head; + struct mbuf *la_hold; + time_t la_expire; + uint16_t la_flags; + uint16_t la_asked; + uint16_t la_preempt; + uint16_t ln_byhint; + int16_t ln_state; /* IPv6 has ND6_LLINFO_NOSTATE == -2 */ + uint16_t ln_router; + time_t ln_ntick; + union { + uint64_t mac_aligned; + uint16_t mac16[3]; + } ll_addr; + + /* XXX af-private? */ + union { + struct callout ln_timer_ch; + struct callout la_timer; + } lle_timer; + /* NB: struct sockaddr must immediately follow */ +}; + +#define ln_timer_ch lle_timer.ln_timer_ch +#define la_timer lle_timer.la_timer + +/* XXX bad name */ +#define L3_ADDR(lle) ((struct sockaddr *)(&lle[1])) +#define L3_ADDR_LEN(lle) (((struct sockaddr *)(&lle[1]))->sa_len) + +#ifndef LLTBL_HASHTBL_SIZE +#define LLTBL_HASHTBL_SIZE 32 /* default 32 ? */ +#endif + +#ifndef LLTBL_HASHMASK +#define LLTBL_HASHMASK (LLTBL_HASHTBL_SIZE - 1) +#endif + +struct lltable { + SLIST_ENTRY(lltable) llt_link; + struct llentries lle_head[LLTBL_HASHTBL_SIZE]; + int llt_af; + struct ifnet *llt_ifp; + + struct llentry * (*llt_new)(const struct sockaddr *, u_int); + void (*llt_free)(struct lltable *, struct llentry *); + struct llentry * (*llt_lookup)(struct lltable *, u_int flags, + const struct sockaddr *l3addr); + int (*llt_rtcheck)(struct ifnet *, + const struct sockaddr *); + int (*llt_dump)(struct lltable *, + struct sysctl_req *); +}; +MALLOC_DECLARE(M_LLTABLE); + +/* + * 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 LLATBL_HASH(key, mask) \ + (((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask) + +struct lltable *lltable_init(struct ifnet *, int); +void lltable_free(struct lltable *); +void lltable_drain(int); +int lltable_sysctl_dumparp(int, struct sysctl_req *); + +void llentry_free(struct llentry *); + +/* + * Generic link layer address lookup function. + */ +static __inline struct llentry * +lla_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr) +{ + return llt->llt_lookup(llt, flags, l3addr); +} + +int lla_rt_output(struct rt_msghdr *, struct rt_addrinfo *); +#endif /* _NET_IF_LLATBL_H_ */ Modified: user/kmacy/head_arpv2/sys/net/if_var.h ============================================================================== --- user/kmacy/head_arpv2/sys/net/if_var.h Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/net/if_var.h Thu Dec 4 02:23:01 2008 (r185598) @@ -68,6 +68,7 @@ struct rtentry; struct rt_addrinfo; struct socket; struct ether_header; +struct lltable; struct carp_if; struct ifvlantrunk; #endif @@ -169,8 +170,6 @@ struct ifnet { void *if_bridge; /* bridge glue */ - struct lltable *lltables; /* list of L3-L2 resolution tables */ - struct label *if_label; /* interface MAC label */ /* these are only used by IPv6 */ @@ -181,6 +180,7 @@ struct ifnet { 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 */ + 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 */ @@ -359,7 +359,8 @@ typedef void (*group_change_event_handle 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) Modified: user/kmacy/head_arpv2/sys/net/route.c ============================================================================== --- user/kmacy/head_arpv2/sys/net/route.c Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/net/route.c Thu Dec 4 02:23:01 2008 (r185598) @@ -41,6 +41,7 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/syslog.h> #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/socket.h> @@ -52,6 +53,7 @@ #include <sys/vimage.h> #include <net/if.h> +#include <net/if_dl.h> #include <net/route.h> #ifdef RADIX_MPATH @@ -383,7 +385,7 @@ rtfree(struct rtentry *rt) */ RT_REMREF(rt); if (rt->rt_refcnt > 0) { - printf("%s: %p has %lu refs\n", __func__, rt, rt->rt_refcnt); + log(LOG_DEBUG, "%s: %p has %lu refs\t", __func__, rt, rt->rt_refcnt); goto done; } @@ -1452,6 +1454,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int char tempbuf[_SOCKADDR_TMPSIZE]; int didwork = 0; int a_failure = 0; + static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK}; if (flags & RTF_HOST) { dst = ifa->ifa_dstaddr; @@ -1556,7 +1559,14 @@ rtinit1(struct ifaddr *ifa, int cmd, int info.rti_ifa = ifa; info.rti_flags = flags | ifa->ifa_flags; info.rti_info[RTAX_DST] = dst; - info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; + /* + * doing this for compatibility reasons + */ + if (cmd == RTM_ADD) + info.rti_info[RTAX_GATEWAY] = + (struct sockaddr *)&null_sdl; + else + info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; info.rti_info[RTAX_NETMASK] = netmask; error = rtrequest1_fib(cmd, &info, &rt, fibnum); if (error == 0 && rt != NULL) { @@ -1580,6 +1590,15 @@ rtinit1(struct ifaddr *ifa, int cmd, int rt->rt_ifa = ifa; } #endif + /* + * doing this for compatibility reasons + */ + if (cmd == RTM_ADD) { + ((struct sockaddr_dl *)rt->rt_gateway)->sdl_type = + rt->rt_ifp->if_type; + ((struct sockaddr_dl *)rt->rt_gateway)->sdl_index = + rt->rt_ifp->if_index; + } rt_newaddrmsg(cmd, ifa, error, rt); if (cmd == RTM_DELETE) { /* Modified: user/kmacy/head_arpv2/sys/net/rtsock.c ============================================================================== --- user/kmacy/head_arpv2/sys/net/rtsock.c Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/net/rtsock.c Thu Dec 4 02:23:01 2008 (r185598) @@ -51,6 +51,7 @@ #include <sys/vimage.h> #include <net/if.h> +#include <net/if_llatbl.h> #include <net/netisr.h> #include <net/raw_cb.h> #include <net/route.h> @@ -524,6 +525,11 @@ route_output(struct mbuf *m, struct sock if (info.rti_info[RTAX_GATEWAY] == NULL) senderr(EINVAL); saved_nrt = NULL; + /* support for new ARP code */ + if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) { + error = lla_rt_output(rtm, &info); + break; + } error = rtrequest1_fib(RTM_ADD, &info, &saved_nrt, so->so_fibnum); if (error == 0 && saved_nrt) { @@ -539,6 +545,12 @@ route_output(struct mbuf *m, struct sock case RTM_DELETE: saved_nrt = NULL; + /* support for new ARP code */ + if (info.rti_info[RTAX_GATEWAY] && + (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK)) { + error = lla_rt_output(rtm, &info); + break; + } error = rtrequest1_fib(RTM_DELETE, &info, &saved_nrt, so->so_fibnum); if (error == 0) { @@ -1430,6 +1442,11 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS) RADIX_NODE_HEAD_UNLOCK(rnh); } else if (af != 0) error = EAFNOSUPPORT; + /* + * take care of llinfo entries + */ + if (w.w_op == NET_RT_FLAGS && (RTF_LLINFO & w.w_arg)) + error = lltable_sysctl_dumparp(af, w.w_req); break; case NET_RT_IFLIST: Modified: user/kmacy/head_arpv2/sys/netinet/if_ether.c ============================================================================== --- user/kmacy/head_arpv2/sys/netinet/if_ether.c Thu Dec 4 02:16:53 2008 (r185597) +++ user/kmacy/head_arpv2/sys/netinet/if_ether.c Thu Dec 4 02:23:01 2008 (r185598) @@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$"); #include <netinet/in.h> #include <netinet/in_var.h> +#include <net/if_llatbl.h> #include <netinet/if_ether.h> #include <netinet/vinet.h> @@ -79,6 +80,7 @@ __FBSDID("$FreeBSD$"); #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, ""); @@ -87,7 +89,7 @@ SYSCTL_NODE(_net_link_ether, PF_INET, in #ifdef VIMAGE_GLOBALS static int arpt_keep; /* once resolved, good for 20 more minutes */ static int arp_maxtries; -static int useloopback; /* use loopback interface for local traffic */ +int useloopback; /* use loopback interface for local traffic */ static int arp_proxyall; #endif @@ -96,14 +98,6 @@ SYSCTL_V_INT(V_NET, vnet_inet, _net_link #define rt_expire rt_rmx.rmx_expire -struct llinfo_arp { - struct callout la_timer; - struct rtentry *la_rt; - struct mbuf *la_hold; /* last packet until resolved/timeout */ - u_short la_preempt; /* countdown for pre-expiry arps */ - u_short la_asked; /* # requests sent */ -}; - static struct ifqueue arpintrq; SYSCTL_V_INT(V_NET, vnet_inet, _net_link_ether_inet, OID_AUTO, maxtries, @@ -117,212 +111,104 @@ SYSCTL_V_INT(V_NET, vnet_inet, _net_link "Enable proxy ARP for all suitable requests"); static void arp_init(void); -static void arp_rtrequest(int, struct rtentry *, struct rt_addrinfo *); -static void arprequest(struct ifnet *, +void arprequest(struct ifnet *, struct in_addr *, struct in_addr *, u_char *); static void arpintr(struct mbuf *); static void arptimer(void *); -static struct rtentry - *arplookup(u_long, int, int, int); #ifdef INET static void in_arpinput(struct mbuf *); #endif +#ifdef AF_INET +void arp_ifscrub(struct ifnet *ifp, uint32_t addr); + /* - * Timeout routine. + * called by in_ifscrub to remove entry from the table when + * the interface goes away */ -static void -arptimer(void *arg) +void +arp_ifscrub(struct ifnet *ifp, uint32_t addr) { - struct rtentry *rt = (struct rtentry *)arg; + struct sockaddr_in addr4; + struct llentry *lle; - RT_LOCK_ASSERT(rt); - /* *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812040223.mB42N2UU007804>