Skip to content

Commit c29f74e

Browse files
ummakynesdavem330
authored andcommitted
netfilter: nf_flow_table: hardware offload support
This patch adds the dataplane hardware offload to the flowtable infrastructure. Three new flags represent the hardware state of this flow: * FLOW_OFFLOAD_HW: This flow entry resides in the hardware. * FLOW_OFFLOAD_HW_DYING: This flow entry has been scheduled to be remove from hardware. This might be triggered by either packet path (via TCP RST/FIN packet) or via aging. * FLOW_OFFLOAD_HW_DEAD: This flow entry has been already removed from the hardware, the software garbage collector can remove it from the software flowtable. This patch supports for: * IPv4 only. * Aging via FLOW_CLS_STATS, no packet and byte counter synchronization at this stage. This patch also adds the action callback that specifies how to convert the flow entry into the flow_rule object that is passed to the driver. Signed-off-by: Pablo Neira Ayuso <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8bb69f3 commit c29f74e

File tree

8 files changed

+822
-9
lines changed

8 files changed

+822
-9
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: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include <net/dst.h>
1313

1414
struct nf_flowtable;
15+
struct nf_flow_rule;
16+
struct flow_offload;
17+
enum flow_offload_tuple_dir;
1518

1619
struct nf_flowtable_type {
1720
struct list_head list;
@@ -20,6 +23,10 @@ struct nf_flowtable_type {
2023
int (*setup)(struct nf_flowtable *ft,
2124
struct net_device *dev,
2225
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);
2330
void (*free)(struct nf_flowtable *ft);
2431
nf_hookfn *hook;
2532
struct module *owner;
@@ -80,6 +87,9 @@ struct flow_offload_tuple_rhash {
8087
#define FLOW_OFFLOAD_DNAT 0x2
8188
#define FLOW_OFFLOAD_DYING 0x4
8289
#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
8393

8494
enum flow_offload_type {
8595
NF_FLOW_OFFLOAD_UNSPEC = 0,
@@ -142,11 +152,22 @@ unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
142152
#define MODULE_ALIAS_NF_FLOWTABLE(family) \
143153
MODULE_ALIAS("nf-flowtable-" __stringify(family))
144154

145-
static inline int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
146-
struct net_device *dev,
147-
enum flow_block_command cmd)
148-
{
149-
return 0;
150-
}
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);
151172

152173
#endif /* _NF_FLOW_TABLE_H */

net/ipv4/netfilter/nf_flow_table_ipv4.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ static struct nf_flowtable_type flowtable_ipv4 = {
1010
.family = NFPROTO_IPV4,
1111
.init = nf_flow_table_init,
1212
.setup = nf_flow_table_offload_setup,
13+
.action = nf_flow_rule_route,
1314
.free = nf_flow_table_free,
1415
.hook = nf_flow_offload_ip_hook,
1516
.owner = THIS_MODULE,

net/ipv6/netfilter/nf_flow_table_ipv6.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ static struct nf_flowtable_type flowtable_ipv6 = {
1111
.family = NFPROTO_IPV6,
1212
.init = nf_flow_table_init,
1313
.setup = nf_flow_table_offload_setup,
14+
.action = nf_flow_rule_route,
1415
.free = nf_flow_table_free,
1516
.hook = nf_flow_offload_ipv6_hook,
1617
.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

net/netfilter/nf_flow_table_core.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow)
250250
return err;
251251
}
252252

253+
if (flow_table->flags & NF_FLOWTABLE_HW_OFFLOAD)
254+
nf_flow_offload_add(flow_table, flow);
255+
253256
return 0;
254257
}
255258
EXPORT_SYMBOL_GPL(flow_offload_add);
@@ -350,9 +353,20 @@ static void nf_flow_offload_gc_step(struct flow_offload *flow, void *data)
350353
{
351354
struct nf_flowtable *flow_table = data;
352355

356+
if (flow->flags & FLOW_OFFLOAD_HW)
357+
nf_flow_offload_stats(flow_table, flow);
358+
353359
if (nf_flow_has_expired(flow) || nf_ct_is_dying(flow->ct) ||
354-
(flow->flags & (FLOW_OFFLOAD_DYING | FLOW_OFFLOAD_TEARDOWN)))
355-
flow_offload_del(flow_table, flow);
360+
(flow->flags & (FLOW_OFFLOAD_DYING | FLOW_OFFLOAD_TEARDOWN))) {
361+
if (flow->flags & FLOW_OFFLOAD_HW) {
362+
if (!(flow->flags & FLOW_OFFLOAD_HW_DYING))
363+
nf_flow_offload_del(flow_table, flow);
364+
else if (flow->flags & FLOW_OFFLOAD_HW_DEAD)
365+
flow_offload_del(flow_table, flow);
366+
} else {
367+
flow_offload_del(flow_table, flow);
368+
}
369+
}
356370
}
357371

358372
static void nf_flow_offload_work_gc(struct work_struct *work)
@@ -485,6 +499,7 @@ int nf_flow_table_init(struct nf_flowtable *flowtable)
485499
int err;
486500

487501
INIT_DEFERRABLE_WORK(&flowtable->gc_work, nf_flow_offload_work_gc);
502+
flow_block_init(&flowtable->flow_block);
488503

489504
err = rhashtable_init(&flowtable->rhashtable,
490505
&nf_flow_offload_rhash_params);
@@ -520,6 +535,7 @@ static void nf_flow_table_do_cleanup(struct flow_offload *flow, void *data)
520535
static void nf_flow_table_iterate_cleanup(struct nf_flowtable *flowtable,
521536
struct net_device *dev)
522537
{
538+
nf_flow_table_offload_flush(flowtable);
523539
nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev);
524540
flush_delayed_work(&flowtable->gc_work);
525541
}
@@ -547,5 +563,18 @@ void nf_flow_table_free(struct nf_flowtable *flow_table)
547563
}
548564
EXPORT_SYMBOL_GPL(nf_flow_table_free);
549565

566+
static int __init nf_flow_table_module_init(void)
567+
{
568+
return nf_flow_table_offload_init();
569+
}
570+
571+
static void __exit nf_flow_table_module_exit(void)
572+
{
573+
nf_flow_table_offload_exit();
574+
}
575+
576+
module_init(nf_flow_table_module_init);
577+
module_exit(nf_flow_table_module_exit);
578+
550579
MODULE_LICENSE("GPL");
551580
MODULE_AUTHOR("Pablo Neira Ayuso <[email protected]>");

net/netfilter/nf_flow_table_inet.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ static struct nf_flowtable_type flowtable_inet = {
2525
.family = NFPROTO_INET,
2626
.init = nf_flow_table_init,
2727
.setup = nf_flow_table_offload_setup,
28+
.action = nf_flow_rule_route,
2829
.free = nf_flow_table_free,
2930
.hook = nf_flow_offload_inet_hook,
3031
.owner = THIS_MODULE,

0 commit comments

Comments
 (0)