Skip to content

Commit

Permalink
netfilter: nf_tables: skip flowtable hooknum and priority on device u…
Browse files Browse the repository at this point in the history
…pdates

On device updates, the hooknum and priority attributes are not required.
This patch makes optional these two netlink attributes.

Moreover, bail out with EOPNOTSUPP if userspace tries to update the
hooknum and priority for existing flowtables.

While at this, turn EINVAL into EOPNOTSUPP in case the hooknum is not
ingress. EINVAL is reserved for missing netlink attribute / malformed
netlink messages.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Pablo Neira Ayuso committed May 27, 2020
1 parent 05abe44 commit 5b6743f
Showing 1 changed file with 35 additions and 18 deletions.
53 changes: 35 additions & 18 deletions net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -6195,7 +6195,7 @@ static const struct nla_policy nft_flowtable_hook_policy[NFTA_FLOWTABLE_HOOK_MAX
static int nft_flowtable_parse_hook(const struct nft_ctx *ctx,
const struct nlattr *attr,
struct nft_flowtable_hook *flowtable_hook,
struct nf_flowtable *ft)
struct nft_flowtable *flowtable, bool add)
{
struct nlattr *tb[NFTA_FLOWTABLE_HOOK_MAX + 1];
struct nft_hook *hook;
Expand All @@ -6209,15 +6209,35 @@ static int nft_flowtable_parse_hook(const struct nft_ctx *ctx,
if (err < 0)
return err;

if (!tb[NFTA_FLOWTABLE_HOOK_NUM] ||
!tb[NFTA_FLOWTABLE_HOOK_PRIORITY])
return -EINVAL;
if (add) {
if (!tb[NFTA_FLOWTABLE_HOOK_NUM] ||
!tb[NFTA_FLOWTABLE_HOOK_PRIORITY])
return -EINVAL;

hooknum = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_NUM]));
if (hooknum != NF_NETDEV_INGRESS)
return -EINVAL;
hooknum = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_NUM]));
if (hooknum != NF_NETDEV_INGRESS)
return -EOPNOTSUPP;

priority = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_PRIORITY]));

flowtable_hook->priority = priority;
flowtable_hook->num = hooknum;
} else {
if (tb[NFTA_FLOWTABLE_HOOK_NUM]) {
hooknum = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_NUM]));
if (hooknum != flowtable->hooknum)
return -EOPNOTSUPP;
}

if (tb[NFTA_FLOWTABLE_HOOK_PRIORITY]) {
priority = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_PRIORITY]));
if (priority != flowtable->data.priority)
return -EOPNOTSUPP;
}

priority = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_PRIORITY]));
flowtable_hook->priority = flowtable->data.priority;
flowtable_hook->num = flowtable->hooknum;
}

if (tb[NFTA_FLOWTABLE_HOOK_DEVS]) {
err = nf_tables_parse_netdev_hooks(ctx->net,
Expand All @@ -6227,15 +6247,12 @@ static int nft_flowtable_parse_hook(const struct nft_ctx *ctx,
return err;
}

flowtable_hook->priority = priority;
flowtable_hook->num = hooknum;

list_for_each_entry(hook, &flowtable_hook->list, list) {
hook->ops.pf = NFPROTO_NETDEV;
hook->ops.hooknum = hooknum;
hook->ops.priority = priority;
hook->ops.priv = ft;
hook->ops.hook = ft->type->hook;
hook->ops.hooknum = flowtable_hook->num;
hook->ops.priority = flowtable_hook->priority;
hook->ops.priv = &flowtable->data;
hook->ops.hook = flowtable->data.type->hook;
}

return err;
Expand Down Expand Up @@ -6363,7 +6380,7 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh,
int err;

err = nft_flowtable_parse_hook(ctx, nla[NFTA_FLOWTABLE_HOOK],
&flowtable_hook, &flowtable->data);
&flowtable_hook, flowtable, false);
if (err < 0)
return err;

Expand Down Expand Up @@ -6492,7 +6509,7 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
goto err3;

err = nft_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK],
&flowtable_hook, &flowtable->data);
&flowtable_hook, flowtable, true);
if (err < 0)
goto err4;

Expand Down Expand Up @@ -6543,7 +6560,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
int err;

err = nft_flowtable_parse_hook(ctx, nla[NFTA_FLOWTABLE_HOOK],
&flowtable_hook, &flowtable->data);
&flowtable_hook, flowtable, false);
if (err < 0)
return err;

Expand Down

0 comments on commit 5b6743f

Please sign in to comment.