svn commit: r184321 - in user/kmacy/HEAD_fast_xmit/sys: net netinet

Kip Macy kmacy at FreeBSD.org
Mon Oct 27 05:23:40 UTC 2008


Author: kmacy
Date: Mon Oct 27 05:23:40 2008
New Revision: 184321
URL: http://svn.freebsd.org/changeset/base/184321

Log:
  Hook rtentry_info use in to ip_output and ether_output in a non-disruptive
  albeit extremely hackish way

Modified:
  user/kmacy/HEAD_fast_xmit/sys/net/if_ethersubr.c
  user/kmacy/HEAD_fast_xmit/sys/net/radix_mpath.h
  user/kmacy/HEAD_fast_xmit/sys/net/route.h
  user/kmacy/HEAD_fast_xmit/sys/netinet/if_ether.c
  user/kmacy/HEAD_fast_xmit/sys/netinet/ip_input.c
  user/kmacy/HEAD_fast_xmit/sys/netinet/ip_output.c
  user/kmacy/HEAD_fast_xmit/sys/netinet/ip_var.h

Modified: user/kmacy/HEAD_fast_xmit/sys/net/if_ethersubr.c
==============================================================================
--- user/kmacy/HEAD_fast_xmit/sys/net/if_ethersubr.c	Mon Oct 27 05:19:26 2008	(r184320)
+++ user/kmacy/HEAD_fast_xmit/sys/net/if_ethersubr.c	Mon Oct 27 05:23:40 2008	(r184321)
@@ -55,6 +55,7 @@
 #include <net/if_arp.h>
 #include <net/netisr.h>
 #include <net/route.h>
+#include <net/flowtable.h>
 #include <net/if_llc.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
@@ -160,7 +161,8 @@ ether_output(struct ifnet *ifp, struct m
 	u_char esrc[ETHER_ADDR_LEN], edst[ETHER_ADDR_LEN];
 	struct ether_header *eh;
 	struct pf_mtag *t;
-	int loop_copy = 1;
+	struct rtentry_info *ri = NULL;
+	int riset = 0, loop_copy = 1;
 	int hlen;	/* link layer header length */
 
 #ifdef MAC
@@ -168,6 +170,17 @@ ether_output(struct ifnet *ifp, struct m
 	if (error)
 		senderr(error);
 #endif
+	/*
+	 * XXX rather hackish interface to ip_output
+	 * to pass an rtentry_info in 
+	 * 
+	 */
+	if (dst == NULL) {
+		ri = (struct rtentry_info *)rt0;
+		dst = (struct sockaddr *)&ri->ri_dst;
+		riset = 1;
+		rt0 = NULL;
+	}
 
 	M_PROFILE(m);
 	if (ifp->if_flags & IFF_MONITOR)
@@ -180,7 +193,11 @@ ether_output(struct ifnet *ifp, struct m
 	switch (dst->sa_family) {
 #ifdef INET
 	case AF_INET:
-		error = arpresolve(ifp, rt0, m, dst, edst);
+		error = 0;
+		if (riset && (ri->ri_flags && RTF_DESTEN_VALID))
+			memcpy(edst, ri->ri_desten, ETHER_ADDR_LEN);
+		else
+			error = arpresolve(ifp, rt0, m, dst, edst);
 		if (error)
 			return (error == EWOULDBLOCK ? 0 : error);
 		type = htons(ETHERTYPE_IP);

Modified: user/kmacy/HEAD_fast_xmit/sys/net/radix_mpath.h
==============================================================================
--- user/kmacy/HEAD_fast_xmit/sys/net/radix_mpath.h	Mon Oct 27 05:19:26 2008	(r184320)
+++ user/kmacy/HEAD_fast_xmit/sys/net/radix_mpath.h	Mon Oct 27 05:23:40 2008	(r184321)
@@ -58,11 +58,6 @@ int rt_mpath_deldup(struct rtentry *, st
 int	rn4_mpath_inithead(void **, int);
 int	rn6_mpath_inithead(void **, int);
 
-uint32_t ipv4_flow_alloc(struct mbuf *m, struct route *ro);
-void ipv4_flow_free(uint32_t hash);
-
-uint32_t ipv4_flow_lookup_hash(struct mbuf *m);
-void ipv4_flow_free_all(struct rtentry *rt);
 #endif
 
 #endif /* _NET_RADIX_MPATH_H_ */

Modified: user/kmacy/HEAD_fast_xmit/sys/net/route.h
==============================================================================
--- user/kmacy/HEAD_fast_xmit/sys/net/route.h	Mon Oct 27 05:19:26 2008	(r184320)
+++ user/kmacy/HEAD_fast_xmit/sys/net/route.h	Mon Oct 27 05:23:40 2008	(r184321)
@@ -148,9 +148,7 @@ struct rtentry {
 #ifdef _KERNEL
 	/* XXX ugly, user apps use this definition but don't have a mtx def */
 	struct	mtx rt_mtx;		/* mutex for routing entry */
-#ifdef RADIX_MPATH
-	uint32_t 	rt_flow_head;
-#endif 
+	time_t  rt_llinfo_uptime;	/* last time the rt_llinfo changed */
 #endif
 };
 
@@ -199,6 +197,7 @@ struct ortentry {
 #define	RTF_BROADCAST	0x400000	/* route represents a bcast address */
 #define	RTF_MULTICAST	0x800000	/* route represents a mcast address */
 					/* 0x1000000 and up unassigned */
+#define	RTF_DESTEN_VALID 0x80000000	/* rtentry_info L2 addr is valid */
 
 /* Mask of RTF flags that are allowed to be modified by RTM_CHANGE. */
 #define RTF_FMASK	\

Modified: user/kmacy/HEAD_fast_xmit/sys/netinet/if_ether.c
==============================================================================
--- user/kmacy/HEAD_fast_xmit/sys/netinet/if_ether.c	Mon Oct 27 05:19:26 2008	(r184320)
+++ user/kmacy/HEAD_fast_xmit/sys/netinet/if_ether.c	Mon Oct 27 05:23:40 2008	(r184321)
@@ -216,6 +216,7 @@ arp_rtrequest(int req, struct rtentry *r
 		 */
 		R_Zalloc(la, struct llinfo_arp *, sizeof(*la));
 		rt->rt_llinfo = (caddr_t)la;
+		rt->rt_llinfo_uptime = time_uptime;
 		if (la == 0) {
 			log(LOG_DEBUG, "%s: malloc failed\n", __func__);
 			break;
@@ -299,6 +300,7 @@ arp_rtrequest(int req, struct rtentry *r
 		callout_stop(&la->la_timer);
 		rt->rt_llinfo = NULL;
 		rt->rt_flags &= ~RTF_LLINFO;
+		rt->rt_llinfo_uptime = time_uptime;
 		RT_REMREF(rt);
 		if (la->la_hold)
 			m_freem(la->la_hold);

Modified: user/kmacy/HEAD_fast_xmit/sys/netinet/ip_input.c
==============================================================================
--- user/kmacy/HEAD_fast_xmit/sys/netinet/ip_input.c	Mon Oct 27 05:19:26 2008	(r184320)
+++ user/kmacy/HEAD_fast_xmit/sys/netinet/ip_input.c	Mon Oct 27 05:23:40 2008	(r184321)
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_dl.h>
 #include <net/route.h>
 #include <net/netisr.h>
+#include <net/flowtable.h>
 
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
@@ -211,6 +212,7 @@ SYSCTL_V_INT(V_NET, vnet_inet, _net_inet
 ip_fw_chk_t *ip_fw_chk_ptr = NULL;
 ip_dn_io_t *ip_dn_io_ptr = NULL;
 int fw_one_pass = 1;
+struct flowtable *ipv4_ft;
 
 static void	ip_freef(struct ipqhead *, struct ipq *);
 
@@ -277,6 +279,8 @@ ip_init(void)
 	ipintrq.ifq_maxlen = ipqmaxlen;
 	mtx_init(&ipintrq.ifq_mtx, "ip_inq", NULL, MTX_DEF);
 	netisr_register(NETISR_IP, ip_input, &ipintrq, 0);
+	
+	ipv4_ft = flowtable_alloc(2048, FL_LOCAL_XMIT|FL_PCPU);
 }
 
 void

Modified: user/kmacy/HEAD_fast_xmit/sys/netinet/ip_output.c
==============================================================================
--- user/kmacy/HEAD_fast_xmit/sys/netinet/ip_output.c	Mon Oct 27 05:19:26 2008	(r184320)
+++ user/kmacy/HEAD_fast_xmit/sys/netinet/ip_output.c	Mon Oct 27 05:23:40 2008	(r184321)
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
 #ifdef RADIX_MPATH
 #include <net/radix_mpath.h>
 #endif
+#include <net/flowtable.h>
 
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
@@ -97,6 +98,9 @@ static void	ip_mloopback
 
 extern	struct protosw inetsw[];
 
+extern struct flowtable *ipv4_ft;
+
+
 /*
  * IP output.  The packet in mbuf chain m contains a skeletal IP
  * header (with len, off, ttl, proto, tos, src, dst).
@@ -120,20 +124,27 @@ ip_output(struct mbuf *m, struct mbuf *o
 	struct sockaddr_in *dst = NULL;	/* keep compiler happy */
 	struct in_ifaddr *ia = NULL;
 	int isbroadcast, sw_csum;
-	struct route iproute;
+	struct rtentry_info ipri, *ri;
 	struct in_addr odst;
 #ifdef IPFIREWALL_FORWARD
 	struct m_tag *fwd_tag = NULL;
 #endif
 	M_ASSERTPKTHDR(m);
-
-	if (ro == NULL) {
-		ro = &iproute;
-		bzero(ro, sizeof (*ro));
+	if (inp != NULL) {
+		INP_LOCK_ASSERT(inp);
+		M_SETFIB(m, inp->inp_inc.inc_fibnum);
 	}
 
-	if (inp != NULL)
-		INP_LOCK_ASSERT(inp);
+	if (flags & IP_RTINFO) /* ugly interface overload */
+		ri = (struct rtentry_info *)ro;
+	else {
+		ri = &ipri;
+		bzero(ri, sizeof (*ri));
+		if (ro) 
+			route_to_rtentry_info(ro, NULL, ri);
+		else if (flowtable_lookup(ipv4_ft, m, ri))
+			return (ENETUNREACH);
+	}
 
 	if (opt) {
 		len = 0;
@@ -163,32 +174,9 @@ ip_output(struct mbuf *m, struct mbuf *o
 		hlen = ip->ip_hl << 2;
 	}
 
-	dst = (struct sockaddr_in *)&ro->ro_dst;
+	dst = (struct sockaddr_in *)&ri->ri_dst;
 again:
 	/*
-	 * If there is a cached route,
-	 * check that it is to the same destination
-	 * and is still up.  If not, free it and try again.
-	 * The address family should also be checked in case of sharing the
-	 * cache with IPv6.
-	 */
-	if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
-			  dst->sin_family != AF_INET ||
-			  dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
-		RTFREE(ro->ro_rt);
-		ro->ro_rt = (struct rtentry *)NULL;
-	}
-#ifdef IPFIREWALL_FORWARD
-	if (ro->ro_rt == NULL && fwd_tag == NULL) {
-#else
-	if (ro->ro_rt == NULL) {
-#endif
-		bzero(dst, sizeof(*dst));
-		dst->sin_family = AF_INET;
-		dst->sin_len = sizeof(*dst);
-		dst->sin_addr = ip->ip_dst;
-	}
-	/*
 	 * If routing to interface only, short circuit routing lookup.
 	 * The use of an all-ones broadcast address implies this; an
 	 * interface is specified by the broadcast address of an interface,
@@ -231,7 +219,14 @@ again:
 		 * as this is probably required in all cases for correct
 		 * operation (as it is for ARP).
 		 */
-		if (ro->ro_rt == NULL)
+		if ((ri->ri_flags & RTF_UP) == 0) {
+			error = flowtable_lookup(ipv4_ft, m, ri);
+			if (error)
+				goto bad;
+			
+		}
+#ifdef 	nomore		
+
 #ifdef RADIX_MPATH
 			rtalloc_mpath_fib(ro,
 			    ntohl(ip->ip_src.s_addr ^ ip->ip_dst.s_addr),
@@ -245,13 +240,11 @@ again:
 			error = EHOSTUNREACH;
 			goto bad;
 		}
-		ia = ifatoia(ro->ro_rt->rt_ifa);
-		ifp = ro->ro_rt->rt_ifp;
-		ro->ro_rt->rt_rmx.rmx_pksent++;
-		if (ro->ro_rt->rt_flags & RTF_GATEWAY)
-			dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
-		if (ro->ro_rt->rt_flags & RTF_HOST)
-			isbroadcast = (ro->ro_rt->rt_flags & RTF_BROADCAST);
+#endif
+		ia = ifatoia(ri->ri_ifa);
+		ifp = ri->ri_ifp;
+		if (ri->ri_flags & RTF_HOST)
+			isbroadcast = (ri->ri_flags & RTF_BROADCAST);
 		else
 			isbroadcast = in_broadcast(dst->sin_addr, ifp);
 	}
@@ -259,7 +252,7 @@ again:
 	 * Calculate MTU.  If we have a route that is up, use that,
 	 * otherwise use the interface's MTU.
 	 */
-	if (ro->ro_rt != NULL && (ro->ro_rt->rt_flags & (RTF_UP|RTF_HOST))) {
+	if (ri->ri_flags & (RTF_UP|RTF_HOST)) {
 		/*
 		 * This case can happen if the user changed the MTU
 		 * of an interface after enabling IP on it.  Because
@@ -267,9 +260,9 @@ again:
 		 * them, there is no way for one to update all its
 		 * routes when the MTU is changed.
 		 */
-		if (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu)
-			ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu;
-		mtu = ro->ro_rt->rt_rmx.rmx_mtu;
+		if (ri->ri_mtu > ifp->if_mtu)
+			ri->ri_mtu = ifp->if_mtu;
+		mtu = ri->ri_mtu;
 	} else {
 		mtu = ifp->if_mtu;
 	}
@@ -278,12 +271,6 @@ again:
 
 		m->m_flags |= M_MCAST;
 		/*
-		 * IP destination address is multicast.  Make sure "dst"
-		 * still points to the address in "ro".  (It may have been
-		 * changed to point to a gateway address, above.)
-		 */
-		dst = (struct sockaddr_in *)&ro->ro_dst;
-		/*
 		 * See if the caller provided any multicast options
 		 */
 		if (imo != NULL) {
@@ -430,6 +417,10 @@ again:
 	}
 
 sendit:
+/*
+ * XXX we've broken IPSEC
+ *
+ */
 #ifdef IPSEC
 	switch(ip_ipsec_output(&m, inp, &flags, &error, &ro, &iproute, &dst, &ia, &ifp)) {
 	case 1:
@@ -498,7 +489,7 @@ sendit:
 	/* Or forward to some other address? */
 	fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
 	if (fwd_tag) {
-		dst = (struct sockaddr_in *)&ro->ro_dst;
+		dst = (struct sockaddr_in *)&ri->ri_dst;
 		bcopy((fwd_tag+1), dst, sizeof(struct sockaddr_in));
 		m->m_flags |= M_SKIP_FIREWALL;
 		m_tag_delete(m, fwd_tag);
@@ -562,8 +553,17 @@ passout:
 		 */
 		m->m_flags &= ~(M_PROTOFLAGS);
 
-		error = (*ifp->if_output)(ifp, m,
-				(struct sockaddr *)dst, ro->ro_rt);
+		/*
+		 * XXX rather hackish interface to ether_output
+		 * to pass an rtentry_info in 
+		 * 
+		 */
+		if (ifp->if_output == ether_output)
+			error = (*ifp->if_output)(ifp, m,
+			    NULL, (struct rtentry *)ri);
+		else
+			error = (*ifp->if_output)(ifp, m,
+			    (struct sockaddr *)dst, NULL);
 		goto done;
 	}
 
@@ -596,8 +596,17 @@ passout:
 			 */
 			m->m_flags &= ~(M_PROTOFLAGS);
 
-			error = (*ifp->if_output)(ifp, m,
-			    (struct sockaddr *)dst, ro->ro_rt);
+			/*
+			 * XXX rather hackish interface to ether_output
+			 * to pass an rtentry_info in 
+			 * 
+			 */
+			if (ifp->if_output == ether_output)
+				error = (*ifp->if_output)(ifp, m,
+				    NULL, (struct rtentry *)ri);
+			else
+				error = (*ifp->if_output)(ifp, m,
+				    (struct sockaddr *)dst, NULL);
 		} else
 			m_freem(m);
 	}
@@ -606,9 +615,6 @@ passout:
 		V_ipstat.ips_fragmented++;
 
 done:
-	if (ro == &iproute && ro->ro_rt) {
-		RTFREE(ro->ro_rt);
-	}
 	return (error);
 bad:
 	m_freem(m);

Modified: user/kmacy/HEAD_fast_xmit/sys/netinet/ip_var.h
==============================================================================
--- user/kmacy/HEAD_fast_xmit/sys/netinet/ip_var.h	Mon Oct 27 05:19:26 2008	(r184320)
+++ user/kmacy/HEAD_fast_xmit/sys/netinet/ip_var.h	Mon Oct 27 05:23:40 2008	(r184321)
@@ -158,6 +158,7 @@ struct	ipstat {
 #define	IP_SENDTOIF		0x8		/* send on specific ifnet */
 #define IP_ROUTETOIF		SO_DONTROUTE	/* 0x10 bypass routing tables */
 #define IP_ALLOWBROADCAST	SO_BROADCAST	/* 0x20 can send broadcast packets */
+#define	IP_RTINFO		0x80		/* ip_output is passed an rtentry_info */
 
 /*
  * mbuf flag used by ip_fastfwd


More information about the svn-src-user mailing list