Author: kmacy
Date: Sun May  9 20:32:00 2010
New Revision: 207828
URL: http://svn.freebsd.org/changeset/base/207828

Log:
  Add flowtable support to IPv6
  
  Tested by: qingli@
  
  Reviewed by:  qingli@
  MFC after:    3 days

Modified:
  head/sys/netinet6/in6_proto.c
  head/sys/netinet6/ip6_input.c
  head/sys/netinet6/ip6_output.c
  head/sys/netinet6/udp6_usrreq.c

Modified: head/sys/netinet6/in6_proto.c
==============================================================================
--- head/sys/netinet6/in6_proto.c       Sun May  9 19:32:37 2010        
(r207827)
+++ head/sys/netinet6/in6_proto.c       Sun May  9 20:32:00 2010        
(r207828)
@@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_carp.h"
 #include "opt_sctp.h"
 #include "opt_mpath.h"
+#include "opt_route.h"
 
 #include <sys/param.h>
 #include <sys/socket.h>
@@ -130,6 +131,10 @@ __FBSDID("$FreeBSD$");
 
 #include <netinet6/ip6protosw.h>
 
+#ifdef FLOWTABLE
+#include <net/flowtable.h>
+#endif
+
 /*
  * TCP/IP protocol family: IP6, ICMP6, UDP, TCP.
  */
@@ -569,6 +574,16 @@ SYSCTL_VNET_INT(_net_inet6_ip6, IPV6CTL_
        &VNET_NAME(ip6stealth), 0, "");
 #endif
 
+#ifdef FLOWTABLE
+VNET_DEFINE(int, ip6_output_flowtable_size) = 2048;
+VNET_DEFINE(struct flowtable *, ip6_ft);
+#define        V_ip6_output_flowtable_size     VNET(ip6_output_flowtable_size)
+
+SYSCTL_VNET_INT(_net_inet6_ip6, OID_AUTO, output_flowtable_size, CTLFLAG_RDTUN,
+    &VNET_NAME(ip6_output_flowtable_size), 2048,
+    "number of entries in the per-cpu output flow caches");
+#endif
+
 /* net.inet6.icmp6 */
 SYSCTL_VNET_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRACCEPT, rediraccept,
        CTLFLAG_RW, &VNET_NAME(icmp6_rediraccept), 0, "");

Modified: head/sys/netinet6/ip6_input.c
==============================================================================
--- head/sys/netinet6/ip6_input.c       Sun May  9 19:32:37 2010        
(r207827)
+++ head/sys/netinet6/ip6_input.c       Sun May  9 20:32:00 2010        
(r207828)
@@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_inet.h"
 #include "opt_inet6.h"
 #include "opt_ipsec.h"
+#include "opt_route.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -113,6 +114,12 @@ __FBSDID("$FreeBSD$");
 
 #include <netinet6/ip6protosw.h>
 
+#ifdef FLOWTABLE
+#include <net/flowtable.h>
+extern VNET_DEFINE(int, ip6_output_flowtable_size);
+#define        V_ip6_output_flowtable_size     VNET(ip6_output_flowtable_size)
+#endif
+
 extern struct domain inet6domain;
 
 u_char ip6_protox[IPPROTO_MAX];
@@ -169,6 +176,12 @@ ip6_init(void)
        nd6_init();
        frag6_init();
 
+#ifdef FLOWTABLE
+       TUNABLE_INT_FETCH("net.inet6.ip6.output_flowtable_size",
+           &V_ip6_output_flowtable_size);
+       V_ip6_ft = flowtable_alloc("ipv6", V_ip6_output_flowtable_size, 
FL_PCPU);
+#endif 
+       
        V_ip6_desync_factor = arc4random() % MAX_TEMP_DESYNC_FACTOR;
 
        /* Skip global initialization stuff for non-default instances. */

Modified: head/sys/netinet6/ip6_output.c
==============================================================================
--- head/sys/netinet6/ip6_output.c      Sun May  9 19:32:37 2010        
(r207827)
+++ head/sys/netinet6/ip6_output.c      Sun May  9 20:32:00 2010        
(r207828)
@@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_inet6.h"
 #include "opt_ipsec.h"
 #include "opt_sctp.h"
+#include "opt_route.h"
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -111,6 +112,10 @@ __FBSDID("$FreeBSD$");
 #include <netinet6/ip6protosw.h>
 #include <netinet6/scope6_var.h>
 
+#ifdef FLOWTABLE
+#include <net/flowtable.h>
+#endif
+
 extern int in6_mcast_loop;
 
 struct ip6_exthdrs {
@@ -211,6 +216,7 @@ ip6_output(struct mbuf *m0, struct ip6_p
        struct in6_addr finaldst, src0, dst0;
        u_int32_t zone;
        struct route_in6 *ro_pmtu = NULL;
+       int flevalid = 0;
        int hdrsplit = 0;
        int needipsec = 0;
 #ifdef SCTP
@@ -231,9 +237,7 @@ ip6_output(struct mbuf *m0, struct ip6_p
        }
 
        finaldst = ip6->ip6_dst;
-
        bzero(&exthdrs, sizeof(exthdrs));
-
        if (opt) {
                /* Hop-by-Hop options header */
                MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh);
@@ -470,7 +474,22 @@ skip_ipsec2:;
        if (opt && opt->ip6po_rthdr)
                ro = &opt->ip6po_route;
        dst = (struct sockaddr_in6 *)&ro->ro_dst;
-
+#ifdef FLOWTABLE
+       if (ro == &ip6route) {
+               struct flentry *fle;
+               
+               /*
+                * The flow table returns route entries valid for up to 30
+                * seconds; we rely on the remainder of ip_output() taking no
+                * longer than that long for the stability of ro_rt.  The
+                * flow ID assignment must have happened before this point.
+                */
+               if ((fle = flowtable_lookup_mbuf(V_ip6_ft, m, AF_INET6)) != 
NULL) {
+                       flow_to_route_in6(fle, ro);
+                       flevalid = 1;
+               }
+       }
+#endif 
 again:
        /*
         * if specified, try to fill in the traffic class field.
@@ -576,7 +595,10 @@ again:
        dst_sa.sin6_family = AF_INET6;
        dst_sa.sin6_len = sizeof(dst_sa);
        dst_sa.sin6_addr = ip6->ip6_dst;
-       if ((error = in6_selectroute(&dst_sa, opt, im6o, ro,
+       if (flevalid) {
+               rt = ro->ro_rt;
+               ifp = ro->ro_rt->rt_ifp;
+       } else if ((error = in6_selectroute(&dst_sa, opt, im6o, ro,
            &ifp, &rt)) != 0) {
                switch (error) {
                case EHOSTUNREACH:
@@ -1071,9 +1093,11 @@ sendorfree:
                V_ip6stat.ip6s_fragmented++;
 
 done:
-       if (ro == &ip6route && ro->ro_rt) { /* brace necessary for RTFREE */
+       if (ro == &ip6route && ro->ro_rt && flevalid == 0) {
+                /* brace necessary for RTFREE */
                RTFREE(ro->ro_rt);
-       } else if (ro_pmtu == &ip6route && ro_pmtu->ro_rt) {
+       } else if (ro_pmtu == &ip6route && ro_pmtu->ro_rt &&
+           ((flevalid == 0) || (ro_pmtu != ro))) {
                RTFREE(ro_pmtu->ro_rt);
        }
 #ifdef IPSEC

Modified: head/sys/netinet6/udp6_usrreq.c
==============================================================================
--- head/sys/netinet6/udp6_usrreq.c     Sun May  9 19:32:37 2010        
(r207827)
+++ head/sys/netinet6/udp6_usrreq.c     Sun May  9 20:32:00 2010        
(r207828)
@@ -1079,7 +1079,9 @@ udp6_send(struct socket *so, int flags, 
        mac_inpcb_create_mbuf(inp, m);
 #endif
        error = udp6_output(inp, m, addr, control, td);
+#ifdef INET
 out:
+#endif 
        INP_WUNLOCK(inp);
        INP_INFO_WUNLOCK(&V_udbinfo);
        return (error);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to