summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkmacy <kmacy@FreeBSD.org>2009-04-19 04:44:05 +0000
committerkmacy <kmacy@FreeBSD.org>2009-04-19 04:44:05 +0000
commit96ce69a748787b032fef633aec21d684b2eefe8a (patch)
treedf39cf96cca8e7716158c26f1fa8e64dc725144e
parent2160bcc98c432a34104be13d4b41316bb8da6338 (diff)
downloadFreeBSD-src-96ce69a748787b032fef633aec21d684b2eefe8a.zip
FreeBSD-src-96ce69a748787b032fef633aec21d684b2eefe8a.tar.gz
- Allocate a small flowtable in ip_input.c (changeable by tuneable)
- Use for accelerating ip_output
-rw-r--r--sys/netinet/ip_input.c9
-rw-r--r--sys/netinet/ip_output.c11
-rw-r--r--sys/netinet/vinet.h1
3 files changed, 19 insertions, 2 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 920d741..2db3afb 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <net/route.h>
#include <net/netisr.h>
#include <net/vnet.h>
+#include <net/flowtable.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -211,6 +212,11 @@ SYSCTL_INT(_net_inet_ip, IPCTL_DEFMTU, mtu, CTLFLAG_RW,
SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip, OID_AUTO, stealth, CTLFLAG_RW,
ipstealth, 0, "IP stealth mode, no TTL decrementation on forwarding");
#endif
+static int ip_output_flowtable_size = 2048;
+TUNABLE_INT("net.inet.ip.output_flowtable_size", &ip_output_flowtable_size);
+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");
/*
* ipfw_ether and ipfw_bridge hooks.
@@ -221,6 +227,7 @@ ip_dn_io_t *ip_dn_io_ptr = NULL;
#ifdef VIMAGE_GLOBALS
int fw_one_pass;
#endif
+struct flowtable *ip_ft;
static void ip_freef(struct ipqhead *, struct ipq *);
@@ -342,6 +349,8 @@ ip_init(void)
ipintrq.ifq_maxlen = ipqmaxlen;
mtx_init(&ipintrq.ifq_mtx, "ip_inq", NULL, MTX_DEF);
netisr_register(NETISR_IP, ip_input, &ipintrq, 0);
+
+ ip_ft = flowtable_alloc(ip_output_flowtable_size, FL_PCPU);
}
void
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 76d8f2a..20acb921 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <net/netisr.h>
#include <net/pfil.h>
#include <net/route.h>
+#include <net/flowtable.h>
#ifdef RADIX_MPATH
#include <net/radix_mpath.h>
#endif
@@ -135,6 +136,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
int hlen = sizeof (struct ip);
int mtu;
int len, error = 0;
+ int nortfree = 0;
struct sockaddr_in *dst = NULL; /* keep compiler happy */
struct in_ifaddr *ia = NULL;
int isbroadcast, sw_csum;
@@ -158,6 +160,10 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
m->m_flags |= M_FLOWID;
}
}
+ if ((ro == &iproute) && (ro->ro_rt == NULL) && (ro->ro_lle == NULL)) {
+ if (flowtable_lookup(ip_ft, m, ro) == 0)
+ nortfree = 1;
+ }
if (opt) {
len = 0;
@@ -199,7 +205,8 @@ again:
if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
dst->sin_family != AF_INET ||
dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
- RTFREE(ro->ro_rt);
+ if (!nortfree)
+ RTFREE(ro->ro_rt);
ro->ro_rt = (struct rtentry *)NULL;
}
#ifdef IPFIREWALL_FORWARD
@@ -638,7 +645,7 @@ passout:
IPSTAT_INC(ips_fragmented);
done:
- if (ro == &iproute && ro->ro_rt) {
+ if (ro == &iproute && ro->ro_rt && !nortfree) {
RTFREE(ro->ro_rt);
}
return (error);
diff --git a/sys/netinet/vinet.h b/sys/netinet/vinet.h
index b65acc1..20a36c5 100644
--- a/sys/netinet/vinet.h
+++ b/sys/netinet/vinet.h
@@ -72,6 +72,7 @@ struct vnet_inet {
int _ip_sendsourcequench;
int _ip_do_randomid;
int _ip_checkinterface;
+ int _ip_output_flowtable_size;
u_short _ip_id;
uma_zone_t _ipq_zone;
OpenPOWER on IntegriCloud