|
|
@@ -156,35 +156,17 @@ static const struct nf_chain_type nft_filter_chain_netdev = {
|
|
|
.hook_mask = (1 << NF_NETDEV_INGRESS),
|
|
|
};
|
|
|
|
|
|
-static void nft_netdev_event(unsigned long event, struct nft_af_info *afi,
|
|
|
- struct net_device *dev, struct nft_table *table,
|
|
|
- struct nft_base_chain *basechain)
|
|
|
+static void nft_netdev_event(unsigned long event, struct net_device *dev,
|
|
|
+ struct nft_ctx *ctx)
|
|
|
{
|
|
|
- switch (event) {
|
|
|
- case NETDEV_REGISTER:
|
|
|
- if (strcmp(basechain->dev_name, dev->name) != 0)
|
|
|
- return;
|
|
|
+ struct nft_base_chain *basechain = nft_base_chain(ctx->chain);
|
|
|
|
|
|
- BUG_ON(!(basechain->flags & NFT_BASECHAIN_DISABLED));
|
|
|
-
|
|
|
- dev_hold(dev);
|
|
|
- basechain->ops[0].dev = dev;
|
|
|
- basechain->flags &= ~NFT_BASECHAIN_DISABLED;
|
|
|
- if (!(table->flags & NFT_TABLE_F_DORMANT))
|
|
|
- nft_register_basechain(basechain, afi->nops);
|
|
|
- break;
|
|
|
+ switch (event) {
|
|
|
case NETDEV_UNREGISTER:
|
|
|
if (strcmp(basechain->dev_name, dev->name) != 0)
|
|
|
return;
|
|
|
|
|
|
- BUG_ON(basechain->flags & NFT_BASECHAIN_DISABLED);
|
|
|
-
|
|
|
- if (!(table->flags & NFT_TABLE_F_DORMANT))
|
|
|
- nft_unregister_basechain(basechain, afi->nops);
|
|
|
-
|
|
|
- dev_put(basechain->ops[0].dev);
|
|
|
- basechain->ops[0].dev = NULL;
|
|
|
- basechain->flags |= NFT_BASECHAIN_DISABLED;
|
|
|
+ __nft_release_basechain(ctx);
|
|
|
break;
|
|
|
case NETDEV_CHANGENAME:
|
|
|
if (dev->ifindex != basechain->ops[0].dev->ifindex)
|
|
|
@@ -201,20 +183,29 @@ static int nf_tables_netdev_event(struct notifier_block *this,
|
|
|
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
|
|
struct nft_af_info *afi;
|
|
|
struct nft_table *table;
|
|
|
- struct nft_chain *chain;
|
|
|
+ struct nft_chain *chain, *nr;
|
|
|
+ struct nft_ctx ctx = {
|
|
|
+ .net = dev_net(dev),
|
|
|
+ };
|
|
|
+
|
|
|
+ if (event != NETDEV_UNREGISTER &&
|
|
|
+ event != NETDEV_CHANGENAME)
|
|
|
+ return NOTIFY_DONE;
|
|
|
|
|
|
nfnl_lock(NFNL_SUBSYS_NFTABLES);
|
|
|
list_for_each_entry(afi, &dev_net(dev)->nft.af_info, list) {
|
|
|
+ ctx.afi = afi;
|
|
|
if (afi->family != NFPROTO_NETDEV)
|
|
|
continue;
|
|
|
|
|
|
list_for_each_entry(table, &afi->tables, list) {
|
|
|
- list_for_each_entry(chain, &table->chains, list) {
|
|
|
+ ctx.table = table;
|
|
|
+ list_for_each_entry_safe(chain, nr, &table->chains, list) {
|
|
|
if (!(chain->flags & NFT_BASE_CHAIN))
|
|
|
continue;
|
|
|
|
|
|
- nft_netdev_event(event, afi, dev, table,
|
|
|
- nft_base_chain(chain));
|
|
|
+ ctx.chain = chain;
|
|
|
+ nft_netdev_event(event, dev, &ctx);
|
|
|
}
|
|
|
}
|
|
|
}
|