Also a pretty dull wrapper around the hook->ops.dev comparison for now. Will search the embedded nf_hook_ops list in future. The ugly cast to eliminate the const qualifier will vanish then, too. Signed-off-by: Phil Sutter <phil@xxxxxx> --- include/net/netfilter/nf_tables.h | 3 +++ net/netfilter/nf_tables_api.c | 14 +++++++++++++- net/netfilter/nf_tables_offload.c | 2 +- net/netfilter/nft_chain_filter.c | 6 ++++-- net/netfilter/nft_flow_offload.c | 2 +- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 16daffcee0e1..be11518646a3 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -1195,6 +1195,9 @@ struct nft_hook { u8 ifnamelen; }; +struct nf_hook_ops *nft_hook_find_ops(const struct nft_hook *hook, + const struct net_device *dev); + /** * struct nft_base_chain - nf_tables base chain * diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index dedf50ba266c..65db4c54cfae 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -9222,13 +9222,25 @@ static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net, return -EMSGSIZE; } +struct nf_hook_ops *nft_hook_find_ops(const struct nft_hook *hook, + const struct net_device *dev) +{ + if (hook->ops.dev == dev) + return (struct nf_hook_ops *)&hook->ops; + + return NULL; +} +EXPORT_SYMBOL_GPL(nft_hook_find_ops); + static void nft_flowtable_event(unsigned long event, struct net_device *dev, struct nft_flowtable *flowtable) { + struct nf_hook_ops *ops; struct nft_hook *hook; list_for_each_entry(hook, &flowtable->hook_list, list) { - if (hook->ops.dev != dev) + ops = nft_hook_find_ops(hook, dev); + if (!ops) continue; /* flow_offload_netdev_event() cleans up entries for us. */ diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c index 64675f1c7f29..75b756f0b9f0 100644 --- a/net/netfilter/nf_tables_offload.c +++ b/net/netfilter/nf_tables_offload.c @@ -638,7 +638,7 @@ static struct nft_chain *__nft_offload_get_chain(const struct nftables_pernet *n found = NULL; basechain = nft_base_chain(chain); list_for_each_entry(hook, &basechain->hook_list, list) { - if (hook->ops.dev != dev) + if (!nft_hook_find_ops(hook, dev)) continue; found = hook; diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c index 543f258b7c6b..d34c6fe7ba72 100644 --- a/net/netfilter/nft_chain_filter.c +++ b/net/netfilter/nft_chain_filter.c @@ -322,14 +322,16 @@ static void nft_netdev_event(unsigned long event, struct net_device *dev, struct nft_ctx *ctx) { struct nft_base_chain *basechain = nft_base_chain(ctx->chain); + struct nf_hook_ops *ops; struct nft_hook *hook; list_for_each_entry(hook, &basechain->hook_list, list) { - if (hook->ops.dev != dev) + ops = nft_hook_find_ops(hook, dev); + if (!ops) continue; if (!(ctx->chain->table->flags & NFT_TABLE_F_DORMANT)) - nf_unregister_net_hook(ctx->net, &hook->ops); + nf_unregister_net_hook(ctx->net, ops); list_del_rcu(&hook->list); kfree_rcu(hook, rcu); diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c index 9dcd1548df9d..646192321265 100644 --- a/net/netfilter/nft_flow_offload.c +++ b/net/netfilter/nft_flow_offload.c @@ -174,7 +174,7 @@ static bool nft_flowtable_find_dev(const struct net_device *dev, bool found = false; list_for_each_entry_rcu(hook, &ft->hook_list, list) { - if (hook->ops.dev != dev) + if (!nft_hook_find_ops(hook, dev)) continue; found = true; -- 2.43.0