svn commit: r184383 - in user/kmacy/HEAD_fast_xmit/sys: net netinet
Kip Macy
kmacy at FreeBSD.org
Tue Oct 28 01:21:19 UTC 2008
Author: kmacy
Date: Tue Oct 28 01:21:19 2008
New Revision: 184383
URL: http://svn.freebsd.org/changeset/base/184383
Log:
- simplify validation in flow_lookup
- rename and invert sense of FL_LOCAL_XMIT to FL_HASH_PORTS for clarity
- add route validation to flow_stale
- add flag to disable flowtable usage
- add explanation of hideousness of route + arp lookup locking
- make hashjitter a static so as not to rely on RADIX_MPATH being enabled
Modified:
user/kmacy/HEAD_fast_xmit/sys/net/flowtable.c
user/kmacy/HEAD_fast_xmit/sys/net/flowtable.h
user/kmacy/HEAD_fast_xmit/sys/net/radix_mpath.c
user/kmacy/HEAD_fast_xmit/sys/netinet/ip_input.c
Modified: user/kmacy/HEAD_fast_xmit/sys/net/flowtable.c
==============================================================================
--- user/kmacy/HEAD_fast_xmit/sys/net/flowtable.c Mon Oct 27 23:11:14 2008 (r184382)
+++ user/kmacy/HEAD_fast_xmit/sys/net/flowtable.c Tue Oct 28 01:21:19 2008 (r184383)
@@ -269,7 +269,8 @@ struct flowtable {
};
-extern uint32_t hashjitter;
+static uint32_t hashjitter;
+static int flowtable_disable;
static void
in_rtalloc_ign_wrapper(struct route *ro, uint32_t hash, u_int fib)
@@ -337,6 +338,9 @@ ipv4_flow_lookup_hash_internal(struct mb
sin->sin_len = sizeof(*sin);
sin->sin_addr = ip->ip_dst;
+ if (flowtable_disable)
+ return (0);
+
switch (proto) {
case IPPROTO_TCP:
th = (struct tcphdr *)((caddr_t)ip + iphlen);
@@ -369,7 +373,7 @@ ipv4_flow_lookup_hash_internal(struct mb
* hash all flows to a given destination to
* the same bucket
*/
- if (*flags & FL_LOCAL_XMIT)
+ if ((*flags & FL_HASH_PORTS) == 0)
proto = sport = dport = 0;
((uint16_t *)key)[0] = sport;
@@ -423,9 +427,13 @@ flow_stale(struct flowtable *ft, struct
{
time_t idle_time;
- if (fle->f_fhash == 0)
+ if ((fle->f_fhash == 0)
+ || ((fle->f_rt->rt_flags & RTF_UP) == 0)
+ || (fle->f_uptime <= fle->f_rt->rt_llinfo_uptime)
+ || ((fle->f_rt->rt_flags & RTF_GATEWAY) &&
+ ((fle->f_rt->rt_gwroute->rt_flags & RTF_UP) == 0)))
return (1);
-
+
idle_time = time_uptime - fle->f_uptime;
if ((fle->f_flags & FL_STALE) ||
@@ -553,12 +561,12 @@ flowtable_lookup(struct flowtable *ft, s
uint32_t key[9], hash;
struct flentry *fle;
uint16_t flags;
- uint8_t proto;
+ uint8_t proto = 0;
struct route ro;
int cache = 1, error = 0;
u_char desten[ETHER_ADDR_LEN];
- flags = ft ? ft->ft_flags : FL_LOCAL_XMIT;
+ flags = ft ? ft->ft_flags : 0;
/*
* The internal hash lookup is the only IPv4 specific bit
@@ -572,19 +580,16 @@ flowtable_lookup(struct flowtable *ft, s
* Ports are zero and this isn't a transmit cache
* - thus not a protocol for which we need to keep
* statex
- * FL_LOCAL_XMIT => key[0] == 0
+ * FL_HASH_PORTS => key[0] != 0 for TCP || UDP || SCTP
*/
- if (hash == 0 || (key[0] == 0 && (ft->ft_flags & FL_LOCAL_XMIT) == 0)) {
+ if (hash == 0 || (key[0] == 0 && (ft->ft_flags & FL_HASH_PORTS))) {
cache = 0;
goto uncached;
}
FL_ENTRY_LOCK(ft, hash);
fle = FL_ENTRY(ft, hash);
- if (fle->f_fhash != hash) {
- cache = !flow_stale(ft, fle);
- FL_ENTRY_UNLOCK(ft, hash);
- } else if (fle->f_fhash == hash
+ if (fle->f_fhash == hash
&& flowtable_key_equal(fle, key, flags)
&& (proto == fle->f_proto)
&& (fle->f_rt->rt_flags & RTF_UP)
@@ -601,7 +606,20 @@ flowtable_lookup(struct flowtable *ft, s
FL_ENTRY_UNLOCK(ft, hash);
return (0);
}
+ FL_ENTRY_UNLOCK(ft, hash);
+
uncached:
+ /*
+ * This bit of code ends up locking the
+ * same route 3 times (just like ip_output + ether_output)
+ * - at lookup
+ * - in rt_check when called by arpresolve
+ * - dropping the refcount for the rtentry
+ *
+ * This could be consolidated to one if we wrote a variant
+ * of arpresolve with an rt_check variant that expected to
+ * receive the route locked
+ */
ft->ft_rtalloc(&ro, hash, M_GETFIB(m));
if (ro.ro_rt == NULL)
error = ENETUNREACH;
@@ -643,6 +661,9 @@ flowtable_alloc(int nentry, int flags)
struct flowtable *ft;
int i;
+ if (hashjitter == 0)
+ hashjitter = arc4random();
+
ft = malloc(sizeof(struct flowtable),
M_RTABLE, M_WAITOK | M_ZERO);
@@ -685,15 +706,17 @@ flowtable_alloc(int nentry, int flags)
* just a cache - so everything is eligible for
* replacement after 5s of non-use
*/
- if (flags & FL_LOCAL_XMIT)
- ft->ft_udp_idle = ft->ft_fin_wait_idle =
- ft->ft_syn_idle = ft->ft_tcp_idle = 5;
- else {
+ if (flags & FL_HASH_PORTS) {
ft->ft_udp_idle = UDP_IDLE;
ft->ft_syn_idle = SYN_IDLE;
ft->ft_fin_wait_idle = FIN_WAIT_IDLE;
ft->ft_tcp_idle = TCP_IDLE;
+ } else {
+ ft->ft_udp_idle = ft->ft_fin_wait_idle =
+ ft->ft_syn_idle = ft->ft_tcp_idle = 5;
+
}
+
return (ft);
}
Modified: user/kmacy/HEAD_fast_xmit/sys/net/flowtable.h
==============================================================================
--- user/kmacy/HEAD_fast_xmit/sys/net/flowtable.h Mon Oct 27 23:11:14 2008 (r184382)
+++ user/kmacy/HEAD_fast_xmit/sys/net/flowtable.h Tue Oct 28 01:21:19 2008 (r184383)
@@ -5,7 +5,7 @@
#include <net/ethernet.h>
#include <netinet/in.h>
-#define FL_LOCAL_XMIT (1<<0) /* per host, don't hash ports */
+#define FL_HASH_PORTS (1<<0) /* hash 4-tuple + protocol */
#define FL_PCPU (1<<1) /* pcpu cache */
#define FL_IPV6 (1<<2) /* IPv6 table */
Modified: user/kmacy/HEAD_fast_xmit/sys/net/radix_mpath.c
==============================================================================
--- user/kmacy/HEAD_fast_xmit/sys/net/radix_mpath.c Mon Oct 27 23:11:14 2008 (r184382)
+++ user/kmacy/HEAD_fast_xmit/sys/net/radix_mpath.c Tue Oct 28 01:21:19 2008 (r184383)
@@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
/*
* give some jitter to hash, to avoid synchronization between routers
*/
-uint32_t hashjitter;
+static uint32_t hashjitter;
int
rn_mpath_capable(struct radix_node_head *rnh)
Modified: user/kmacy/HEAD_fast_xmit/sys/netinet/ip_input.c
==============================================================================
--- user/kmacy/HEAD_fast_xmit/sys/netinet/ip_input.c Mon Oct 27 23:11:14 2008 (r184382)
+++ user/kmacy/HEAD_fast_xmit/sys/netinet/ip_input.c Tue Oct 28 01:21:19 2008 (r184383)
@@ -280,7 +280,7 @@ ip_init(void)
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);
+ ipv4_ft = flowtable_alloc(2048, FL_PCPU);
}
void
More information about the svn-src-user
mailing list