Commit 375f2228 authored by Phil Sutter's avatar Phil Sutter Committed by Pablo Neira Ayuso
Browse files

netfilter: nf_tables: Simplify chain netdev notifier



With conditional chain deletion gone, callback code simplifies: Instead
of filling an nft_ctx object, just pass basechain to the per-chain
function. Also plain list_for_each_entry() is safe now.

Signed-off-by: default avatarPhil Sutter <phil@nwl.cc>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent fc013342
Loading
Loading
Loading
Loading
+7 −14
Original line number Diff line number Diff line
@@ -319,17 +319,16 @@ static const struct nft_chain_type nft_chain_filter_netdev = {
};

static void nft_netdev_event(unsigned long event, struct net_device *dev,
			     struct nft_ctx *ctx)
			     struct nft_base_chain *basechain)
{
	struct nft_base_chain *basechain = nft_base_chain(ctx->chain);
	struct nft_hook *hook;

	list_for_each_entry(hook, &basechain->hook_list, list) {
		if (hook->ops.dev != dev)
			continue;

		if (!(ctx->chain->table->flags & NFT_TABLE_F_DORMANT))
			nf_unregister_net_hook(ctx->net, &hook->ops);
		if (!(basechain->chain.table->flags & NFT_TABLE_F_DORMANT))
			nf_unregister_net_hook(dev_net(dev), &hook->ops);

		list_del_rcu(&hook->list);
		kfree_rcu(hook, rcu);
@@ -343,25 +342,20 @@ static int nf_tables_netdev_event(struct notifier_block *this,
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct nft_base_chain *basechain;
	struct nftables_pernet *nft_net;
	struct nft_chain *chain, *nr;
	struct nft_chain *chain;
	struct nft_table *table;
	struct nft_ctx ctx = {
		.net	= dev_net(dev),
	};

	if (event != NETDEV_UNREGISTER)
		return NOTIFY_DONE;

	nft_net = nft_pernet(ctx.net);
	nft_net = nft_pernet(dev_net(dev));
	mutex_lock(&nft_net->commit_mutex);
	list_for_each_entry(table, &nft_net->tables, list) {
		if (table->family != NFPROTO_NETDEV &&
		    table->family != NFPROTO_INET)
			continue;

		ctx.family = table->family;
		ctx.table = table;
		list_for_each_entry_safe(chain, nr, &table->chains, list) {
		list_for_each_entry(chain, &table->chains, list) {
			if (!nft_is_base_chain(chain))
				continue;

@@ -370,8 +364,7 @@ static int nf_tables_netdev_event(struct notifier_block *this,
			    basechain->ops.hooknum != NF_INET_INGRESS)
				continue;

			ctx.chain = chain;
			nft_netdev_event(event, dev, &ctx);
			nft_netdev_event(event, dev, basechain);
		}
	}
	mutex_unlock(&nft_net->commit_mutex);