Thanks for working on this. On Wed, Sep 04, 2019 at 03:07:31PM +0800, wenxu@xxxxxxxxx wrote: > diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c > index 9657001..9fa3bdb 100644 > --- a/net/netfilter/nf_tables_offload.c > +++ b/net/netfilter/nf_tables_offload.c > @@ -396,17 +396,78 @@ static void nft_indr_block_cb(struct net_device *dev, > mutex_unlock(&net->nft.commit_mutex); > } > > +static void nft_offload_chain_clean(struct nft_chain *chain) > +{ > + struct nft_rule *rule; > + > + list_for_each_entry(rule, &chain->rules, list) { > + nft_flow_offload_rule(chain, rule, > + NULL, FLOW_CLS_DESTROY); > + } > + > + nft_flow_offload_chain(chain, FLOW_BLOCK_UNBIND); > +} > + > +static int nft_offload_netdev_event(struct notifier_block *this, > + unsigned long event, void *ptr) > +{ > + struct net_device *dev = netdev_notifier_info_to_dev(ptr); > + struct nft_base_chain *basechain; > + struct net *net = dev_net(dev); > + struct nft_table *table; > + struct nft_chain *chain; > + > + if (event != NETDEV_UNREGISTER) > + return NOTIFY_DONE; > + > + mutex_lock(&net->nft.commit_mutex); > + list_for_each_entry(table, &net->nft.tables, list) { > + if (table->family != NFPROTO_NETDEV) > + continue; > + > + list_for_each_entry(chain, &table->chains, list) { > + if (!nft_is_base_chain(chain) || > + !(chain->flags & NFT_CHAIN_HW_OFFLOAD)) > + continue; > + > + basechain = nft_base_chain(chain); > + if (strncmp(basechain->dev_name, dev->name, IFNAMSIZ)) > + continue; > + > + nft_offload_chain_clean(chain); > + mutex_unlock(&net->nft.commit_mutex); > + return NOTIFY_DONE; > + } > + } > + mutex_unlock(&net->nft.commit_mutex); This code around the mutex look very similar to nft_block_indr_cb(), could you consolidate this? Probably something like nft_offload_netdev_iterate() and add a callback. > + return NOTIFY_DONE; > +} > + > static struct flow_indr_block_ing_entry block_ing_entry = { > .cb = nft_indr_block_cb, > .list = LIST_HEAD_INIT(block_ing_entry.list), > }; > > -void nft_offload_init(void) > +static struct notifier_block nft_offload_netdev_notifier = { > + .notifier_call = nft_offload_netdev_event, No need for priority because of registration order, right?