Author: zec
Date: Mon Jun 22 21:19:24 2009
New Revision: 194660
URL: http://svn.freebsd.org/changeset/base/194660

Log:
  V_irtualize flowtable state.
  
  This change should make options VIMAGE kernel builds usable again,
  to some extent at least.
  
  Note that the size of struct vnet_inet has changed, though in
  accordance with one-bump-per-day policy we didn't update the
  __FreeBSD_version number, given that it has already been touched
  by r194640 a few hours ago.
  Reviewed by:  bz
  Approved by:  julian (mentor)

Modified:
  head/sys/net/flowtable.c
  head/sys/net/flowtable.h
  head/sys/netinet/ip_input.c
  head/sys/netinet/ip_output.c
  head/sys/netinet/vinet.h
  head/sys/sys/vimage.h

Modified: head/sys/net/flowtable.c
==============================================================================
--- head/sys/net/flowtable.c    Mon Jun 22 21:09:52 2009        (r194659)
+++ head/sys/net/flowtable.c    Mon Jun 22 21:19:24 2009        (r194660)
@@ -54,10 +54,8 @@ __FBSDID("$FreeBSD$");
 #include <net/if_llatbl.h>
 #include <net/if_var.h>
 #include <net/route.h> 
-#include <net/vnet.h>
 #include <net/flowtable.h>
 
-
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/in_var.h>
@@ -66,6 +64,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
 #include <netinet/sctp.h>
+#include <netinet/vinet.h>
 
 #include <libkern/jenkins.h>
 
@@ -165,10 +164,29 @@ struct flowtable {
 };
 
 static struct proc *flowcleanerproc;
+#ifdef VIMAGE_GLOBALS
 static struct flowtable *flow_list_head;
-static uint32_t hashjitter;
-static uma_zone_t ipv4_zone;
-static uma_zone_t ipv6_zone;
+static uint32_t flow_hashjitter;
+static uma_zone_t flow_ipv4_zone;
+static uma_zone_t flow_ipv6_zone;
+#endif
+
+static int     flowtable_iattach(const void *);
+#ifdef VIMAGE
+static int     flowtable_idetach(const void *);
+#endif
+
+#ifndef VIMAGE_GLOBALS
+static const vnet_modinfo_t flowtable_modinfo = {
+       .vmi_id         = VNET_MOD_FLOWTABLE,
+       .vmi_name       = "flowtable",
+       .vmi_dependson  = VNET_MOD_INET,
+       .vmi_iattach    = flowtable_iattach,
+#ifdef VIMAGE
+       .vmi_idetach    = flowtable_idetach
+#endif
+};
+#endif /* !VIMAGE_GLOBALS */
 
 /*
  * TODO:
@@ -185,49 +203,57 @@ static uma_zone_t ipv6_zone;
  *   of flows with flag to indicate that a flow was imported so should
  *   not be considered for auto-cleaning
  * - support explicit connection state (currently only ad-hoc for DSR)
+ * - idetach() cleanup for options VIMAGE builds.
  */
+#ifdef VIMAGE_GLOBALS
+int    flowtable_enable;
+static int flowtable_hits;
+static int flowtable_lookups;
+static int flowtable_misses;
+static int flowtable_frees;
+static int flowtable_free_checks;
+static int flowtable_max_depth;
+static int flowtable_collisions;
+static int flowtable_syn_expire;
+static int flowtable_udp_expire;
+static int flowtable_fin_wait_expire;
+static int flowtable_tcp_expire;
+static int flowtable_nmbflows;
+#endif
 SYSCTL_NODE(_net_inet, OID_AUTO, flowtable, CTLFLAG_RD, NULL, "flowtable");
-int    flowtable_enable = 1;
-SYSCTL_INT(_net_inet_flowtable, OID_AUTO, enable, CTLFLAG_RW,
-    &flowtable_enable, 0, "enable flowtable caching.");
-static int flowtable_hits = 0;
-SYSCTL_INT(_net_inet_flowtable, OID_AUTO, hits, CTLFLAG_RD,
-    &flowtable_hits, 0, "# flowtable hits.");
-static int flowtable_lookups = 0;
-SYSCTL_INT(_net_inet_flowtable, OID_AUTO, lookups, CTLFLAG_RD,
-    &flowtable_lookups, 0, "# flowtable lookups.");
-static int flowtable_misses = 0;
-SYSCTL_INT(_net_inet_flowtable, OID_AUTO, misses, CTLFLAG_RD,
-    &flowtable_misses, 0, "#flowtable misses.");
-static int flowtable_frees = 0;
-SYSCTL_INT(_net_inet_flowtable, OID_AUTO, frees, CTLFLAG_RD,
-    &flowtable_frees, 0, "#flows freed.");
-static int flowtable_free_checks = 0;
-SYSCTL_INT(_net_inet_flowtable, OID_AUTO, free_checks, CTLFLAG_RD,
-    &flowtable_free_checks, 0, "#flows free checks.");
-static int flowtable_max_depth = 0;
-SYSCTL_INT(_net_inet_flowtable, OID_AUTO, max_depth, CTLFLAG_RD,
-    &flowtable_max_depth, 0, "max collision list length.");
-static int flowtable_collisions = 0;
-SYSCTL_INT(_net_inet_flowtable, OID_AUTO, collisions, CTLFLAG_RD,
-    &flowtable_collisions, 0, "#flowtable collisions.");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, enable,
+    CTLFLAG_RW, flowtable_enable, 0, "enable flowtable caching.");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, hits,
+    CTLFLAG_RD, flowtable_hits, 0, "# flowtable hits.");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, lookups,
+    CTLFLAG_RD, flowtable_lookups, 0, "# flowtable lookups.");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, misses,
+    CTLFLAG_RD, flowtable_misses, 0, "#flowtable misses.");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, frees,
+    CTLFLAG_RD, flowtable_frees, 0, "#flows freed.");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, free_checks,
+    CTLFLAG_RD, flowtable_free_checks, 0, "#flows free checks.");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, max_depth,
+    CTLFLAG_RD, flowtable_max_depth, 0, "max collision list length.");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, collisions,
+    CTLFLAG_RD, flowtable_collisions, 0, "#flowtable collisions.");
 
 /*
  * XXX This does not end up updating timeouts at runtime
  * and only reflects the value for the last table added :-/
  */
-static int flowtable_syn_expire = SYN_IDLE;
-SYSCTL_INT(_net_inet_flowtable, OID_AUTO, syn_expire, CTLFLAG_RW,
-    &flowtable_syn_expire, 0, "seconds after which to remove syn allocated 
flow.");
-static int flowtable_udp_expire = UDP_IDLE;
-SYSCTL_INT(_net_inet_flowtable, OID_AUTO, udp_expire, CTLFLAG_RW,
-    &flowtable_udp_expire, 0, "seconds after which to remove flow allocated to 
UDP.");
-static int flowtable_fin_wait_expire = FIN_WAIT_IDLE;
-SYSCTL_INT(_net_inet_flowtable, OID_AUTO, fin_wait_expire, CTLFLAG_RW,
-    &flowtable_fin_wait_expire, 0, "seconds after which to remove a flow in 
FIN_WAIT.");
-static int flowtable_tcp_expire = TCP_IDLE;
-SYSCTL_INT(_net_inet_flowtable, OID_AUTO, tcp_expire, CTLFLAG_RW,
-    &flowtable_tcp_expire, 0, "seconds after which to remove flow allocated to 
a TCP connection.");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, syn_expire,
+    CTLFLAG_RW, flowtable_syn_expire, 0,
+    "seconds after which to remove syn allocated flow.");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, udp_expire,
+    CTLFLAG_RW, flowtable_udp_expire, 0,
+    "seconds after which to remove flow allocated to UDP.");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, fin_wait_expire,
+    CTLFLAG_RW, flowtable_fin_wait_expire, 0,
+    "seconds after which to remove a flow in FIN_WAIT.");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, tcp_expire,
+    CTLFLAG_RW, flowtable_tcp_expire, 0,
+    "seconds after which to remove flow allocated to a TCP connection.");
 
 
 /*
@@ -237,27 +263,29 @@ SYSCTL_INT(_net_inet_flowtable, OID_AUTO
  * there is no reason why this could not be changed at runtime)
  * and thus (currently) needs to be set with a tunable.
  */
-static int nmbflows = 4096;
-
 static int
 sysctl_nmbflows(SYSCTL_HANDLER_ARGS)
 {
+       INIT_VNET_INET(curvnet);
        int error, newnmbflows;
 
-       newnmbflows = nmbflows;
+       newnmbflows = V_flowtable_nmbflows;
        error = sysctl_handle_int(oidp, &newnmbflows, 0, req); 
        if (error == 0 && req->newptr) {
-               if (newnmbflows > nmbflows) {
-                       nmbflows = newnmbflows;
-                       uma_zone_set_max(ipv4_zone, nmbflows);
-                       uma_zone_set_max(ipv6_zone, nmbflows);
+               if (newnmbflows > V_flowtable_nmbflows) {
+                       V_flowtable_nmbflows = newnmbflows;
+                       uma_zone_set_max(V_flow_ipv4_zone,
+                           V_flowtable_nmbflows);
+                       uma_zone_set_max(V_flow_ipv6_zone,
+                           V_flowtable_nmbflows);
                } else
                        error = EINVAL;
        }
        return (error);
 }
-SYSCTL_PROC(_net_inet_flowtable, OID_AUTO, nmbflows, CTLTYPE_INT|CTLFLAG_RW,
-    &nmbflows, 0, sysctl_nmbflows, "IU", "Maximum number of flows allowed");
+SYSCTL_V_PROC(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, nmbflows,
+    CTLTYPE_INT|CTLFLAG_RW, flowtable_nmbflows, 0, sysctl_nmbflows, "IU",
+    "Maximum number of flows allowed");
 
 #ifndef RADIX_MPATH
 static void
@@ -310,6 +338,7 @@ static uint32_t
 ipv4_flow_lookup_hash_internal(struct mbuf *m, struct route *ro,
     uint32_t *key, uint16_t *flags, uint8_t *protop)
 {
+       INIT_VNET_INET(curvnet);
        uint16_t sport = 0, dport = 0;
        struct ip *ip = NULL;
        uint8_t proto = 0;
@@ -320,7 +349,7 @@ ipv4_flow_lookup_hash_internal(struct mb
        struct udphdr *uh;
        struct sctphdr *sh;
 
-       if (flowtable_enable == 0)
+       if (V_flowtable_enable == 0)
                return (0);
 
        key[1] = key[0] = 0;
@@ -382,7 +411,7 @@ ipv4_flow_lookup_hash_internal(struct mb
        ((uint16_t *)key)[1] = dport; 
 
 skipports:
-       hash = jenkins_hashword(key, 3, hashjitter + proto);
+       hash = jenkins_hashword(key, 3, V_flow_hashjitter + proto);
        if (m != NULL && (m->m_flags & M_FLOWID) == 0) {
                m->m_flags |= M_FLOWID;
                m->m_pkthdr.flowid = hash;
@@ -476,12 +505,13 @@ static int
 flowtable_insert(struct flowtable *ft, uint32_t hash, uint32_t *key,
     uint8_t proto, struct route *ro, uint16_t flags)
 {
+       INIT_VNET_INET(curvnet);
        struct flentry *fle, *fletail, *newfle, **flep;
        int depth;
        uma_zone_t flezone;
        bitstr_t *mask;
 
-       flezone = (flags & FL_IPV6) ? ipv6_zone : ipv4_zone;
+       flezone = (flags & FL_IPV6) ? V_flow_ipv6_zone : V_flow_ipv4_zone;
        newfle = uma_zalloc(flezone, M_NOWAIT | M_ZERO);
        if (newfle == NULL)
                return (ENOMEM);
@@ -500,7 +530,7 @@ flowtable_insert(struct flowtable *ft, u
        } 
        
        depth = 0;
-       flowtable_collisions++;
+       V_flowtable_collisions++;
        /*
         * find end of list and make sure that we were not
         * preempted by another thread handling this flow
@@ -513,7 +543,7 @@ flowtable_insert(struct flowtable *ft, u
                         */
                        FL_ENTRY_UNLOCK(ft, hash);
                        uma_zfree((newfle->f_flags & FL_IPV6) ?
-                           ipv6_zone : ipv4_zone, newfle);
+                           V_flow_ipv6_zone : V_flow_ipv4_zone, newfle);
                        return (EEXIST);
                }
                /*
@@ -526,8 +556,8 @@ flowtable_insert(struct flowtable *ft, u
                fle = fle->f_next;
        } 
 
-       if (depth > flowtable_max_depth)
-               flowtable_max_depth = depth;
+       if (depth > V_flowtable_max_depth)
+               V_flowtable_max_depth = depth;
        fletail->f_next = newfle;
        fle = newfle;
 skip:
@@ -566,6 +596,7 @@ flowtable_key_equal(struct flentry *fle,
 int
 flowtable_lookup(struct flowtable *ft, struct mbuf *m, struct route *ro)
 {
+       INIT_VNET_INET(curvnet);
        uint32_t key[9], hash;
        struct flentry *fle;
        uint16_t flags;
@@ -600,7 +631,7 @@ flowtable_lookup(struct flowtable *ft, s
        if (hash == 0 || (key[0] == 0 && (ft->ft_flags & FL_HASH_PORTS)))
                return (ENOENT);
 
-       flowtable_lookups++;
+       V_flowtable_lookups++;
        FL_ENTRY_LOCK(ft, hash);
        if ((fle = FL_ENTRY(ft, hash)) == NULL) {
                FL_ENTRY_UNLOCK(ft, hash);
@@ -615,7 +646,7 @@ keycheck:   
            && (proto == fle->f_proto)
            && (rt->rt_flags & RTF_UP)
            && (rt->rt_ifp != NULL)) {
-               flowtable_hits++;
+               V_flowtable_hits++;
                fle->f_uptime = time_uptime;
                fle->f_flags |= flags;
                ro->ro_rt = rt;
@@ -629,7 +660,7 @@ keycheck:   
        FL_ENTRY_UNLOCK(ft, hash);
 
 uncached:
-       flowtable_misses++;
+       V_flowtable_misses++;
        /*
         * This bit of code ends up locking the
         * same route 3 times (just like ip_output + ether_output)
@@ -687,11 +718,12 @@ uncached:
 struct flowtable *
 flowtable_alloc(int nentry, int flags)
 {
+       INIT_VNET_INET(curvnet);
        struct flowtable *ft, *fttail;
        int i;
 
-       if (hashjitter == 0)
-               hashjitter = arc4random();
+       if (V_flow_hashjitter == 0)
+               V_flow_hashjitter = arc4random();
 
        KASSERT(nentry > 0, ("nentry must be > 0, is %d\n", nentry));
 
@@ -739,10 +771,10 @@ flowtable_alloc(int nentry, int flags)
         * replacement after 5s of non-use
         */
        if (flags & FL_HASH_PORTS) {
-               ft->ft_udp_idle = flowtable_udp_expire;
-               ft->ft_syn_idle = flowtable_syn_expire;
-               ft->ft_fin_wait_idle = flowtable_fin_wait_expire;
-               ft->ft_tcp_idle = flowtable_fin_wait_expire;
+               ft->ft_udp_idle = V_flowtable_udp_expire;
+               ft->ft_syn_idle = V_flowtable_syn_expire;
+               ft->ft_fin_wait_idle = V_flowtable_fin_wait_expire;
+               ft->ft_tcp_idle = V_flowtable_fin_wait_expire;
        } else {
                ft->ft_udp_idle = ft->ft_fin_wait_idle =
                    ft->ft_syn_idle = ft->ft_tcp_idle = 30;
@@ -752,10 +784,10 @@ flowtable_alloc(int nentry, int flags)
        /*
         * hook in to the cleaner list
         */
-       if (flow_list_head == NULL)
-               flow_list_head = ft;
+       if (V_flow_list_head == NULL)
+               V_flow_list_head = ft;
        else {
-               fttail = flow_list_head;
+               fttail = V_flow_list_head;
                while (fttail->ft_next != NULL)
                        fttail = fttail->ft_next;
                fttail->ft_next = ft;
@@ -768,14 +800,53 @@ static void
 flowtable_setup(void *arg)
 {
 
-       ipv4_zone = uma_zcreate("ip4flow", sizeof(struct flentry_v4), NULL,
-           NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET);
-       ipv6_zone = uma_zcreate("ip6flow", sizeof(struct flentry_v6), NULL,
-           NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET);  
-       uma_zone_set_max(ipv4_zone, nmbflows);
-       uma_zone_set_max(ipv6_zone, nmbflows);
+#ifndef VIMAGE_GLOBALS
+       vnet_mod_register(&flowtable_modinfo);
+#else
+       flowtable_iattach(NULL);
+#endif
 }
 
+static int
+flowtable_iattach(const void *unused __unused)
+{
+       INIT_VNET_INET(curvnet);
+
+       V_flowtable_enable = 1;
+       V_flowtable_hits = 0;
+       V_flowtable_lookups = 0;
+       V_flowtable_misses = 0;
+       V_flowtable_frees = 0;
+       V_flowtable_free_checks = 0;
+       V_flowtable_max_depth = 0;
+       V_flowtable_collisions = 0;
+       V_flowtable_syn_expire = SYN_IDLE;
+       V_flowtable_udp_expire = UDP_IDLE;
+       V_flowtable_fin_wait_expire = FIN_WAIT_IDLE;
+       V_flowtable_tcp_expire = TCP_IDLE;
+       V_flowtable_nmbflows = 4096;
+
+       V_flow_ipv4_zone = uma_zcreate("ip4flow", sizeof(struct flentry_v4),
+           NULL, NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET);
+       V_flow_ipv6_zone = uma_zcreate("ip6flow", sizeof(struct flentry_v6),
+           NULL, NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET);    
+       uma_zone_set_max(V_flow_ipv4_zone, V_flowtable_nmbflows);
+       uma_zone_set_max(V_flow_ipv6_zone, V_flowtable_nmbflows);
+       return (0);
+}
+
+#ifdef VIMAGE
+static int
+flowtable_idetach(const void *unused __unused)
+{
+       INIT_VNET_INET(curvnet);
+
+       uma_zdestroy(V_flow_ipv4_zone);
+       uma_zdestroy(V_flow_ipv6_zone);
+       return (0);
+}
+#endif
+
 SYSINIT(flowtable_setup, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, flowtable_setup, 
NULL);
 
 /*
@@ -787,6 +858,7 @@ SYSINIT(flowtable_setup, SI_SUB_KTHREAD_
 static void
 fle_free(struct flentry *fle)
 {
+       INIT_VNET_INET(curvnet);
        struct rtentry *rt;
        struct llentry *lle;
 
@@ -794,12 +866,14 @@ fle_free(struct flentry *fle)
        lle = __DEVOLATILE(struct llentry *, fle->f_lle);
        RTFREE(rt);
        LLE_FREE(lle);
-       uma_zfree((fle->f_flags & FL_IPV6) ? ipv6_zone : ipv4_zone, fle);
+       uma_zfree((fle->f_flags & FL_IPV6) ?
+           V_flow_ipv6_zone : V_flow_ipv4_zone, fle);
 }
 
 static void
 flowtable_free_stale(struct flowtable *ft)
 {
+       INIT_VNET_INET(curvnet);
        int curbit = 0, count;
        struct flentry *fle,  **flehead, *fleprev;
        struct flentry *flefreehead, *flefreetail, *fletmp;
@@ -826,7 +900,7 @@ flowtable_free_stale(struct flowtable *f
                flehead = flowtable_entry(ft, curbit);
                fle = fleprev = *flehead;
 
-               flowtable_free_checks++;
+               V_flowtable_free_checks++;
 #ifdef DIAGNOSTIC
                if (fle == NULL && curbit > 0) {
                        log(LOG_ALERT,
@@ -877,7 +951,7 @@ flowtable_free_stale(struct flowtable *f
        while ((fle = flefreehead) != NULL) {
                flefreehead = fle->f_next;
                count++;
-               flowtable_frees++;
+               V_flowtable_frees++;
                fle_free(fle);
        }
        if (bootverbose && count)
@@ -885,36 +959,52 @@ flowtable_free_stale(struct flowtable *f
 }
 
 static void
-flowtable_cleaner(void)
+flowtable_clean_vnet(void)
 {
+       INIT_VNET_INET(curvnet);
        struct flowtable *ft;
        int i;
 
+       ft = V_flow_list_head;
+       while (ft != NULL) {
+               if (ft->ft_flags & FL_PCPU) {
+                       for (i = 0; i <= mp_maxid; i++) {
+                               if (CPU_ABSENT(i))
+                                       continue;
+
+                               thread_lock(curthread);
+                               sched_bind(curthread, i);
+                               thread_unlock(curthread);
+
+                               flowtable_free_stale(ft);
+
+                               thread_lock(curthread);
+                               sched_unbind(curthread);
+                               thread_unlock(curthread);
+                       }
+               } else {
+                       flowtable_free_stale(ft);
+               }
+               ft = ft->ft_next;
+       }
+}
+
+static void
+flowtable_cleaner(void)
+{
+       VNET_ITERATOR_DECL(vnet_iter);
+
        if (bootverbose)
                log(LOG_INFO, "flowtable cleaner started\n");
        while (1) {
-               ft = flow_list_head;
-               while (ft != NULL) {
-                       if (ft->ft_flags & FL_PCPU) {
-                               for (i = 0; i <= mp_maxid; i++) {
-                                       if (CPU_ABSENT(i))
-                                               continue;
-
-                                       thread_lock(curthread);
-                                       sched_bind(curthread, i);
-                                       thread_unlock(curthread);
-
-                                       flowtable_free_stale(ft);
-
-                                       thread_lock(curthread);
-                                       sched_unbind(curthread);
-                                       thread_unlock(curthread);
-                               }
-                       } else {
-                               flowtable_free_stale(ft);
-                       }
-                       ft = ft->ft_next;
+               VNET_LIST_RLOCK();
+               VNET_FOREACH(vnet_iter) {
+                       CURVNET_SET(vnet_iter);
+                       flowtable_clean_vnet();
+                       CURVNET_RESTORE();
                }
+               VNET_LIST_RUNLOCK();
+
                /*
                 * The 20 second interval between cleaning checks
                 * is arbitrary

Modified: head/sys/net/flowtable.h
==============================================================================
--- head/sys/net/flowtable.h    Mon Jun 22 21:09:52 2009        (r194659)
+++ head/sys/net/flowtable.h    Mon Jun 22 21:19:24 2009        (r194660)
@@ -38,7 +38,9 @@ $FreeBSD$
 #define        FL_PCPU         (1<<1)  /* pcpu cache */
 
 struct flowtable;
+#ifdef VIMAGE_GLOBALS
 extern struct flowtable *ip_ft;
+#endif
 
 struct flowtable *flowtable_alloc(int nentry, int flags);
 

Modified: head/sys/netinet/ip_input.c
==============================================================================
--- head/sys/netinet/ip_input.c Mon Jun 22 21:09:52 2009        (r194659)
+++ head/sys/netinet/ip_input.c Mon Jun 22 21:19:24 2009        (r194660)
@@ -207,13 +207,13 @@ SYSCTL_V_INT(V_NET, vnet_inet, _net_inet
     ipstealth, 0, "IP stealth mode, no TTL decrementation on forwarding");
 #endif
 #ifdef FLOWTABLE
-static int ip_output_flowtable_size = 2048;
-TUNABLE_INT("net.inet.ip.output_flowtable_size", &ip_output_flowtable_size);
+#ifdef VIMAGE_GLOBALS
+static int ip_output_flowtable_size;
+struct flowtable *ip_ft;
+#endif
 SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip, OID_AUTO, output_flowtable_size,
     CTLFLAG_RDTUN, ip_output_flowtable_size, 2048,
     "number of entries in the per-cpu output flow caches");
-
-struct flowtable *ip_ft;
 #endif
 
 #ifdef VIMAGE_GLOBALS
@@ -335,6 +335,13 @@ ip_init(void)
            NULL, UMA_ALIGN_PTR, 0);
        maxnipq_update();
 
+#ifdef FLOWTABLE
+       V_ip_output_flowtable_size = 2048;
+       TUNABLE_INT_FETCH("net.inet.ip.output_flowtable_size",
+           &V_ip_output_flowtable_size);
+       V_ip_ft = flowtable_alloc(V_ip_output_flowtable_size, FL_PCPU);
+#endif
+
        /* Skip initialization of globals for non-default instances. */
        if (!IS_DEFAULT_VNET(curvnet))
                return;
@@ -377,9 +384,6 @@ ip_init(void)
        /* Initialize various other remaining things. */
        IPQ_LOCK_INIT();
        netisr_register(&ip_nh);
-#ifdef FLOWTABLE
-       ip_ft = flowtable_alloc(ip_output_flowtable_size, FL_PCPU);
-#endif
 }
 
 void

Modified: head/sys/netinet/ip_output.c
==============================================================================
--- head/sys/netinet/ip_output.c        Mon Jun 22 21:09:52 2009        
(r194659)
+++ head/sys/netinet/ip_output.c        Mon Jun 22 21:19:24 2009        
(r194660)
@@ -162,7 +162,7 @@ ip_output(struct mbuf *m, struct mbuf *o
                 * longer than that long for the stability of ro_rt.  The
                 * flow ID assignment must have happened before this point.
                 */
-               if (flowtable_lookup(ip_ft, m, ro) == 0)
+               if (flowtable_lookup(V_ip_ft, m, ro) == 0)
                        nortfree = 1;
 #endif
        }

Modified: head/sys/netinet/vinet.h
==============================================================================
--- head/sys/netinet/vinet.h    Mon Jun 22 21:09:52 2009        (r194659)
+++ head/sys/netinet/vinet.h    Mon Jun 22 21:19:24 2009        (r194660)
@@ -212,6 +212,25 @@ struct vnet_inet {
        int                     _icmpbmcastecho;
 
        int                     _fw_one_pass;
+
+       struct flowtable *      _ip_ft;
+       struct flowtable *      _flow_list_head;
+       uint32_t                _flow_hashjitter;
+       uma_zone_t              _flow_ipv4_zone;
+       uma_zone_t              _flow_ipv6_zone;
+       int                     _flowtable_enable;
+       int                     _flowtable_hits;
+       int                     _flowtable_lookups;
+       int                     _flowtable_misses;
+       int                     _flowtable_frees;
+       int                     _flowtable_free_checks;
+       int                     _flowtable_max_depth;
+       int                     _flowtable_collisions;
+       int                     _flowtable_syn_expire;
+       int                     _flowtable_udp_expire;
+       int                     _flowtable_fin_wait_expire;
+       int                     _flowtable_tcp_expire;
+       int                     _flowtable_nmbflows;
 };
 
 /* Size guard. See sys/vimage.h. */
@@ -240,6 +259,23 @@ extern struct vnet_inet vnet_inet_0;
 #define        V_drop_redirect         VNET_INET(drop_redirect)
 #define        V_drop_synfin           VNET_INET(drop_synfin)
 #define        V_fw_one_pass           VNET_INET(fw_one_pass)
+#define        V_flow_hashjitter       VNET_INET(flow_hashjitter)
+#define        V_flow_ipv4_zone        VNET_INET(flow_ipv4_zone)
+#define        V_flow_ipv6_zone        VNET_INET(flow_ipv6_zone)
+#define        V_flow_list_head        VNET_INET(flow_list_head)
+#define        V_flowtable_collisions  VNET_INET(flowtable_collisions)
+#define        V_flowtable_enable      VNET_INET(flowtable_enable)
+#define        V_flowtable_fin_wait_expire VNET_INET(flowtable_fin_wait_expire)
+#define        V_flowtable_free_checks VNET_INET(flowtable_free_checks)
+#define        V_flowtable_frees       VNET_INET(flowtable_frees)
+#define        V_flowtable_hits        VNET_INET(flowtable_hits)
+#define        V_flowtable_lookups     VNET_INET(flowtable_lookups)
+#define        V_flowtable_max_depth   VNET_INET(flowtable_max_depth)
+#define        V_flowtable_misses      VNET_INET(flowtable_misses)
+#define        V_flowtable_nmbflows    VNET_INET(flowtable_nmbflows)
+#define        V_flowtable_syn_expire  VNET_INET(flowtable_syn_expire)
+#define        V_flowtable_tcp_expire  VNET_INET(flowtable_tcp_expire)
+#define        V_flowtable_udp_expire  VNET_INET(flowtable_udp_expire)
 #define        V_icmp_may_rst          VNET_INET(icmp_may_rst)
 #define        V_icmp_quotelen         VNET_INET(icmp_quotelen)
 #define        V_icmp_rfi              VNET_INET(icmp_rfi)
@@ -272,9 +308,11 @@ extern struct vnet_inet vnet_inet_0;
 #define        V_ip_checkinterface     VNET_INET(ip_checkinterface)
 #define        V_ip_defttl             VNET_INET(ip_defttl)
 #define        V_ip_do_randomid        VNET_INET(ip_do_randomid)
+#define        V_ip_ft                 VNET_INET(ip_ft)
 #define        V_ip_id                 VNET_INET(ip_id)
 #define        V_ip_keepfaith          VNET_INET(ip_keepfaith)
 #define        V_ip_mrouter            VNET_INET(ip_mrouter)
+#define        V_ip_output_flowtable_size VNET_INET(ip_output_flowtable_size)
 #define        V_ip_rsvp_on            VNET_INET(ip_rsvp_on)
 #define        V_ip_rsvpd              VNET_INET(ip_rsvpd)
 #define        V_ip_sendsourcequench   VNET_INET(ip_sendsourcequench)

Modified: head/sys/sys/vimage.h
==============================================================================
--- head/sys/sys/vimage.h       Mon Jun 22 21:09:52 2009        (r194659)
+++ head/sys/sys/vimage.h       Mon Jun 22 21:19:24 2009        (r194660)
@@ -135,7 +135,7 @@ struct vnet_modlink {
 #define        VNET_MOD_IPCOMP         26      
 #define        VNET_MOD_GIF            27
 #define        VNET_MOD_ARP            28
-               /*              29 */
+#define        VNET_MOD_FLOWTABLE      29
 #define        VNET_MOD_LOIF           30
 #define        VNET_MOD_DOMAIN         31
 #define        VNET_MOD_DYNAMIC_START  32
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to