svn commit: r189332 - in user/kmacy/HEAD_fast_net_merge/sys: net netinet

Kip Macy kmacy at FreeBSD.org
Tue Mar 3 17:33:17 PST 2009


Author: kmacy
Date: Wed Mar  4 01:33:16 2009
New Revision: 189332
URL: http://svn.freebsd.org/changeset/base/189332

Log:
   extend flowtable usage to other areas
  186585, 186621, 186629, 186631
  
  186585:
  -  make ipv4 forwarding flowtable aware
  
  186621:
  - initialize ro_dst at the beginning of ip_forward
  
  186629:
  - make flowtable_lookup handle case of NULL mbuf
  
  186631:
  - use flowtable_lookup in in_pcbladdr to avoid
    contending in calls to in_pcbconnect_setup
    when the laddr is not bound

Modified:
  user/kmacy/HEAD_fast_net_merge/sys/net/flowtable.c
  user/kmacy/HEAD_fast_net_merge/sys/netinet/in_pcb.c
  user/kmacy/HEAD_fast_net_merge/sys/netinet/ip_input.c

Modified: user/kmacy/HEAD_fast_net_merge/sys/net/flowtable.c
==============================================================================
--- user/kmacy/HEAD_fast_net_merge/sys/net/flowtable.c	Wed Mar  4 01:31:09 2009	(r189331)
+++ user/kmacy/HEAD_fast_net_merge/sys/net/flowtable.c	Wed Mar  4 01:33:16 2009	(r189332)
@@ -334,26 +334,32 @@ ipv4_flow_lookup_hash_internal(struct mb
     uint32_t *key, uint16_t *flags, uint8_t *protop)
 {
 	uint16_t sport = 0, dport = 0;
-	struct ip *ip = mtod(m, struct ip *);
-	uint8_t proto = ip->ip_p;
-	int iphlen = ip->ip_hl << 2;
+	struct ip *ip;
+	uint8_t proto = 0;
+	int iphlen;
 	uint32_t hash;
 	struct sockaddr_in *sin;
 	struct tcphdr *th;
 	struct udphdr *uh;
 	struct sctphdr *sh;
 
-	key[0] = 0;
-	key[1] = ip->ip_src.s_addr;
-	key[2] = ip->ip_dst.s_addr;	
+	if (flowtable_enable == 0)
+		return (0);
 
 	sin = (struct sockaddr_in *)&ro->ro_dst;
-	sin->sin_family = AF_INET;
-	sin->sin_len = sizeof(*sin);
-	sin->sin_addr = ip->ip_dst;
+	KASSERT(sin->sin_family == AF_INET,
+	    ("bad address passed"));
+	key[0] = 0;
+	key[1] = 0;
+	key[2] = sin->sin_addr.s_addr;
 
-	if (flowtable_enable == 0)
-		return (0);
+	if (m == NULL || (*flags & FL_HASH_PORTS) == 0)
+		goto skipports;
+
+	ip = mtod(m, struct ip *);
+	proto = ip->ip_p;
+	iphlen = ip->ip_hl << 2; /* XXX options? */
+	key[1] = ip->ip_src.s_addr;
 	
 	switch (proto) {
 	case IPPROTO_TCP:
@@ -394,8 +400,13 @@ ipv4_flow_lookup_hash_internal(struct mb
 	((uint16_t *)key)[0] = sport;
 	((uint16_t *)key)[1] = dport; 
 
+skipports:
 	hash = hashword(key, 3, hashjitter + proto);
-	if (m->m_pkthdr.flowid == 0)
+#ifdef notyet
+	if (m != NULL && (m->m_flags & M_FLOWID) == 0)
+#else
+	if (m != NULL && m->m_pkthdr.flowid != 0)
+#endif
 		m->m_pkthdr.flowid = hash;
 	
 	CTR5(KTR_SPARE3, "proto=%d hash=%x key[0]=%x sport=%d dport=%d\n", proto, hash, key[0], sport, dport);
@@ -564,7 +575,7 @@ flowtable_lookup(struct flowtable *ft, s
 	struct flentry *fle;
 	uint16_t flags;
 	uint8_t proto = 0;
-	int cache = 1, error = 0;
+	int cache = 1, error = 0, fib = 0;
 	struct rtentry *rt;
 	struct llentry *lle;
 
@@ -620,7 +631,10 @@ uncached:
 	 * of arpresolve with an rt_check variant that expected to
 	 * receive the route locked
 	 */
-	ft->ft_rtalloc(ro, hash, M_GETFIB(m));
+	if (m != NULL)
+		fib = M_GETFIB(m);
+
+	ft->ft_rtalloc(ro, hash, fib);
 	if (ro->ro_rt == NULL) 
 		error = ENETUNREACH;
 	else {

Modified: user/kmacy/HEAD_fast_net_merge/sys/netinet/in_pcb.c
==============================================================================
--- user/kmacy/HEAD_fast_net_merge/sys/netinet/in_pcb.c	Wed Mar  4 01:31:09 2009	(r189331)
+++ user/kmacy/HEAD_fast_net_merge/sys/netinet/in_pcb.c	Wed Mar  4 01:33:16 2009	(r189332)
@@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_types.h>
 #include <net/if_llatbl.h>
 #include <net/route.h>
+#include <net/flowtable.h>
 
 #include <netinet/in.h>
 #include <netinet/in_pcb.h>
@@ -88,6 +89,7 @@ __FBSDID("$FreeBSD$");
 
 #include <security/mac/mac_framework.h>
 
+extern struct flowtable *ipv4_ft;
 #ifdef VIMAGE_GLOBALS
 /*
  * These configure the range of local port addresses assigned to
@@ -643,11 +645,14 @@ in_pcbladdr(struct inpcb *inp, struct in
 	 * If route is known our src addr is taken from the i/f,
 	 * else punt.
 	 *
+	 * XXX need to account for fibnum
 	 * Find out route to destination.
 	 */
 	if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0)
+		flowtable_lookup(ipv4_ft, NULL, &sro);
+#if 0	
 		in_rtalloc_ign(&sro, 0, inp->inp_inc.inc_fibnum);
-
+#endif
 	/*
 	 * If we found a route, use the address corresponding to
 	 * the outgoing interface.
@@ -811,8 +816,6 @@ in_pcbladdr(struct inpcb *inp, struct in
 	}
 
 done:
-	if (sro.ro_rt != NULL)
-		RTFREE(sro.ro_rt);
 	return (error);
 }
 

Modified: user/kmacy/HEAD_fast_net_merge/sys/netinet/ip_input.c
==============================================================================
--- user/kmacy/HEAD_fast_net_merge/sys/netinet/ip_input.c	Wed Mar  4 01:31:09 2009	(r189331)
+++ user/kmacy/HEAD_fast_net_merge/sys/netinet/ip_input.c	Wed Mar  4 01:33:16 2009	(r189332)
@@ -1349,8 +1349,10 @@ ip_forward(struct mbuf *m, int srcrt)
 	struct in_ifaddr *ia = NULL;
 	struct mbuf *mcopy;
 	struct in_addr dest;
+	struct sockaddr_in *sin;
 	struct route ro;
 	int error, type = 0, code = 0, mtu = 0;
+	int flerror;
 
 	if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(ip->ip_dst) == 0) {
 		V_ipstat.ips_cantforward++;
@@ -1368,8 +1370,18 @@ ip_forward(struct mbuf *m, int srcrt)
 #ifdef IPSTEALTH
 	}
 #endif
+	bzero(&ro, sizeof(ro));
+	sin = (struct sockaddr_in *)&ro.ro_dst;
+	sin->sin_family = AF_INET;
+	sin->sin_len = sizeof(*sin);
+	sin->sin_addr = ip->ip_dst;
+	
+	flerror = flowtable_lookup(ipv4_forward_ft, m, &ro);
+	if (flerror == 0)
+		ia = ifatoia(ro.ro_rt->rt_ifa);
+	else
+		ia = ip_rtaddr(ip->ip_dst, M_GETFIB(m));
 
-	ia = ip_rtaddr(ip->ip_dst, M_GETFIB(m));
 	if (!srcrt && ia == NULL) {
 		icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
 		return;
@@ -1426,19 +1438,15 @@ ip_forward(struct mbuf *m, int srcrt)
 	 */
 	dest.s_addr = 0;
 	if (!srcrt && V_ipsendredirects && ia->ia_ifp == m->m_pkthdr.rcvif) {
-		struct sockaddr_in *sin;
 		struct rtentry *rt;
 
-		bzero(&ro, sizeof(ro));
-		sin = (struct sockaddr_in *)&ro.ro_dst;
-		sin->sin_family = AF_INET;
-		sin->sin_len = sizeof(*sin);
-		sin->sin_addr = ip->ip_dst;
-		in_rtalloc_ign(&ro, 0, M_GETFIB(m));
+		if (flerror != 0)
+			in_rtalloc_ign(&ro, 0, M_GETFIB(m));
 
 		rt = ro.ro_rt;
 
-		if (rt && (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 &&
+		if (rt != NULL &&
+		    (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 &&
 		    satosin(rt_key(rt))->sin_addr.s_addr != 0) {
 #define	RTA(rt)	((struct in_ifaddr *)(rt->rt_ifa))
 			u_long src = ntohl(ip->ip_src.s_addr);
@@ -1454,7 +1462,7 @@ ip_forward(struct mbuf *m, int srcrt)
 				code = ICMP_REDIRECT_HOST;
 			}
 		}
-		if (rt)
+		if (rt && (flerror != 0))
 			RTFREE(rt);
 	}
 
@@ -1462,13 +1470,14 @@ ip_forward(struct mbuf *m, int srcrt)
 	 * Try to cache the route MTU from ip_output so we can consider it for
 	 * the ICMP_UNREACH_NEEDFRAG "Next-Hop MTU" field described in RFC1191.
 	 */
-	bzero(&ro, sizeof(ro));
+	if (flerror != 0)
+		bzero(&ro, sizeof(ro));
 
 	error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL, NULL);
 
 	if (error == EMSGSIZE && ro.ro_rt)
 		mtu = ro.ro_rt->rt_rmx.rmx_mtu;
-	if (ro.ro_rt)
+	if (ro.ro_rt && flerror != 0)
 		RTFREE(ro.ro_rt);
 
 	if (error)


More information about the svn-src-user mailing list