Commit d9246a53 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nf_tables: generalise flowtable hook parsing

Update nft_flowtable_parse_hook() to take the flowtable hook list as
parameter. This allows to reuse this function to update the hooks.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent cb8aa9a3
...@@ -6178,21 +6178,30 @@ nft_flowtable_lookup_byhandle(const struct nft_table *table, ...@@ -6178,21 +6178,30 @@ nft_flowtable_lookup_byhandle(const struct nft_table *table,
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
} }
struct nft_flowtable_hook {
u32 num;
int priority;
struct list_head list;
};
static const struct nla_policy nft_flowtable_hook_policy[NFTA_FLOWTABLE_HOOK_MAX + 1] = { static const struct nla_policy nft_flowtable_hook_policy[NFTA_FLOWTABLE_HOOK_MAX + 1] = {
[NFTA_FLOWTABLE_HOOK_NUM] = { .type = NLA_U32 }, [NFTA_FLOWTABLE_HOOK_NUM] = { .type = NLA_U32 },
[NFTA_FLOWTABLE_HOOK_PRIORITY] = { .type = NLA_U32 }, [NFTA_FLOWTABLE_HOOK_PRIORITY] = { .type = NLA_U32 },
[NFTA_FLOWTABLE_HOOK_DEVS] = { .type = NLA_NESTED }, [NFTA_FLOWTABLE_HOOK_DEVS] = { .type = NLA_NESTED },
}; };
static int nf_tables_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 *flowtable) struct nft_flowtable_hook *flowtable_hook,
struct nf_flowtable *ft)
{ {
struct nlattr *tb[NFTA_FLOWTABLE_HOOK_MAX + 1]; struct nlattr *tb[NFTA_FLOWTABLE_HOOK_MAX + 1];
struct nft_hook *hook; struct nft_hook *hook;
int hooknum, priority; int hooknum, priority;
int err; int err;
INIT_LIST_HEAD(&flowtable_hook->list);
err = nla_parse_nested_deprecated(tb, NFTA_FLOWTABLE_HOOK_MAX, attr, err = nla_parse_nested_deprecated(tb, NFTA_FLOWTABLE_HOOK_MAX, attr,
nft_flowtable_hook_policy, NULL); nft_flowtable_hook_policy, NULL);
if (err < 0) if (err < 0)
...@@ -6211,19 +6220,19 @@ static int nf_tables_flowtable_parse_hook(const struct nft_ctx *ctx, ...@@ -6211,19 +6220,19 @@ static int nf_tables_flowtable_parse_hook(const struct nft_ctx *ctx,
err = nf_tables_parse_netdev_hooks(ctx->net, err = nf_tables_parse_netdev_hooks(ctx->net,
tb[NFTA_FLOWTABLE_HOOK_DEVS], tb[NFTA_FLOWTABLE_HOOK_DEVS],
&flowtable->hook_list); &flowtable_hook->list);
if (err < 0) if (err < 0)
return err; return err;
flowtable->hooknum = hooknum; flowtable_hook->priority = priority;
flowtable->data.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 = hooknum;
hook->ops.priority = priority; hook->ops.priority = priority;
hook->ops.priv = &flowtable->data; hook->ops.priv = ft;
hook->ops.hook = flowtable->data.type->hook; hook->ops.hook = ft->type->hook;
} }
return err; return err;
...@@ -6336,6 +6345,7 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, ...@@ -6336,6 +6345,7 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
const struct nfgenmsg *nfmsg = nlmsg_data(nlh); const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
struct nft_flowtable_hook flowtable_hook;
const struct nf_flowtable_type *type; const struct nf_flowtable_type *type;
u8 genmask = nft_genmask_next(net); u8 genmask = nft_genmask_next(net);
int family = nfmsg->nfgen_family; int family = nfmsg->nfgen_family;
...@@ -6409,11 +6419,15 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, ...@@ -6409,11 +6419,15 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
if (err < 0) if (err < 0)
goto err3; goto err3;
err = nf_tables_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK], err = nft_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK],
flowtable); &flowtable_hook, &flowtable->data);
if (err < 0) if (err < 0)
goto err4; goto err4;
list_splice(&flowtable_hook.list, &flowtable->hook_list);
flowtable->data.priority = flowtable_hook.priority;
flowtable->hooknum = flowtable_hook.num;
err = nft_register_flowtable_net_hooks(ctx.net, table, flowtable); err = nft_register_flowtable_net_hooks(ctx.net, table, flowtable);
if (err < 0) { if (err < 0) {
list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) { list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) {
......
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