blob: ee34589e48a4407918b06a3f2452611d38366399 [file] [log] [blame]
Patrick McHardyd62f9ed2006-11-29 02:35:17 +01001/* nf_sysctl.c netfilter sysctl registration/unregistation
2 *
3 * Copyright (c) 2006 Patrick McHardy <kaber@trash.net>
4 */
5#include <linux/module.h>
6#include <linux/sysctl.h>
7#include <linux/string.h>
8#include <linux/slab.h>
9
10static void
11path_free(struct ctl_table *path, struct ctl_table *table)
12{
13 struct ctl_table *t, *next;
14
15 for (t = path; t != NULL && t != table; t = next) {
16 next = t->child;
17 kfree(t);
18 }
19}
20
21static struct ctl_table *
22path_dup(struct ctl_table *path, struct ctl_table *table)
23{
24 struct ctl_table *t, *last = NULL, *tmp;
25
26 for (t = path; t != NULL; t = t->child) {
27 /* twice the size since path elements are terminated by an
28 * empty element */
29 tmp = kmemdup(t, 2 * sizeof(*t), GFP_KERNEL);
30 if (tmp == NULL) {
31 if (last != NULL)
32 path_free(path, table);
33 return NULL;
34 }
35
36 if (last != NULL)
37 last->child = tmp;
38 else
39 path = tmp;
40 last = tmp;
41 }
42
43 if (last != NULL)
44 last->child = table;
45 else
46 path = table;
47
48 return path;
49}
50
51struct ctl_table_header *
52nf_register_sysctl_table(struct ctl_table *path, struct ctl_table *table)
53{
54 struct ctl_table_header *header;
55
56 path = path_dup(path, table);
57 if (path == NULL)
58 return NULL;
Eric W. Biederman0b4d4142007-02-14 00:34:09 -080059 header = register_sysctl_table(path);
Patrick McHardyd62f9ed2006-11-29 02:35:17 +010060 if (header == NULL)
61 path_free(path, table);
62 return header;
63}
64EXPORT_SYMBOL_GPL(nf_register_sysctl_table);
65
66void
67nf_unregister_sysctl_table(struct ctl_table_header *header,
68 struct ctl_table *table)
69{
70 struct ctl_table *path = header->ctl_table;
71
72 unregister_sysctl_table(header);
73 path_free(path, table);
74}
75EXPORT_SYMBOL_GPL(nf_unregister_sysctl_table);
76
77/* net/netfilter */
78static struct ctl_table nf_net_netfilter_table[] = {
79 {
80 .ctl_name = NET_NETFILTER,
81 .procname = "netfilter",
82 .mode = 0555,
83 },
84 {
85 .ctl_name = 0
86 }
87};
88struct ctl_table nf_net_netfilter_sysctl_path[] = {
89 {
90 .ctl_name = CTL_NET,
91 .procname = "net",
92 .mode = 0555,
93 .child = nf_net_netfilter_table,
94 },
95 {
96 .ctl_name = 0
97 }
98};
99EXPORT_SYMBOL_GPL(nf_net_netfilter_sysctl_path);
100
101/* net/ipv4/netfilter */
102static struct ctl_table nf_net_ipv4_netfilter_table[] = {
103 {
104 .ctl_name = NET_IPV4_NETFILTER,
105 .procname = "netfilter",
106 .mode = 0555,
107 },
108 {
109 .ctl_name = 0
110 }
111};
112static struct ctl_table nf_net_ipv4_table[] = {
113 {
114 .ctl_name = NET_IPV4,
115 .procname = "ipv4",
116 .mode = 0555,
117 .child = nf_net_ipv4_netfilter_table,
118 },
119 {
120 .ctl_name = 0
121 }
122};
123struct ctl_table nf_net_ipv4_netfilter_sysctl_path[] = {
124 {
125 .ctl_name = CTL_NET,
126 .procname = "net",
127 .mode = 0555,
128 .child = nf_net_ipv4_table,
129 },
130 {
131 .ctl_name = 0
132 }
133};
134EXPORT_SYMBOL_GPL(nf_net_ipv4_netfilter_sysctl_path);