Skip to content

Commit 0320d1e

Browse files
committed
Merge branch 'netfilter-flowtable-hardware-offload'
Pablo Neira Ayuso says: ==================== netfilter flowtable hardware offload The following patchset adds hardware offload support for the flowtable infrastructure [1]. This infrastructure provides a fast datapath for the classic Linux forwarding path that users can enable through policy, eg. table inet x { flowtable f { hook ingress priority 10 devices = { eth0, eth1 } flags offload } chain y { type filter hook forward priority 0; policy accept; ip protocol tcp flow offload @f } } This example above enables the fastpath for TCP traffic between devices eth0 and eth1. Users can turn on the hardware offload through the 'offload' flag from the flowtable definition. If this new flag is not specified, the software flowtable datapath is used. This patchset is composed of 4 preparation patches: room to extend this infrastructure, eg. accelerate bridge forwarding. And 2 patches to add the hardware offload control and data planes: hardware offload. This includes a new NFTA_FLOWTABLE_FLAGS netlink attribute to convey the optional NF_FLOWTABLE_HW_OFFLOAD flag. API available at net/core/flow_offload.h to represent the flow through two flow_rule objects to configure an exact 5-tuple matching on each direction plus the corresponding forwarding actions, that is, the MAC address, NAT and checksum updates; and port redirection in order to configure the hardware datapath. This patch only supports for IPv4 support and statistics collection for flow aging as an initial step. This patchset introduces a new flow_block callback type that needs to be set up to configure the flowtable hardware offload. The first client of this infrastructure follows up after this batch. I would like to thank Mellanox for developing the first upstream driver to use this infrastructure. [1] Documentation/networking/nf_flowtable.txt ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 4717b05 + c29f74e commit 0320d1e

File tree

11 files changed

+955
-74
lines changed

11 files changed

+955
-74
lines changed

include/linux/netdevice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,7 @@ enum tc_setup_type {
848848
TC_SETUP_ROOT_QDISC,
849849
TC_SETUP_QDISC_GRED,
850850
TC_SETUP_QDISC_TAPRIO,
851+
TC_SETUP_FT,
851852
};
852853

853854
/* These structures hold the attributes of bpf state that are being passed

include/net/netfilter/nf_flow_table.h

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,43 @@
88
#include <linux/rcupdate.h>
99
#include <linux/netfilter.h>
1010
#include <linux/netfilter/nf_conntrack_tuple_common.h>
11+
#include <net/flow_offload.h>
1112
#include <net/dst.h>
1213

1314
struct nf_flowtable;
15+
struct nf_flow_rule;
16+
struct flow_offload;
17+
enum flow_offload_tuple_dir;
1418

1519
struct nf_flowtable_type {
1620
struct list_head list;
1721
int family;
1822
int (*init)(struct nf_flowtable *ft);
23+
int (*setup)(struct nf_flowtable *ft,
24+
struct net_device *dev,
25+
enum flow_block_command cmd);
26+
int (*action)(struct net *net,
27+
const struct flow_offload *flow,
28+
enum flow_offload_tuple_dir dir,
29+
struct nf_flow_rule *flow_rule);
1930
void (*free)(struct nf_flowtable *ft);
2031
nf_hookfn *hook;
2132
struct module *owner;
2233
};
2334

35+
enum nf_flowtable_flags {
36+
NF_FLOWTABLE_HW_OFFLOAD = 0x1,
37+
};
38+
2439
struct nf_flowtable {
2540
struct list_head list;
2641
struct rhashtable rhashtable;
2742
int priority;
2843
const struct nf_flowtable_type *type;
2944
struct delayed_work gc_work;
45+
unsigned int flags;
46+
struct flow_block flow_block;
47+
possible_net_t net;
3048
};
3149

3250
enum flow_offload_tuple_dir {
@@ -69,14 +87,22 @@ struct flow_offload_tuple_rhash {
6987
#define FLOW_OFFLOAD_DNAT 0x2
7088
#define FLOW_OFFLOAD_DYING 0x4
7189
#define FLOW_OFFLOAD_TEARDOWN 0x8
90+
#define FLOW_OFFLOAD_HW 0x10
91+
#define FLOW_OFFLOAD_HW_DYING 0x20
92+
#define FLOW_OFFLOAD_HW_DEAD 0x40
93+
94+
enum flow_offload_type {
95+
NF_FLOW_OFFLOAD_UNSPEC = 0,
96+
NF_FLOW_OFFLOAD_ROUTE,
97+
};
7298

7399
struct flow_offload {
74100
struct flow_offload_tuple_rhash tuplehash[FLOW_OFFLOAD_DIR_MAX];
75-
u32 flags;
76-
union {
77-
/* Your private driver data here. */
78-
u32 timeout;
79-
};
101+
struct nf_conn *ct;
102+
u16 flags;
103+
u16 type;
104+
u32 timeout;
105+
struct rcu_head rcu_head;
80106
};
81107

82108
#define NF_FLOW_TIMEOUT (30 * HZ)
@@ -87,10 +113,12 @@ struct nf_flow_route {
87113
} tuple[FLOW_OFFLOAD_DIR_MAX];
88114
};
89115

90-
struct flow_offload *flow_offload_alloc(struct nf_conn *ct,
91-
struct nf_flow_route *route);
116+
struct flow_offload *flow_offload_alloc(struct nf_conn *ct);
92117
void flow_offload_free(struct flow_offload *flow);
93118

119+
int flow_offload_route_init(struct flow_offload *flow,
120+
const struct nf_flow_route *route);
121+
94122
int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow);
95123
struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table,
96124
struct flow_offload_tuple *tuple);
@@ -124,4 +152,22 @@ unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
124152
#define MODULE_ALIAS_NF_FLOWTABLE(family) \
125153
MODULE_ALIAS("nf-flowtable-" __stringify(family))
126154

155+
void nf_flow_offload_add(struct nf_flowtable *flowtable,
156+
struct flow_offload *flow);
157+
void nf_flow_offload_del(struct nf_flowtable *flowtable,
158+
struct flow_offload *flow);
159+
void nf_flow_offload_stats(struct nf_flowtable *flowtable,
160+
struct flow_offload *flow);
161+
162+
void nf_flow_table_offload_flush(struct nf_flowtable *flowtable);
163+
int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
164+
struct net_device *dev,
165+
enum flow_block_command cmd);
166+
int nf_flow_rule_route(struct net *net, const struct flow_offload *flow,
167+
enum flow_offload_tuple_dir dir,
168+
struct nf_flow_rule *flow_rule);
169+
170+
int nf_flow_table_offload_init(void);
171+
void nf_flow_table_offload_exit(void);
172+
127173
#endif /* _NF_FLOW_TABLE_H */

include/uapi/linux/netfilter/nf_tables.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,6 +1518,7 @@ enum nft_object_attributes {
15181518
* @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32)
15191519
* @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32)
15201520
* @NFTA_FLOWTABLE_HANDLE: object handle (NLA_U64)
1521+
* @NFTA_FLOWTABLE_FLAGS: flags (NLA_U32)
15211522
*/
15221523
enum nft_flowtable_attributes {
15231524
NFTA_FLOWTABLE_UNSPEC,
@@ -1527,6 +1528,7 @@ enum nft_flowtable_attributes {
15271528
NFTA_FLOWTABLE_USE,
15281529
NFTA_FLOWTABLE_HANDLE,
15291530
NFTA_FLOWTABLE_PAD,
1531+
NFTA_FLOWTABLE_FLAGS,
15301532
__NFTA_FLOWTABLE_MAX
15311533
};
15321534
#define NFTA_FLOWTABLE_MAX (__NFTA_FLOWTABLE_MAX - 1)

net/ipv4/netfilter/nf_flow_table_ipv4.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
static struct nf_flowtable_type flowtable_ipv4 = {
1010
.family = NFPROTO_IPV4,
1111
.init = nf_flow_table_init,
12+
.setup = nf_flow_table_offload_setup,
13+
.action = nf_flow_rule_route,
1214
.free = nf_flow_table_free,
1315
.hook = nf_flow_offload_ip_hook,
1416
.owner = THIS_MODULE,

net/ipv6/netfilter/nf_flow_table_ipv6.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
static struct nf_flowtable_type flowtable_ipv6 = {
1111
.family = NFPROTO_IPV6,
1212
.init = nf_flow_table_init,
13+
.setup = nf_flow_table_offload_setup,
14+
.action = nf_flow_rule_route,
1315
.free = nf_flow_table_free,
1416
.hook = nf_flow_offload_ipv6_hook,
1517
.owner = THIS_MODULE,

net/netfilter/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ obj-$(CONFIG_NFT_FWD_NETDEV) += nft_fwd_netdev.o
120120

121121
# flow table infrastructure
122122
obj-$(CONFIG_NF_FLOW_TABLE) += nf_flow_table.o
123-
nf_flow_table-objs := nf_flow_table_core.o nf_flow_table_ip.o
123+
nf_flow_table-objs := nf_flow_table_core.o nf_flow_table_ip.o \
124+
nf_flow_table_offload.o
124125

125126
obj-$(CONFIG_NF_FLOW_TABLE_INET) += nf_flow_table_inet.o
126127

0 commit comments

Comments
 (0)