Commit 06d392cb authored by wenxu's avatar wenxu Committed by Pablo Neira Ayuso

netfilter: nf_tables_offload: remove rules when the device unregisters

If the net_device unregisters, clean up the offload rules before the
chain is destroy.
Signed-off-by: default avatarwenxu <wenxu@ucloud.cn>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent e211aab7
...@@ -77,7 +77,7 @@ int nft_flow_rule_offload_commit(struct net *net); ...@@ -77,7 +77,7 @@ int nft_flow_rule_offload_commit(struct net *net);
int nft_chain_offload_priority(struct nft_base_chain *basechain); int nft_chain_offload_priority(struct nft_base_chain *basechain);
void nft_offload_init(void); int nft_offload_init(void);
void nft_offload_exit(void); void nft_offload_exit(void);
#endif #endif
...@@ -7694,15 +7694,20 @@ static int __init nf_tables_module_init(void) ...@@ -7694,15 +7694,20 @@ static int __init nf_tables_module_init(void)
if (err < 0) if (err < 0)
goto err4; goto err4;
err = nft_offload_init();
if (err < 0)
goto err5;
/* must be last */ /* must be last */
err = nfnetlink_subsys_register(&nf_tables_subsys); err = nfnetlink_subsys_register(&nf_tables_subsys);
if (err < 0) if (err < 0)
goto err5; goto err6;
nft_chain_route_init(); nft_chain_route_init();
nft_offload_init();
return err; return err;
err6:
nft_offload_exit();
err5: err5:
rhltable_destroy(&nft_objname_ht); rhltable_destroy(&nft_objname_ht);
err4: err4:
...@@ -7718,8 +7723,8 @@ static int __init nf_tables_module_init(void) ...@@ -7718,8 +7723,8 @@ static int __init nf_tables_module_init(void)
static void __exit nf_tables_module_exit(void) static void __exit nf_tables_module_exit(void)
{ {
nft_offload_exit();
nfnetlink_subsys_unregister(&nf_tables_subsys); nfnetlink_subsys_unregister(&nf_tables_subsys);
nft_offload_exit();
unregister_netdevice_notifier(&nf_tables_flowtable_notifier); unregister_netdevice_notifier(&nf_tables_flowtable_notifier);
nft_chain_filter_fini(); nft_chain_filter_fini();
nft_chain_route_fini(); nft_chain_route_fini();
......
...@@ -426,17 +426,58 @@ static void nft_indr_block_cb(struct net_device *dev, ...@@ -426,17 +426,58 @@ static void nft_indr_block_cb(struct net_device *dev,
mutex_unlock(&net->nft.commit_mutex); 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, NULL, 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 net *net = dev_net(dev);
struct nft_chain *chain;
mutex_lock(&net->nft.commit_mutex);
chain = __nft_offload_get_chain(dev);
if (chain)
nft_offload_chain_clean(chain);
mutex_unlock(&net->nft.commit_mutex);
return NOTIFY_DONE;
}
static struct flow_indr_block_ing_entry block_ing_entry = { static struct flow_indr_block_ing_entry block_ing_entry = {
.cb = nft_indr_block_cb, .cb = nft_indr_block_cb,
.list = LIST_HEAD_INIT(block_ing_entry.list), .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,
};
int nft_offload_init(void)
{ {
int err;
err = register_netdevice_notifier(&nft_offload_netdev_notifier);
if (err < 0)
return err;
flow_indr_add_block_ing_cb(&block_ing_entry); flow_indr_add_block_ing_cb(&block_ing_entry);
return 0;
} }
void nft_offload_exit(void) void nft_offload_exit(void)
{ {
flow_indr_del_block_ing_cb(&block_ing_entry); flow_indr_del_block_ing_cb(&block_ing_entry);
unregister_netdevice_notifier(&nft_offload_netdev_notifier);
} }
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