MFC 205066, 205069, 205093, 205097, 205488:

r205066:

Log:
 - restructure flowtable to support ipv6
 - add a name argument to flowtable_alloc for printing with ddb commands
 - extend ddb commands to print destination address or 4-tuples
 - don't parse ports in ulp header if FL_HASH_ALL is not passed
 - add kern_flowtable_insert to enable more generic use of flowtable
   (e.g. system calls for adding entries)
 - don't hash loopback addresses
 - cleanup whitespace
 - keep statistics per-cpu for per-cpu flowtables to avoid cache line contention
 - add sysctls to accumulate stats and report aggregate

r205069:
Log:
 fix stats reporting sysctl

r205093:
Log:
 re-update copyright to 2010
 pointed out by danfe@

r205097:

Log:
 flowtable_get_hashkey is only used by a DDB function - move under #ifdef DDB

 pointed out by jkim@

r205488:

Log:
 - boot-time size the ipv4 flowtable and the maximum number of flows
 - increase flow cleaning frequency and decrease flow caching time
   when near the flow limit
 - stop allocating new flows when within 3% of maxflows don't start
   allocating again until below 12.5%
This commit is contained in:
kmacy 2010-04-01 00:36:40 +00:00
parent 47181b4061
commit cb43f423ed
6 changed files with 855 additions and 195 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/**************************************************************************
Copyright (c) 2008-2009, BitGravity Inc.
Copyright (c) 2008-2010, BitGravity Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -34,24 +34,49 @@ POSSIBILITY OF SUCH DAMAGE.
#ifdef _KERNEL
#define FL_HASH_PORTS (1<<0) /* hash 4-tuple + protocol */
#define FL_HASH_ALL (1<<0) /* hash 4-tuple + protocol */
#define FL_PCPU (1<<1) /* pcpu cache */
#define FL_NOAUTO (1<<2) /* don't automatically add flentry on miss */
#define FL_TCP (1<<11)
#define FL_SCTP (1<<12)
#define FL_UDP (1<<13)
#define FL_DEBUG (1<<14)
#define FL_DEBUG_ALL (1<<15)
struct flowtable;
struct flentry;
struct route;
struct route_in6;
VNET_DECLARE(struct flowtable *, ip_ft);
#define V_ip_ft VNET(ip_ft)
struct flowtable *flowtable_alloc(int nentry, int flags);
VNET_DECLARE(struct flowtable *, ip6_ft);
#define V_ip6_ft VNET(ip6_ft)
struct flowtable *flowtable_alloc(char *name, int nentry, int flags);
/*
* Given a flow table, look up the L3 and L2 information and
* return it in the route.
*
*/
int flowtable_lookup(struct flowtable *ft, struct mbuf *m,
struct route *ro, uint32_t fibnum);
struct flentry *flowtable_lookup_mbuf(struct flowtable *ft, struct mbuf *m, int af);
struct flentry *flowtable_lookup(struct flowtable *ft, struct sockaddr_storage *ssa,
struct sockaddr_storage *dsa, uint32_t fibnum, int flags);
int kern_flowtable_insert(struct flowtable *ft, struct sockaddr_storage *ssa,
struct sockaddr_storage *dsa, struct route *ro, uint32_t fibnum, int flags);
void flow_invalidate(struct flentry *fl);
void flowtable_route_flush(struct flowtable *ft, struct rtentry *rt);
void flow_to_route(struct flentry *fl, struct route *ro);
void flow_to_route_in6(struct flentry *fl, struct route_in6 *ro);
#endif /* _KERNEL */
#endif

View File

@ -116,13 +116,13 @@ llentry_free(struct llentry *lle)
/*
* Update an llentry for address dst (equivalent to rtalloc for new-arp)
* Caller must pass in a valid struct llentry *
* Caller must pass in a valid struct llentry * (or NULL)
*
* if found the llentry * is returned referenced and unlocked
*/
int
llentry_update(struct llentry **llep, struct lltable *lt,
struct sockaddr *dst, struct ifnet *ifp)
struct sockaddr_storage *dst, struct ifnet *ifp)
{
struct llentry *la;

View File

@ -191,7 +191,7 @@ int lltable_sysctl_dumparp(int, struct sysctl_req *);
void llentry_free(struct llentry *);
int llentry_update(struct llentry **, struct lltable *,
struct sockaddr *, struct ifnet *);
struct sockaddr_storage *, struct ifnet *);
/*
* Generic link layer address lookup function.

View File

@ -327,9 +327,21 @@ ip_init(void)
"error %d\n", __func__, i);
#ifdef FLOWTABLE
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);
if (TUNABLE_INT_FETCH("net.inet.ip.output_flowtable_size",
&V_ip_output_flowtable_size)) {
if (V_ip_output_flowtable_size < 256)
V_ip_output_flowtable_size = 256;
if (!powerof2(V_ip_output_flowtable_size)) {
printf("flowtable must be power of 2 size\n");
V_ip_output_flowtable_size = 2048;
}
} else {
/*
* round up to the next power of 2
*/
V_ip_output_flowtable_size = 1 << fls((1024 + maxusers * 64)-1);
}
V_ip_ft = flowtable_alloc("ipv4", V_ip_output_flowtable_size, FL_PCPU);
#endif
/* Skip initialization of globals for non-default instances. */

View File

@ -151,14 +151,20 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
bzero(ro, sizeof (*ro));
#ifdef FLOWTABLE
/*
* 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 (flowtable_lookup(V_ip_ft, m, ro, M_GETFIB(m)) == 0)
nortfree = 1;
{
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_ip_ft, m, AF_INET)) != NULL) {
flow_to_route(fle, ro);
nortfree = 1;
}
}
#endif
}