- 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

MFC after:	7 days
This commit is contained in:
Kip Macy 2010-03-12 05:03:26 +00:00
parent 2200b28e5f
commit d4121a02c0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=205066
6 changed files with 764 additions and 173 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

@ -111,13 +111,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

@ -329,7 +329,7 @@ ip_init(void)
#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);
V_ip_ft = flowtable_alloc("ipv4", V_ip_output_flowtable_size, FL_PCPU);
#endif
/* Skip initialization of globals for non-default instances. */

View File

@ -148,14 +148,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
}