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(proc_nf_hooks_lwtunnel_enabled);
49 
50 	return ret;
51 }
52 EXPORT_SYMBOL_GPL(nf_hooks_lwtunnel_sysctl_handler);
53 #endif /* CONFIG_SYSCTL */
54