Commit 5b6743fb authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nf_tables: skip flowtable hooknum and priority on device updates

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: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 05abe445
...@@ -6195,7 +6195,7 @@ static const struct nla_policy nft_flowtable_hook_policy[NFTA_FLOWTABLE_HOOK_MAX ...@@ -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, static int nft_flowtable_parse_hook(const struct nft_ctx *ctx,
const struct nlattr *attr, const struct nlattr *attr,
struct nft_flowtable_hook *flowtable_hook, 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 nlattr *tb[NFTA_FLOWTABLE_HOOK_MAX + 1];
struct nft_hook *hook; struct nft_hook *hook;
...@@ -6209,15 +6209,35 @@ static int nft_flowtable_parse_hook(const struct nft_ctx *ctx, ...@@ -6209,15 +6209,35 @@ static int nft_flowtable_parse_hook(const struct nft_ctx *ctx,
if (err < 0) if (err < 0)
return err; return err;
if (add) {
if (!tb[NFTA_FLOWTABLE_HOOK_NUM] || if (!tb[NFTA_FLOWTABLE_HOOK_NUM] ||
!tb[NFTA_FLOWTABLE_HOOK_PRIORITY]) !tb[NFTA_FLOWTABLE_HOOK_PRIORITY])
return -EINVAL; return -EINVAL;
hooknum = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_NUM])); hooknum = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_NUM]));
if (hooknum != NF_NETDEV_INGRESS) if (hooknum != NF_NETDEV_INGRESS)
return -EINVAL; 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])); priority = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_PRIORITY]));
if (priority != flowtable->data.priority)
return -EOPNOTSUPP;
}
flowtable_hook->priority = flowtable->data.priority;
flowtable_hook->num = flowtable->hooknum;
}
if (tb[NFTA_FLOWTABLE_HOOK_DEVS]) { if (tb[NFTA_FLOWTABLE_HOOK_DEVS]) {
err = nf_tables_parse_netdev_hooks(ctx->net, err = nf_tables_parse_netdev_hooks(ctx->net,
...@@ -6227,15 +6247,12 @@ static int nft_flowtable_parse_hook(const struct nft_ctx *ctx, ...@@ -6227,15 +6247,12 @@ static int nft_flowtable_parse_hook(const struct nft_ctx *ctx,
return err; return err;
} }
flowtable_hook->priority = priority;
flowtable_hook->num = hooknum;
list_for_each_entry(hook, &flowtable_hook->list, list) { list_for_each_entry(hook, &flowtable_hook->list, list) {
hook->ops.pf = NFPROTO_NETDEV; hook->ops.pf = NFPROTO_NETDEV;
hook->ops.hooknum = hooknum; hook->ops.hooknum = flowtable_hook->num;
hook->ops.priority = priority; hook->ops.priority = flowtable_hook->priority;
hook->ops.priv = ft; hook->ops.priv = &flowtable->data;
hook->ops.hook = ft->type->hook; hook->ops.hook = flowtable->data.type->hook;
} }
return err; return err;
...@@ -6363,7 +6380,7 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh, ...@@ -6363,7 +6380,7 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh,
int err; int err;
err = nft_flowtable_parse_hook(ctx, nla[NFTA_FLOWTABLE_HOOK], err = nft_flowtable_parse_hook(ctx, nla[NFTA_FLOWTABLE_HOOK],
&flowtable_hook, &flowtable->data); &flowtable_hook, flowtable, false);
if (err < 0) if (err < 0)
return err; return err;
...@@ -6492,7 +6509,7 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, ...@@ -6492,7 +6509,7 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
goto err3; goto err3;
err = nft_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK], err = nft_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK],
&flowtable_hook, &flowtable->data); &flowtable_hook, flowtable, true);
if (err < 0) if (err < 0)
goto err4; goto err4;
...@@ -6543,7 +6560,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx, ...@@ -6543,7 +6560,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
int err; int err;
err = nft_flowtable_parse_hook(ctx, nla[NFTA_FLOWTABLE_HOOK], err = nft_flowtable_parse_hook(ctx, nla[NFTA_FLOWTABLE_HOOK],
&flowtable_hook, &flowtable->data); &flowtable_hook, flowtable, false);
if (err < 0) if (err < 0)
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment