1 | // SPDX-License-Identifier: GPL-2.0 |
2 | |
3 | #include <linux/sysctl.h> |
4 | #include <net/lwtunnel.h> |
5 | #include <net/netfilter/nf_hooks_lwtunnel.h> |
6 | |
7 | static inline int nf_hooks_lwtunnel_get(void) |
8 | { |
9 | if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled)) |
10 | return 1; |
11 | else |
12 | return 0; |
13 | } |
14 | |
15 | static inline int nf_hooks_lwtunnel_set(int enable) |
16 | { |
17 | if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled)) { |
18 | if (!enable) |
19 | return -EBUSY; |
20 | } else if (enable) { |
21 | static_branch_enable(&nf_hooks_lwtunnel_enabled); |
22 | } |
23 | |
24 | return 0; |
25 | } |
26 | |
27 | #ifdef CONFIG_SYSCTL |
28 | int nf_hooks_lwtunnel_sysctl_handler(struct ctl_table *table, int write, |
29 | void *buffer, size_t *lenp, loff_t *ppos) |
30 | { |
31 | int proc_nf_hooks_lwtunnel_enabled = 0; |
32 | struct ctl_table tmp = { |
33 | .procname = table->procname, |
34 | .data = &proc_nf_hooks_lwtunnel_enabled, |
35 | .maxlen = sizeof(int), |
36 | .mode = table->mode, |
37 | .extra1 = SYSCTL_ZERO, |
38 | .extra2 = SYSCTL_ONE, |
39 | }; |
40 | int ret; |
41 | |
42 | if (!write) |
43 | proc_nf_hooks_lwtunnel_enabled = nf_hooks_lwtunnel_get(); |
44 | |
45 | ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); |
46 | |
47 | if (write && ret == 0) |
48 | ret = nf_hooks_lwtunnel_set(enable: proc_nf_hooks_lwtunnel_enabled); |
49 | |
50 | return ret; |
51 | } |
52 | EXPORT_SYMBOL_GPL(nf_hooks_lwtunnel_sysctl_handler); |
53 | #endif /* CONFIG_SYSCTL */ |
54 | |