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

Kip Macy kmacy at FreeBSD.org
Wed Dec 3 18:23:03 PST 2008


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 ***


More information about the svn-src-user mailing list