Skip to content

Commit 8bb69f3

Browse files
ummakynesdavem330
authored andcommitted
netfilter: nf_tables: add flowtable offload control plane
This patch adds the NFTA_FLOWTABLE_FLAGS attribute that allows users to specify the NF_FLOWTABLE_HW_OFFLOAD flag. This patch also adds a new setup interface for the flowtable type to perform the flowtable offload block callback configuration. Signed-off-by: Pablo Neira Ayuso <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f1363e0 commit 8bb69f3

File tree

6 files changed

+42
-2
lines changed

6 files changed

+42
-2
lines changed

include/net/netfilter/nf_flow_table.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
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;
@@ -16,17 +17,27 @@ struct nf_flowtable_type {
1617
struct list_head list;
1718
int family;
1819
int (*init)(struct nf_flowtable *ft);
20+
int (*setup)(struct nf_flowtable *ft,
21+
struct net_device *dev,
22+
enum flow_block_command cmd);
1923
void (*free)(struct nf_flowtable *ft);
2024
nf_hookfn *hook;
2125
struct module *owner;
2226
};
2327

28+
enum nf_flowtable_flags {
29+
NF_FLOWTABLE_HW_OFFLOAD = 0x1,
30+
};
31+
2432
struct nf_flowtable {
2533
struct list_head list;
2634
struct rhashtable rhashtable;
2735
int priority;
2836
const struct nf_flowtable_type *type;
2937
struct delayed_work gc_work;
38+
unsigned int flags;
39+
struct flow_block flow_block;
40+
possible_net_t net;
3041
};
3142

3243
enum flow_offload_tuple_dir {
@@ -131,4 +142,11 @@ unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
131142
#define MODULE_ALIAS_NF_FLOWTABLE(family) \
132143
MODULE_ALIAS("nf-flowtable-" __stringify(family))
133144

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+
}
151+
134152
#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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
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,
1213
.free = nf_flow_table_free,
1314
.hook = nf_flow_offload_ip_hook,
1415
.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
@@ -10,6 +10,7 @@
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,
1314
.free = nf_flow_table_free,
1415
.hook = nf_flow_offload_ipv6_hook,
1516
.owner = THIS_MODULE,

net/netfilter/nf_flow_table_inet.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ nf_flow_offload_inet_hook(void *priv, struct sk_buff *skb,
2424
static struct nf_flowtable_type flowtable_inet = {
2525
.family = NFPROTO_INET,
2626
.init = nf_flow_table_init,
27+
.setup = nf_flow_table_offload_setup,
2728
.free = nf_flow_table_free,
2829
.hook = nf_flow_offload_inet_hook,
2930
.owner = THIS_MODULE,

net/netfilter/nf_tables_api.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5835,6 +5835,7 @@ static const struct nla_policy nft_flowtable_policy[NFTA_FLOWTABLE_MAX + 1] = {
58355835
.len = NFT_NAME_MAXLEN - 1 },
58365836
[NFTA_FLOWTABLE_HOOK] = { .type = NLA_NESTED },
58375837
[NFTA_FLOWTABLE_HANDLE] = { .type = NLA_U64 },
5838+
[NFTA_FLOWTABLE_FLAGS] = { .type = NLA_U32 },
58385839
};
58395840

58405841
struct nft_flowtable *nft_flowtable_lookup(const struct nft_table *table,
@@ -5968,8 +5969,11 @@ static void nft_unregister_flowtable_net_hooks(struct net *net,
59685969
{
59695970
struct nft_hook *hook;
59705971

5971-
list_for_each_entry(hook, &flowtable->hook_list, list)
5972+
list_for_each_entry(hook, &flowtable->hook_list, list) {
59725973
nf_unregister_net_hook(net, &hook->ops);
5974+
flowtable->data.type->setup(&flowtable->data, hook->ops.dev,
5975+
FLOW_BLOCK_UNBIND);
5976+
}
59735977
}
59745978

59755979
static int nft_register_flowtable_net_hooks(struct net *net,
@@ -5991,6 +5995,8 @@ static int nft_register_flowtable_net_hooks(struct net *net,
59915995
}
59925996
}
59935997

5998+
flowtable->data.type->setup(&flowtable->data, hook->ops.dev,
5999+
FLOW_BLOCK_BIND);
59946000
err = nf_register_net_hook(net, &hook->ops);
59956001
if (err < 0)
59966002
goto err_unregister_net_hooks;
@@ -6006,6 +6012,8 @@ static int nft_register_flowtable_net_hooks(struct net *net,
60066012
break;
60076013

60086014
nf_unregister_net_hook(net, &hook->ops);
6015+
flowtable->data.type->setup(&flowtable->data, hook->ops.dev,
6016+
FLOW_BLOCK_UNBIND);
60096017
list_del_rcu(&hook->list);
60106018
kfree_rcu(hook, rcu);
60116019
}
@@ -6080,6 +6088,14 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
60806088
goto err2;
60816089
}
60826090

6091+
if (nla[NFTA_FLOWTABLE_FLAGS]) {
6092+
flowtable->data.flags =
6093+
ntohl(nla_get_be32(nla[NFTA_FLOWTABLE_FLAGS]));
6094+
if (flowtable->data.flags & ~NF_FLOWTABLE_HW_OFFLOAD)
6095+
goto err3;
6096+
}
6097+
6098+
write_pnet(&flowtable->data.net, net);
60836099
flowtable->data.type = type;
60846100
err = type->init(&flowtable->data);
60856101
if (err < 0)
@@ -6191,7 +6207,8 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
61916207
nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) ||
61926208
nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) ||
61936209
nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle),
6194-
NFTA_FLOWTABLE_PAD))
6210+
NFTA_FLOWTABLE_PAD) ||
6211+
nla_put_be32(skb, NFTA_FLOWTABLE_FLAGS, htonl(flowtable->data.flags)))
61956212
goto nla_put_failure;
61966213

61976214
nest = nla_nest_start_noflag(skb, NFTA_FLOWTABLE_HOOK);

0 commit comments

Comments
 (0)