svn commit: r186576 - user/kmacy/HEAD_fast_net/sys/netinet

Kip Macy kmacy at FreeBSD.org
Mon Dec 29 23:31:05 UTC 2008


Author: kmacy
Date: Mon Dec 29 23:31:04 2008
New Revision: 186576
URL: http://svn.freebsd.org/changeset/base/186576

Log:
  install cached llentry in the inpcb and then pass down to ether_output in the struct route

Modified:
  user/kmacy/HEAD_fast_net/sys/netinet/if_ether.c
  user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.c
  user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.h
  user/kmacy/HEAD_fast_net/sys/netinet/ip_output.c

Modified: user/kmacy/HEAD_fast_net/sys/netinet/if_ether.c
==============================================================================
--- user/kmacy/HEAD_fast_net/sys/netinet/if_ether.c	Mon Dec 29 22:36:23 2008	(r186575)
+++ user/kmacy/HEAD_fast_net/sys/netinet/if_ether.c	Mon Dec 29 23:31:04 2008	(r186576)
@@ -80,7 +80,6 @@ __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, "");

Modified: user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.c
==============================================================================
--- user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.c	Mon Dec 29 22:36:23 2008	(r186575)
+++ user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.c	Mon Dec 29 23:31:04 2008	(r186576)
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
 
 #include <net/if.h>
 #include <net/if_types.h>
+#include <net/if_llatbl.h>
 #include <net/route.h>
 
 #include <netinet/in.h>
@@ -494,6 +495,11 @@ void
 in_pcbrtalloc(struct inpcb *inp, in_addr_t faddr, struct route *sro)
 {
 	struct sockaddr_in *sin;
+	struct sockaddr *dst;
+	struct llentry *la;
+	struct rtentry *rt;
+	struct ifnet *ifp;
+	int flags = LLE_EXCLUSIVE;
 
 	INP_WLOCK_ASSERT(inp);
 	bzero(sro, sizeof(*sro));
@@ -516,11 +522,39 @@ in_pcbrtalloc(struct inpcb *inp, in_addr
 #endif		
 	}
 
-	if (sro->ro_rt != NULL) {
-		inp->inp_rt = sro->ro_rt;
-		inp->inp_vflag |= INP_RT_VALID;
+	rt = sro->ro_rt;
+	if (rt == NULL)
+		return;
+	
+	inp->inp_rt = rt;
+	inp->inp_vflag |= INP_RT_VALID;
 
+	if (rt->rt_ifp == NULL)
+		return;
+	
+	ifp = rt->rt_ifp;
+	dst = &sro->ro_dst;
+	if (rt->rt_flags & RTF_GATEWAY)
+		dst = rt->rt_gateway;
+		
+	IF_AFDATA_RLOCK(ifp);	
+	la = lla_lookup(LLTABLE(ifp), flags, dst);
+	IF_AFDATA_RUNLOCK(ifp);
+	if ((la == NULL) && 
+	    (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
+		flags |= (LLE_CREATE | LLE_EXCLUSIVE);
+		IF_AFDATA_WLOCK(ifp);
+		la = lla_lookup(LLTABLE(ifp), flags, dst);
+		IF_AFDATA_WUNLOCK(ifp);	
 	}
+	if (la == NULL)
+		return;
+	
+	LLE_ADDREF(la);
+	LLE_WUNLOCK(la);
+
+	inp->inp_lle = la;
+	inp->inp_flags |= INP_LLE_VALID;
 }
 
 /*
@@ -905,9 +939,14 @@ in_pcbdisconnect(struct inpcb *inp)
 	INP_WLOCK_ASSERT(inp);
 
 	if (inp->inp_vflag & INP_RT_VALID) {
+		inp->inp_vflag &= ~INP_RT_VALID;
 		RTFREE(inp->inp_rt);
 		inp->inp_rt = NULL;
-		inp->inp_vflag &= ~INP_RT_VALID;
+	}
+	if (inp->inp_flags & INP_LLE_VALID) {
+		inp->inp_flags &= ~INP_LLE_VALID;
+		LLE_FREE(inp->inp_lle);
+		inp->inp_lle = NULL;
 	}
 
 	inp->inp_faddr.s_addr = INADDR_ANY;
@@ -948,11 +987,16 @@ in_pcbfree_internal(struct inpcb *inp)
 	INP_WLOCK_ASSERT(inp);
 
 	if (inp->inp_vflag & INP_RT_VALID) {		
+		inp->inp_vflag &= ~INP_RT_VALID;
 		RTFREE(inp->inp_rt);
 		inp->inp_rt = NULL;
-		inp->inp_vflag &= ~INP_RT_VALID;
 	}
-	
+	if (inp->inp_flags & INP_LLE_VALID) {
+		inp->inp_flags &= ~INP_LLE_VALID;
+		LLE_FREE(inp->inp_lle);
+		inp->inp_lle = NULL;
+	}
+
 #ifdef IPSEC
 	if (inp->inp_sp != NULL)
 		ipsec_delete_pcbpolicy(inp);

Modified: user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.h
==============================================================================
--- user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.h	Mon Dec 29 22:36:23 2008	(r186575)
+++ user/kmacy/HEAD_fast_net/sys/netinet/in_pcb.h	Mon Dec 29 23:31:04 2008	(r186576)
@@ -418,6 +418,7 @@ void 	inp_4tuple_get(struct inpcb *inp, 
 #define	INP_FAITH		0x200	/* accept FAITH'ed connections */
 #define	INP_RECVTTL		0x400	/* receive incoming IP TTL */
 #define	INP_DONTFRAG		0x800	/* don't fragment packet */
+#define	INP_LLE_VALID		0x1000	/* L2 entry is set */
 
 #define IN6P_IPV6_V6ONLY	0x008000 /* restrict AF_INET6 socket for v6 */
 

Modified: user/kmacy/HEAD_fast_net/sys/netinet/ip_output.c
==============================================================================
--- user/kmacy/HEAD_fast_net/sys/netinet/ip_output.c	Mon Dec 29 22:36:23 2008	(r186575)
+++ user/kmacy/HEAD_fast_net/sys/netinet/ip_output.c	Mon Dec 29 23:31:04 2008	(r186576)
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/vimage.h>
 
 #include <net/if.h>
+#include <net/if_llatbl.h>
 #include <net/netisr.h>
 #include <net/pfil.h>
 #include <net/route.h>
@@ -121,7 +122,7 @@ ip_output(struct mbuf *m, struct mbuf *o
 	int hlen = sizeof (struct ip);
 	int mtu;
 	int len, error = 0;
-	int neednewroute = 0;
+	int neednewroute = 0, neednewlle = 0;
 	struct sockaddr_in *dst = NULL;	/* keep compiler happy */
 	struct in_ifaddr *ia = NULL;
 	int isbroadcast, sw_csum;
@@ -150,7 +151,13 @@ ip_output(struct mbuf *m, struct mbuf *o
 				ro->ro_rt = inp->inp_rt;
 			} else
 				neednewroute = 1;
-		} 
+		}
+		if ((ro == &iproute) && (inp->inp_flags & INP_LLE_VALID)) {
+			if (inp->inp_lle->la_flags & LLE_VALID) {
+				ro->ro_lle = inp->inp_lle;
+			} else
+				neednewlle = 1;
+		}
 	}
 
 	if (opt) {
@@ -625,19 +632,44 @@ passout:
 done:
 	if (ro == &iproute && ro->ro_rt != NULL) {
 		int wlocked;		
-
+		struct llentry *la;
+		
+		wlocked = INP_WLOCKED(inp);
 		if (inp == NULL || (inp->inp_vflag & INP_RT_VALID) == 0)
-			RTFREE(ro->ro_rt);		
+			RTFREE(ro->ro_rt);
 		else if (neednewroute && ro->ro_rt != inp->inp_rt) {
-			wlocked = INP_WLOCKED(inp);
 			if (!wlocked && INP_TRY_UPGRADE(inp) == 0)
 				return (error);
 			RTFREE(inp->inp_rt);
 			inp->inp_rt = ro->ro_rt;
-			if (!wlocked)
-				INP_DOWNGRADE(inp);
+
+		}
+		if (neednewlle) {
+			if (!wlocked && INP_TRY_UPGRADE(inp) == 0)
+				return (error);
+			IF_AFDATA_RLOCK(ifp);	
+			la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE,
+			    (struct sockaddr *)dst);
+			IF_AFDATA_RUNLOCK(ifp);
+			if ((la == NULL) && 
+			    (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
+				IF_AFDATA_WLOCK(ifp);
+				la = lla_lookup(LLTABLE(ifp),
+				    (LLE_CREATE | LLE_EXCLUSIVE),
+				    (struct sockaddr *)dst);
+				IF_AFDATA_WUNLOCK(ifp);	
+			}
+			if (la != NULL) {
+				LLE_FREE(inp->inp_lle);
+				LLE_ADDREF(la);
+				LLE_WUNLOCK(la);
+				inp->inp_lle = la;
+			}
 		}
+		if (!wlocked)
+			INP_DOWNGRADE(inp);
 	}
+	
 	return (error);
 bad:
 	m_freem(m);


More information about the svn-src-user mailing list