Add flowtable support to IPv6
Tested by: qingli@ Reviewed by: qingli@ MFC after: 3 days
This commit is contained in:
parent
cd06f6e065
commit
77931dd513
@ -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_STEALTH, stealth, CTLFLAG_RW,
|
||||
&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, "");
|
||||
|
@ -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. */
|
||||
|
@ -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_pktopts *opt,
|
||||
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_pktopts *opt,
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -1079,7 +1079,9 @@ udp6_send(struct socket *so, int flags, struct mbuf *m,
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user