aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-02-26 13:16:04 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2018-02-27 08:06:46 +0100
commit32fc71875127498bf99cc648e96400ee0895edf7 (patch)
tree8654a141c6ee33d9df75c069336a6d4fbd31072a /net
parentnetfilter: use skb_to_full_sk in ip6_route_me_harder (diff)
downloadlinux-dev-32fc71875127498bf99cc648e96400ee0895edf7.tar.xz
linux-dev-32fc71875127498bf99cc648e96400ee0895edf7.zip
netfilter: nf_tables: return EBUSY if device already belongs to flowtable
If the netdevice is already part of a flowtable, return EBUSY. I cannot find a valid usecase for having two flowtables bound to the same netdevice. We can still have two flowtable where the device set is disjoint. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nf_tables_api.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 8b9fe30de0cd..43acdeef045d 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5037,9 +5037,9 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
{
const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
const struct nf_flowtable_type *type;
+ struct nft_flowtable *flowtable, *ft;
u8 genmask = nft_genmask_next(net);
int family = nfmsg->nfgen_family;
- struct nft_flowtable *flowtable;
struct nft_table *table;
struct nft_ctx ctx;
int err, i, k;
@@ -5099,6 +5099,22 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
goto err3;
for (i = 0; i < flowtable->ops_len; i++) {
+ if (!flowtable->ops[i].dev)
+ continue;
+
+ list_for_each_entry(ft, &table->flowtables, list) {
+ for (k = 0; k < ft->ops_len; k++) {
+ if (!ft->ops[k].dev)
+ continue;
+
+ if (flowtable->ops[i].dev == ft->ops[k].dev &&
+ flowtable->ops[i].pf == ft->ops[k].pf) {
+ err = -EBUSY;
+ goto err4;
+ }
+ }
+ }
+
err = nf_register_net_hook(net, &flowtable->ops[i]);
if (err < 0)
goto err4;