netfilter: move the sysctl nf_hooks_lwtunnel into the netfilter core
Currently, the sysctl net.netfilter.nf_hooks_lwtunnel depends on the
nf_conntrack module, but the nf_conntrack module is not always loaded.
Therefore, accessing net.netfilter.nf_hooks_lwtunnel may have an error.
Move sysctl nf_hooks_lwtunnel into the netfilter core.
Fixes: 7a3f5b0de3
("netfilter: add netfilter hooks to SRv6 data plane")
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Jianguo Wu <wujianguo@chinatelecom.cn>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
9a3bc8d16e
commit
a2225e0250
@ -15,6 +15,9 @@ struct netns_nf {
|
||||
const struct nf_logger __rcu *nf_loggers[NFPROTO_NUMPROTO];
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct ctl_table_header *nf_log_dir_header;
|
||||
#ifdef CONFIG_LWTUNNEL
|
||||
struct ctl_table_header *nf_lwtnl_dir_header;
|
||||
#endif
|
||||
#endif
|
||||
struct nf_hook_entries __rcu *hooks_ipv4[NF_INET_NUMHOOKS];
|
||||
struct nf_hook_entries __rcu *hooks_ipv6[NF_INET_NUMHOOKS];
|
||||
|
@ -815,12 +815,21 @@ int __init netfilter_init(void)
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
#ifdef CONFIG_LWTUNNEL
|
||||
ret = netfilter_lwtunnel_init();
|
||||
if (ret < 0)
|
||||
goto err_lwtunnel_pernet;
|
||||
#endif
|
||||
ret = netfilter_log_init();
|
||||
if (ret < 0)
|
||||
goto err_pernet;
|
||||
goto err_log_pernet;
|
||||
|
||||
return 0;
|
||||
err_pernet:
|
||||
err_log_pernet:
|
||||
#ifdef CONFIG_LWTUNNEL
|
||||
netfilter_lwtunnel_fini();
|
||||
err_lwtunnel_pernet:
|
||||
#endif
|
||||
unregister_pernet_subsys(&netfilter_net_ops);
|
||||
err:
|
||||
return ret;
|
||||
|
@ -22,9 +22,6 @@
|
||||
#include <net/netfilter/nf_conntrack_acct.h>
|
||||
#include <net/netfilter/nf_conntrack_zones.h>
|
||||
#include <net/netfilter/nf_conntrack_timestamp.h>
|
||||
#ifdef CONFIG_LWTUNNEL
|
||||
#include <net/netfilter/nf_hooks_lwtunnel.h>
|
||||
#endif
|
||||
#include <linux/rculist_nulls.h>
|
||||
|
||||
static bool enable_hooks __read_mostly;
|
||||
@ -612,9 +609,6 @@ enum nf_ct_sysctl_index {
|
||||
NF_SYSCTL_CT_PROTO_TIMEOUT_GRE,
|
||||
NF_SYSCTL_CT_PROTO_TIMEOUT_GRE_STREAM,
|
||||
#endif
|
||||
#ifdef CONFIG_LWTUNNEL
|
||||
NF_SYSCTL_CT_LWTUNNEL,
|
||||
#endif
|
||||
|
||||
NF_SYSCTL_CT_LAST_SYSCTL,
|
||||
};
|
||||
@ -946,15 +940,6 @@ static struct ctl_table nf_ct_sysctl_table[] = {
|
||||
.proc_handler = proc_dointvec_jiffies,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_LWTUNNEL
|
||||
[NF_SYSCTL_CT_LWTUNNEL] = {
|
||||
.procname = "nf_hooks_lwtunnel",
|
||||
.data = NULL,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = nf_hooks_lwtunnel_sysctl_handler,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct ctl_table nf_ct_netfilter_table[] = {
|
||||
|
@ -3,6 +3,9 @@
|
||||
#include <linux/sysctl.h>
|
||||
#include <net/lwtunnel.h>
|
||||
#include <net/netfilter/nf_hooks_lwtunnel.h>
|
||||
#include <linux/netfilter.h>
|
||||
|
||||
#include "nf_internals.h"
|
||||
|
||||
static inline int nf_hooks_lwtunnel_get(void)
|
||||
{
|
||||
@ -50,4 +53,68 @@ int nf_hooks_lwtunnel_sysctl_handler(struct ctl_table *table, int write,
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_hooks_lwtunnel_sysctl_handler);
|
||||
|
||||
static struct ctl_table nf_lwtunnel_sysctl_table[] = {
|
||||
{
|
||||
.procname = "nf_hooks_lwtunnel",
|
||||
.data = NULL,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = nf_hooks_lwtunnel_sysctl_handler,
|
||||
},
|
||||
};
|
||||
|
||||
static int __net_init nf_lwtunnel_net_init(struct net *net)
|
||||
{
|
||||
struct ctl_table_header *hdr;
|
||||
struct ctl_table *table;
|
||||
|
||||
table = nf_lwtunnel_sysctl_table;
|
||||
if (!net_eq(net, &init_net)) {
|
||||
table = kmemdup(nf_lwtunnel_sysctl_table,
|
||||
sizeof(nf_lwtunnel_sysctl_table),
|
||||
GFP_KERNEL);
|
||||
if (!table)
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
hdr = register_net_sysctl_sz(net, "net/netfilter", table,
|
||||
ARRAY_SIZE(nf_lwtunnel_sysctl_table));
|
||||
if (!hdr)
|
||||
goto err_reg;
|
||||
|
||||
net->nf.nf_lwtnl_dir_header = hdr;
|
||||
|
||||
return 0;
|
||||
err_reg:
|
||||
if (!net_eq(net, &init_net))
|
||||
kfree(table);
|
||||
err_alloc:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void __net_exit nf_lwtunnel_net_exit(struct net *net)
|
||||
{
|
||||
const struct ctl_table *table;
|
||||
|
||||
table = net->nf.nf_lwtnl_dir_header->ctl_table_arg;
|
||||
unregister_net_sysctl_table(net->nf.nf_lwtnl_dir_header);
|
||||
if (!net_eq(net, &init_net))
|
||||
kfree(table);
|
||||
}
|
||||
|
||||
static struct pernet_operations nf_lwtunnel_net_ops = {
|
||||
.init = nf_lwtunnel_net_init,
|
||||
.exit = nf_lwtunnel_net_exit,
|
||||
};
|
||||
|
||||
int __init netfilter_lwtunnel_init(void)
|
||||
{
|
||||
return register_pernet_subsys(&nf_lwtunnel_net_ops);
|
||||
}
|
||||
|
||||
void netfilter_lwtunnel_fini(void)
|
||||
{
|
||||
unregister_pernet_subsys(&nf_lwtunnel_net_ops);
|
||||
}
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
|
@ -29,6 +29,12 @@ void nf_queue_nf_hook_drop(struct net *net);
|
||||
/* nf_log.c */
|
||||
int __init netfilter_log_init(void);
|
||||
|
||||
#ifdef CONFIG_LWTUNNEL
|
||||
/* nf_hooks_lwtunnel.c */
|
||||
int __init netfilter_lwtunnel_init(void);
|
||||
void netfilter_lwtunnel_fini(void);
|
||||
#endif
|
||||
|
||||
/* core.c */
|
||||
void nf_hook_entries_delete_raw(struct nf_hook_entries __rcu **pp,
|
||||
const struct nf_hook_ops *reg);
|
||||
|
Loading…
Reference in New Issue
Block a user