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: wenxu <wenxu@ucloud.cn> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
e211aab73d
commit
06d392cbe3
@ -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)
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err4;
|
goto err4;
|
||||||
|
|
||||||
/* must be last */
|
err = nft_offload_init();
|
||||||
err = nfnetlink_subsys_register(&nf_tables_subsys);
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err5;
|
goto err5;
|
||||||
|
|
||||||
|
/* must be last */
|
||||||
|
err = nfnetlink_subsys_register(&nf_tables_subsys);
|
||||||
|
if (err < 0)
|
||||||
|
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 @@ err1:
|
|||||||
|
|
||||||
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,
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user