svn commit: r185819 - in projects/arpv2_merge_1: 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
Tue Dec 9 18:04:47 PST 2008


Author: kmacy
Date: Wed Dec 10 02:04:46 2008
New Revision: 185819
URL: http://svn.freebsd.org/changeset/base/185819

Log:
  merge qingli's latest arpv2 patch

Modified:
  projects/arpv2_merge_1/lib/libstand/if_ether.h
  projects/arpv2_merge_1/sys/conf/files
  projects/arpv2_merge_1/sys/contrib/rdma/rdma_addr.c
  projects/arpv2_merge_1/sys/dev/cxgb/ulp/tom/cxgb_l2t.c
  projects/arpv2_merge_1/sys/net/if.c
  projects/arpv2_merge_1/sys/net/if_arcsubr.c
  projects/arpv2_merge_1/sys/net/if_ethersubr.c
  projects/arpv2_merge_1/sys/net/if_fddisubr.c
  projects/arpv2_merge_1/sys/net/if_fwsubr.c
  projects/arpv2_merge_1/sys/net/if_iso88025subr.c
  projects/arpv2_merge_1/sys/net/if_var.h
  projects/arpv2_merge_1/sys/net/route.c
  projects/arpv2_merge_1/sys/net/rtsock.c
  projects/arpv2_merge_1/sys/netinet/if_ether.c
  projects/arpv2_merge_1/sys/netinet/if_ether.h
  projects/arpv2_merge_1/sys/netinet/in.c
  projects/arpv2_merge_1/sys/netinet/in_proto.c
  projects/arpv2_merge_1/sys/netinet/in_var.h
  projects/arpv2_merge_1/sys/netinet/ip_output.c
  projects/arpv2_merge_1/sys/netinet6/icmp6.c
  projects/arpv2_merge_1/sys/netinet6/in6.c
  projects/arpv2_merge_1/sys/netinet6/in6_var.h
  projects/arpv2_merge_1/sys/netinet6/ip6_forward.c
  projects/arpv2_merge_1/sys/netinet6/ip6_input.c
  projects/arpv2_merge_1/sys/netinet6/ip6_mroute.c
  projects/arpv2_merge_1/sys/netinet6/ip6_output.c
  projects/arpv2_merge_1/sys/netinet6/nd6.c
  projects/arpv2_merge_1/sys/netinet6/nd6.h
  projects/arpv2_merge_1/sys/netinet6/nd6_nbr.c
  projects/arpv2_merge_1/sys/netinet6/nd6_rtr.c
  projects/arpv2_merge_1/sys/netinet6/vinet6.h
  projects/arpv2_merge_1/usr.sbin/arp/arp.c
  projects/arpv2_merge_1/usr.sbin/ndp/ndp.c

Modified: projects/arpv2_merge_1/lib/libstand/if_ether.h
==============================================================================
--- projects/arpv2_merge_1/lib/libstand/if_ether.h	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/lib/libstand/if_ether.h	Wed Dec 10 02:04:46 2008	(r185819)
@@ -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: projects/arpv2_merge_1/sys/conf/files
==============================================================================
--- projects/arpv2_merge_1/sys/conf/files	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/conf/files	Wed Dec 10 02:04:46 2008	(r185819)
@@ -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: projects/arpv2_merge_1/sys/contrib/rdma/rdma_addr.c
==============================================================================
--- projects/arpv2_merge_1/sys/contrib/rdma/rdma_addr.c	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/contrib/rdma/rdma_addr.c	Wed Dec 10 02:04:46 2008	(r185819)
@@ -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: projects/arpv2_merge_1/sys/dev/cxgb/ulp/tom/cxgb_l2t.c
==============================================================================
--- projects/arpv2_merge_1/sys/dev/cxgb/ulp/tom/cxgb_l2t.c	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/dev/cxgb/ulp/tom/cxgb_l2t.c	Wed Dec 10 02:04:46 2008	(r185819)
@@ -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: projects/arpv2_merge_1/sys/net/if.c
==============================================================================
--- projects/arpv2_merge_1/sys/net/if.c	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/net/if.c	Wed Dec 10 02:04:46 2008	(r185819)
@@ -60,6 +60,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>
@@ -70,6 +71,7 @@
 #include <net/radix.h>
 #include <net/route.h>
 #include <net/vnet.h>
+#include <net/if_llatbl.h>
 
 #if defined(INET) || defined(INET6)
 /*XXX*/

Modified: projects/arpv2_merge_1/sys/net/if_arcsubr.c
==============================================================================
--- projects/arpv2_merge_1/sys/net/if_arcsubr.c	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/net/if_arcsubr.c	Wed Dec 10 02:04:46 2008	(r185819)
@@ -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: projects/arpv2_merge_1/sys/net/if_ethersubr.c
==============================================================================
--- projects/arpv2_merge_1/sys/net/if_ethersubr.c	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/net/if_ethersubr.c	Wed Dec 10 02:04:46 2008	(r185819)
@@ -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,17 @@ ether_output(struct ifnet *ifp, struct m
 		senderr(EAFNOSUPPORT);
 	}
 
+	if (lle && (lle->la_flags & LLE_IFADDR) && useloopback) {
+		int csum_flags = 0;
+		if (m->m_pkthdr.csum_flags & CSUM_IP)
+			csum_flags |= (CSUM_IP_CHECKED|CSUM_IP_VALID);
+		if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA)
+			csum_flags |= (CSUM_DATA_VALID|CSUM_PSEUDO_HDR);
+		m->m_pkthdr.csum_flags |= csum_flags;
+		m->m_pkthdr.csum_data = 0xffff;
+		return (if_simloop(ifp, m, dst->sa_family, 0));
+	}
+
 	/*
 	 * Add local net header.  If no space in first mbuf,
 	 * allocate another.

Modified: projects/arpv2_merge_1/sys/net/if_fddisubr.c
==============================================================================
--- projects/arpv2_merge_1/sys/net/if_fddisubr.c	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/net/if_fddisubr.c	Wed Dec 10 02:04:46 2008	(r185819)
@@ -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: projects/arpv2_merge_1/sys/net/if_fwsubr.c
==============================================================================
--- projects/arpv2_merge_1/sys/net/if_fwsubr.c	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/net/if_fwsubr.c	Wed Dec 10 02:04:46 2008	(r185819)
@@ -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: projects/arpv2_merge_1/sys/net/if_iso88025subr.c
==============================================================================
--- projects/arpv2_merge_1/sys/net/if_iso88025subr.c	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/net/if_iso88025subr.c	Wed Dec 10 02:04:46 2008	(r185819)
@@ -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;

Modified: projects/arpv2_merge_1/sys/net/if_var.h
==============================================================================
--- projects/arpv2_merge_1/sys/net/if_var.h	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/net/if_var.h	Wed Dec 10 02:04:46 2008	(r185819)
@@ -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: projects/arpv2_merge_1/sys/net/route.c
==============================================================================
--- projects/arpv2_merge_1/sys/net/route.c	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/net/route.c	Wed Dec 10 02:04:46 2008	(r185819)
@@ -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>
@@ -53,6 +54,7 @@
 #include <sys/vimage.h>
 
 #include <net/if.h>
+#include <net/if_dl.h>
 #include <net/route.h>
 
 #ifdef RADIX_MPATH
@@ -420,7 +422,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;
 	}
 
@@ -1500,6 +1502,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;
@@ -1604,7 +1607,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) {
@@ -1628,6 +1638,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: projects/arpv2_merge_1/sys/net/rtsock.c
==============================================================================
--- projects/arpv2_merge_1/sys/net/rtsock.c	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/net/rtsock.c	Wed Dec 10 02:04:46 2008	(r185819)
@@ -53,6 +53,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>
@@ -526,6 +527,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) {
@@ -541,6 +547,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) {
@@ -1432,6 +1444,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: projects/arpv2_merge_1/sys/netinet/if_ether.c
==============================================================================
--- projects/arpv2_merge_1/sys/netinet/if_ether.c	Wed Dec 10 02:04:45 2008	(r185818)
+++ projects/arpv2_merge_1/sys/netinet/if_ether.c	Wed Dec 10 02:04:46 2008	(r185819)
@@ -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,23 +89,13 @@ 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
 
 SYSCTL_V_INT(V_NET, vnet_inet, _net_link_ether_inet, OID_AUTO, max_age,
     CTLFLAG_RW, arpt_keep, 0, "ARP entry lifetime in seconds");
 
-#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 +109,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;
-
-	RT_LOCK_ASSERT(rt);
-	/*
-	 * The lock is needed to close a theoretical race
-	 * between spontaneous expiry and intentional removal.
-	 * We still got an extra reference on rtentry, so can
-	 * safely pass pointers to its contents.
-	 */
-	RT_UNLOCK(rt);
+	struct sockaddr_in addr4;
+	struct llentry *lle;
 
-	in_rtrequest(RTM_DELETE, rt_key(rt), NULL, rt_mask(rt), 0, NULL,
-	    rt->rt_fibnum);
+	bzero((void *)&addr4, sizeof(addr4));
+	addr4.sin_len    = sizeof(addr4);
+	addr4.sin_family = AF_INET;
+	addr4.sin_addr.s_addr = addr;
+	IF_AFDATA_LOCK(ifp);
+	lle = lla_lookup(LLTABLE(ifp), (LLE_DELETE | LLE_IFADDR),
+	    (struct sockaddr *)&addr4);
+	IF_AFDATA_UNLOCK(ifp);
+#if 0
+	if (lle == NULL)
+		log(LOG_INFO, "arp_ifscrub: interface address is missing from cache\n");
+#endif
 }
+#endif
 
 /*
- * Parallel to llc_rtrequest.
+ * Timeout routine.  Age arp_tab entries periodically.
  */
 static void
-arp_rtrequest(int req, struct rtentry *rt, struct rt_addrinfo *info)
+arptimer(void *arg)
 {
-	INIT_VNET_NET(curvnet);
-	INIT_VNET_INET(curvnet);
-	struct sockaddr *gate;
-	struct llinfo_arp *la;
-	static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
-	struct in_ifaddr *ia;
-	struct ifaddr *ifa;
+	struct ifnet *ifp;
+	struct llentry   *lle = (struct llentry *)arg;
 
-	RT_LOCK_ASSERT(rt);
-
-	if (rt->rt_flags & RTF_GATEWAY)
+	if (lle == NULL) {
+		panic("%s: NULL entry!\n", __func__);
 		return;
-	gate = rt->rt_gateway;
-	la = (struct llinfo_arp *)rt->rt_llinfo;
-	switch (req) {
-
-	case RTM_ADD:
-		/*
-		 * XXX: If this is a manually added route to interface
-		 * such as older version of routed or gated might provide,
-		 * restore cloning bit.
-		 */
-		if ((rt->rt_flags & RTF_HOST) == 0 &&
-		    rt_mask(rt) != NULL &&
-		    SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
-			rt->rt_flags |= RTF_CLONING;
-		if (rt->rt_flags & RTF_CLONING) {
-			/*
-			 * Case 1: This route should come from a route to iface.
-			 */
-			rt_setgate(rt, rt_key(rt),
-					(struct sockaddr *)&null_sdl);
-			gate = rt->rt_gateway;
-			SDL(gate)->sdl_type = rt->rt_ifp->if_type;
-			SDL(gate)->sdl_index = rt->rt_ifp->if_index;
-			rt->rt_expire = time_uptime;
-			break;
-		}
-		/* Announce a new entry if requested. */
-		if (rt->rt_flags & RTF_ANNOUNCE)
-			arprequest(rt->rt_ifp,
-			    &SIN(rt_key(rt))->sin_addr,
-			    &SIN(rt_key(rt))->sin_addr,
-			    (u_char *)LLADDR(SDL(gate)));
-		/*FALLTHROUGH*/
-	case RTM_RESOLVE:
-		if (gate->sa_family != AF_LINK ||
-		    gate->sa_len < sizeof(null_sdl)) {
-			log(LOG_DEBUG, "%s: bad gateway %s%s\n", __func__,
-			    inet_ntoa(SIN(rt_key(rt))->sin_addr),
-			    (gate->sa_family != AF_LINK) ?
-			    " (!AF_LINK)": "");
-			break;
-		}
-		SDL(gate)->sdl_type = rt->rt_ifp->if_type;
-		SDL(gate)->sdl_index = rt->rt_ifp->if_index;
-		if (la != 0)
-			break; /* This happens on a route change */
-		/*
-		 * Case 2:  This route may come from cloning, or a manual route
-		 * add with a LL address.
-		 */
-		R_Zalloc(la, struct llinfo_arp *, sizeof(*la));
-		rt->rt_llinfo = (caddr_t)la;
-		if (la == 0) {
-			log(LOG_DEBUG, "%s: malloc failed\n", __func__);
-			break;
-		}
-		/*
-		 * We are storing a route entry outside of radix tree. So,
-		 * it can be found and accessed by other means than radix
-		 * lookup. The routing code assumes that any rtentry detached
-		 * from radix can be destroyed safely. To prevent this, we
-		 * add an additional reference.
-		 */
-		RT_ADDREF(rt);
-		la->la_rt = rt;
-		rt->rt_flags |= RTF_LLINFO;
-		callout_init_mtx(&la->la_timer, &rt->rt_mtx,
-		    CALLOUT_RETURNUNLOCKED);
-
-#ifdef INET
-		/*
-		 * This keeps the multicast addresses from showing up
-		 * in `arp -a' listings as unresolved.  It's not actually
-		 * functional.  Then the same for broadcast.
-		 */
-		if (IN_MULTICAST(ntohl(SIN(rt_key(rt))->sin_addr.s_addr)) &&
-		    rt->rt_ifp->if_type != IFT_ARCNET) {
-			ETHER_MAP_IP_MULTICAST(&SIN(rt_key(rt))->sin_addr,
-					       LLADDR(SDL(gate)));
-			SDL(gate)->sdl_alen = 6;
-			rt->rt_expire = 0;
-		}
-		if (in_broadcast(SIN(rt_key(rt))->sin_addr, rt->rt_ifp)) {
-			memcpy(LLADDR(SDL(gate)), rt->rt_ifp->if_broadcastaddr,
-			       rt->rt_ifp->if_addrlen);
-			SDL(gate)->sdl_alen = rt->rt_ifp->if_addrlen;
-			rt->rt_expire = 0;
-		}
-#endif
-
-		TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
-			if (ia->ia_ifp == rt->rt_ifp &&
-			    SIN(rt_key(rt))->sin_addr.s_addr ==
-			    (IA_SIN(ia))->sin_addr.s_addr)
-				break;
-		}
-		if (ia) {
-		    /*
-		     * This test used to be
-		     *	if (loif.if_flags & IFF_UP)
-		     * It allowed local traffic to be forced
-		     * through the hardware by configuring the loopback down.
-		     * However, it causes problems during network configuration
-		     * for boards that can't receive packets they send.
-		     * It is now necessary to clear "useloopback" and remove
-		     * the route to force traffic out to the hardware.
-		     */
-			rt->rt_expire = 0;
-			bcopy(IF_LLADDR(rt->rt_ifp), LLADDR(SDL(gate)),
-			      SDL(gate)->sdl_alen = rt->rt_ifp->if_addrlen);
-			if (V_useloopback) {
-				rt->rt_ifp = V_loif;
-				rt->rt_rmx.rmx_mtu = V_loif->if_mtu;
-			}
-
-		    /*
-		     * make sure to set rt->rt_ifa to the interface
-		     * address we are using, otherwise we will have trouble
-		     * with source address selection.
-		     */
-			ifa = &ia->ia_ifa;
-			if (ifa != rt->rt_ifa) {
-				IFAFREE(rt->rt_ifa);
-				IFAREF(ifa);
-				rt->rt_ifa = ifa;
-			}
+	}
+	ifp = lle->lle_tbl->llt_ifp;
+	IF_AFDATA_LOCK(ifp);
+	if ((lle->la_flags & LLE_DELETED) ||
+	    (time_second >= lle->la_expire)) {
+		if (!callout_pending(&lle->la_timer)  &&
+		    (callout_active(&lle->la_timer))) {
+			(void)llentry_free(lle);
 		}
-		break;
-
-	case RTM_DELETE:
-		if (la == NULL)	/* XXX: at least CARP does this. */
-			break;
-		callout_stop(&la->la_timer);
-		rt->rt_llinfo = NULL;
-		rt->rt_flags &= ~RTF_LLINFO;
-		RT_REMREF(rt);
-		if (la->la_hold)
-			m_freem(la->la_hold);
-		Free((caddr_t)la);
 	}
+	IF_AFDATA_UNLOCK(ifp);
 }
 
+
 /*
  * Broadcast an ARP request. Caller specifies:
  *	- arp header source ip address
  *	- arp header target ip address
  *	- arp header source ethernet address
  */
-static void
-arprequest(struct ifnet *ifp, struct in_addr *sip, struct in_addr *tip,
+void
+arprequest(struct ifnet *ifp, struct in_addr *sip, struct in_addr  *tip,
     u_char *enaddr)
 {
 	struct mbuf *m;
 	struct arphdr *ah;
 	struct sockaddr sa;
 
+	if (sip == NULL) {
+		/*
+		 * The caller did not supply a source address, try to find
+		 * a compatible one among those assigned to this interface.
+		 */
+		struct ifaddr *ifa;
+
+		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+			if (!ifa->ifa_addr ||
+			    ifa->ifa_addr->sa_family != AF_INET)
+				continue;
+			sip = &SIN(ifa->ifa_addr)->sin_addr;
+			if (0 == ((sip->s_addr ^ tip->s_addr) &
+			    SIN(ifa->ifa_netmask)->sin_addr.s_addr) )
+				break;  /* found it. */
+		}
+		if (sip == NULL) {  
+			printf("%s: cannot find matching address\n", __func__);
+			return;
+		}
+	}
+
 	if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
 		return;
 	m->m_len = sizeof(*ah) + 2*sizeof(struct in_addr) +
@@ -345,8 +229,6 @@ arprequest(struct ifnet *ifp, struct in_
 	sa.sa_len = 2;
 	m->m_flags |= M_BCAST;
 	(*ifp->if_output)(ifp, m, &sa, (struct rtentry *)0);
-
-	return;
 }
 
 /*
@@ -365,16 +247,16 @@ arprequest(struct ifnet *ifp, struct in_
  */
 int
 arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
-    struct sockaddr *dst, u_char *desten)
+	struct sockaddr *dst, u_char *desten, struct llentry **lle)
 {
 	INIT_VNET_INET(ifp->if_vnet);
-	struct llinfo_arp *la = NULL;
-	struct rtentry *rt = NULL;
-	struct sockaddr_dl *sdl;
+	struct llentry *la = 0;
+	u_int flags;
 	int error;
-	int fibnum = -1;
 
-	if (m) {
+	*lle = NULL;
+
+	if (m != NULL) {
 		if (m->m_flags & M_BCAST) {
 			/* broadcast */
 			(void)memcpy(desten,
@@ -386,95 +268,46 @@ arpresolve(struct ifnet *ifp, struct rte
 			ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, desten);
 			return (0);
 		}
-		fibnum = M_GETFIB(m);
 	}
 
-	if (rt0 != NULL) {
-		/* Look for a cached arp (ll) entry. */
-		if (m == NULL)
-			fibnum = rt0->rt_fibnum;
-		error = rt_check(&rt, &rt0, dst);
-		if (error) {
-			m_freem(m);
-			return error;
-		}
-		la = (struct llinfo_arp *)rt->rt_llinfo;
-		if (la == NULL)
-			RT_UNLOCK(rt);
-	}
+	flags = (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) ? 0 : LLE_CREATE;
 
-	/*
-	 * If we had no mbuf and no route, then hope the caller
-	 * has a fib in mind because we are running out of ideas.
-	 * I think this should not happen in current code.
-	 * (kmacy would know).
+	/* XXXXX
+	 * Since this function returns an llentry, the 
+	 * lock is held by the caller.
 	 */
-	if (fibnum == -1)
-		fibnum = curthread->td_proc->p_fibnum; /* last gasp */
-
+	la = lla_lookup(LLTABLE(ifp), flags, dst);
 	if (la == NULL) {
-		/*
-		 * We enter this block if rt0 was NULL,
-		 * or if rt found by rt_check() didn't have llinfo.
-		 * we should get a cloned route, which since it should
-		 * come from the local interface should have a ll entry.
-		 * It may be incomplete but that's ok.
-		 */
-		rt = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0, fibnum);
-		if (rt == NULL) {
-			log(LOG_DEBUG,
-			    "arpresolve: can't allocate route for %s\n",
-			    inet_ntoa(SIN(dst)->sin_addr));
-			m_freem(m);
-			return (EINVAL); /* XXX */
-		}
-		la = (struct llinfo_arp *)rt->rt_llinfo;
-		if (la == NULL) {
-			RT_UNLOCK(rt);
+		if (flags & LLE_CREATE)
 			log(LOG_DEBUG,
 			    "arpresolve: can't allocate llinfo for %s\n",
 			    inet_ntoa(SIN(dst)->sin_addr));
-			m_freem(m);
-			return (EINVAL); /* XXX */
-		}
-	}
-	sdl = SDL(rt->rt_gateway);
-	/*
-	 * Check the address family and length is valid, the address
-	 * is resolved; otherwise, try to resolve.
-	 */
-	if ((rt->rt_expire == 0 || rt->rt_expire > time_uptime) &&
-	    sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
-
-		bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
+		m_freem(m);
+		return (EINVAL);
+	} 
 
+	if (la->la_flags & LLE_VALID &&
+	    (la->la_flags & LLE_STATIC || la->la_expire > time_uptime)) {
+		bcopy(&la->ll_addr, desten, ifp->if_addrlen);
 		/*
 		 * If entry has an expiry time and it is approaching,
-		 * send an ARP request.
+		 * see if we need to send an ARP request within this
+		 * arpt_down interval.
 		 */
-		if ((rt->rt_expire != 0) &&
-		    (time_uptime + la->la_preempt > rt->rt_expire)) {
-			struct in_addr sin = 
-			    SIN(rt->rt_ifa->ifa_addr)->sin_addr;
+		if (!(la->la_flags & LLE_STATIC) &&
+		    time_uptime + la->la_preempt > la->la_expire) {
+			arprequest(ifp, NULL,
+			    &SIN(dst)->sin_addr, IF_LLADDR(ifp));
 
 			la->la_preempt--;
-			RT_UNLOCK(rt);
-			arprequest(ifp, &sin, &SIN(dst)->sin_addr,
-			    IF_LLADDR(ifp));
-			return (0);
 		} 
-
-		RT_UNLOCK(rt);
+		*lle = la;
 		return (0);
 	}
-	/*
-	 * If ARP is disabled or static on this interface, stop.
-	 * XXX
-	 * Probably should not allocate empty llinfo struct if we are
-	 * not going to be sending out an arp request.
-	 */
-	if (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) {
-		RT_UNLOCK(rt);
+
+	if (la->la_flags & LLE_STATIC) {   /* should not happen! */
+		log(LOG_DEBUG, "arpresolve: ouch, empty static llinfo for %s\n",
+		    inet_ntoa(SIN(dst)->sin_addr));
 		m_freem(m);
 		return (EINVAL);
 	}
@@ -488,8 +321,6 @@ arpresolve(struct ifnet *ifp, struct rte
 			m_freem(la->la_hold);
 		la->la_hold = m;
 	}
-	KASSERT(rt->rt_expire > 0, ("sending ARP request for static entry"));
-
 	/*
 	 * Return EWOULDBLOCK if we have tried less than arp_maxtries. It
 	 * will be masked by ether_output(). Return EHOSTDOWN/EHOSTUNREACH
@@ -499,23 +330,19 @@ arpresolve(struct ifnet *ifp, struct rte
 	if (la->la_asked < V_arp_maxtries)
 		error = EWOULDBLOCK;	/* First request. */
 	else
-		error = (rt == rt0) ? EHOSTDOWN : EHOSTUNREACH;
+		error =
+		    (rt0->rt_flags & RTF_GATEWAY) ? EHOSTDOWN : EHOSTUNREACH;
 
-	if (la->la_asked == 0 || rt->rt_expire != time_uptime) {
-		struct in_addr sin =
-		    SIN(rt->rt_ifa->ifa_addr)->sin_addr;
-
-		rt->rt_expire = time_uptime;
-		callout_reset(&la->la_timer, hz, arptimer, rt);
+	if (la->la_asked == 0 || la->la_expire != time_uptime) {
+		la->la_expire = time_uptime;
+		callout_reset(&la->la_timer, hz, arptimer, la);
 		la->la_asked++;
-		RT_UNLOCK(rt);
 
-		arprequest(ifp, &sin, &SIN(dst)->sin_addr,
+		arprequest(ifp, NULL, &SIN(dst)->sin_addr,
 		    IF_LLADDR(ifp));
-	} else
-		RT_UNLOCK(rt);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list