aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@sw.ru>2008-01-31 07:04:13 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-31 22:27:39 -0500
commit8280aa6182f03c4e27dc235ce0440bc94927dc28 (patch)
treeaff3a05fabf07b8bb17d0e0867a48fdcf4921045 /net/ipv6
parent336b517fdc0f92f54a3f77a2d0933f9556aa79ad (diff)
[NETFILTER]: ip6_tables: per-netns IPv6 FILTER, MANGLE, RAW
Now it's possible to list and manipulate per-netns ip6tables rules. Filtering decisions are based on init_net's table so far. P.S.: remove init_net check in inet6_create() to see the effect Signed-off-by: Alexey Dobriyan <adobriyan@sw.ru> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c40
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c40
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c38
3 files changed, 86 insertions, 32 deletions
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index d0bf71d40cc5..2d9cd095a72c 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -26,7 +26,7 @@ static struct
26 struct ip6t_replace repl; 26 struct ip6t_replace repl;
27 struct ip6t_standard entries[3]; 27 struct ip6t_standard entries[3];
28 struct ip6t_error term; 28 struct ip6t_error term;
29} initial_table __initdata = { 29} initial_table __net_initdata = {
30 .repl = { 30 .repl = {
31 .name = "filter", 31 .name = "filter",
32 .valid_hooks = FILTER_VALID_HOOKS, 32 .valid_hooks = FILTER_VALID_HOOKS,
@@ -51,14 +51,13 @@ static struct
51 .term = IP6T_ERROR_INIT, /* ERROR */ 51 .term = IP6T_ERROR_INIT, /* ERROR */
52}; 52};
53 53
54static struct xt_table __packet_filter = { 54static struct xt_table packet_filter = {
55 .name = "filter", 55 .name = "filter",
56 .valid_hooks = FILTER_VALID_HOOKS, 56 .valid_hooks = FILTER_VALID_HOOKS,
57 .lock = RW_LOCK_UNLOCKED, 57 .lock = RW_LOCK_UNLOCKED,
58 .me = THIS_MODULE, 58 .me = THIS_MODULE,
59 .af = AF_INET6, 59 .af = AF_INET6,
60}; 60};
61static struct xt_table *packet_filter;
62 61
63/* The work comes in here from netfilter.c. */ 62/* The work comes in here from netfilter.c. */
64static unsigned int 63static unsigned int
@@ -68,7 +67,7 @@ ip6t_hook(unsigned int hook,
68 const struct net_device *out, 67 const struct net_device *out,
69 int (*okfn)(struct sk_buff *)) 68 int (*okfn)(struct sk_buff *))
70{ 69{
71 return ip6t_do_table(skb, hook, in, out, packet_filter); 70 return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_filter);
72} 71}
73 72
74static unsigned int 73static unsigned int
@@ -88,7 +87,7 @@ ip6t_local_out_hook(unsigned int hook,
88 } 87 }
89#endif 88#endif
90 89
91 return ip6t_do_table(skb, hook, in, out, packet_filter); 90 return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_filter);
92} 91}
93 92
94static struct nf_hook_ops ip6t_ops[] __read_mostly = { 93static struct nf_hook_ops ip6t_ops[] __read_mostly = {
@@ -119,6 +118,26 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
119static int forward = NF_ACCEPT; 118static int forward = NF_ACCEPT;
120module_param(forward, bool, 0000); 119module_param(forward, bool, 0000);
121 120
121static int __net_init ip6table_filter_net_init(struct net *net)
122{
123 /* Register table */
124 net->ipv6.ip6table_filter =
125 ip6t_register_table(net, &packet_filter, &initial_table.repl);
126 if (IS_ERR(net->ipv6.ip6table_filter))
127 return PTR_ERR(net->ipv6.ip6table_filter);
128 return 0;
129}
130
131static void __net_exit ip6table_filter_net_exit(struct net *net)
132{
133 ip6t_unregister_table(net->ipv6.ip6table_filter);
134}
135
136static struct pernet_operations ip6table_filter_net_ops = {
137 .init = ip6table_filter_net_init,
138 .exit = ip6table_filter_net_exit,
139};
140
122static int __init ip6table_filter_init(void) 141static int __init ip6table_filter_init(void)
123{ 142{
124 int ret; 143 int ret;
@@ -131,10 +150,9 @@ static int __init ip6table_filter_init(void)
131 /* Entry 1 is the FORWARD hook */ 150 /* Entry 1 is the FORWARD hook */
132 initial_table.entries[1].target.verdict = -forward - 1; 151 initial_table.entries[1].target.verdict = -forward - 1;
133 152
134 /* Register table */ 153 ret = register_pernet_subsys(&ip6table_filter_net_ops);
135 packet_filter = ip6t_register_table(&init_net, &__packet_filter, &initial_table.repl); 154 if (ret < 0)
136 if (IS_ERR(packet_filter)) 155 return ret;
137 return PTR_ERR(packet_filter);
138 156
139 /* Register hooks */ 157 /* Register hooks */
140 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 158 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
@@ -144,14 +162,14 @@ static int __init ip6table_filter_init(void)
144 return ret; 162 return ret;
145 163
146 cleanup_table: 164 cleanup_table:
147 ip6t_unregister_table(packet_filter); 165 unregister_pernet_subsys(&ip6table_filter_net_ops);
148 return ret; 166 return ret;
149} 167}
150 168
151static void __exit ip6table_filter_fini(void) 169static void __exit ip6table_filter_fini(void)
152{ 170{
153 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 171 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
154 ip6t_unregister_table(packet_filter); 172 unregister_pernet_subsys(&ip6table_filter_net_ops);
155} 173}
156 174
157module_init(ip6table_filter_init); 175module_init(ip6table_filter_init);
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index abdfece4ab82..035343a90ffe 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -26,7 +26,7 @@ static struct
26 struct ip6t_replace repl; 26 struct ip6t_replace repl;
27 struct ip6t_standard entries[5]; 27 struct ip6t_standard entries[5];
28 struct ip6t_error term; 28 struct ip6t_error term;
29} initial_table __initdata = { 29} initial_table __net_initdata = {
30 .repl = { 30 .repl = {
31 .name = "mangle", 31 .name = "mangle",
32 .valid_hooks = MANGLE_VALID_HOOKS, 32 .valid_hooks = MANGLE_VALID_HOOKS,
@@ -57,14 +57,13 @@ static struct
57 .term = IP6T_ERROR_INIT, /* ERROR */ 57 .term = IP6T_ERROR_INIT, /* ERROR */
58}; 58};
59 59
60static struct xt_table __packet_mangler = { 60static struct xt_table packet_mangler = {
61 .name = "mangle", 61 .name = "mangle",
62 .valid_hooks = MANGLE_VALID_HOOKS, 62 .valid_hooks = MANGLE_VALID_HOOKS,
63 .lock = RW_LOCK_UNLOCKED, 63 .lock = RW_LOCK_UNLOCKED,
64 .me = THIS_MODULE, 64 .me = THIS_MODULE,
65 .af = AF_INET6, 65 .af = AF_INET6,
66}; 66};
67static struct xt_table *packet_mangler;
68 67
69/* The work comes in here from netfilter.c. */ 68/* The work comes in here from netfilter.c. */
70static unsigned int 69static unsigned int
@@ -74,7 +73,7 @@ ip6t_route_hook(unsigned int hook,
74 const struct net_device *out, 73 const struct net_device *out,
75 int (*okfn)(struct sk_buff *)) 74 int (*okfn)(struct sk_buff *))
76{ 75{
77 return ip6t_do_table(skb, hook, in, out, packet_mangler); 76 return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle);
78} 77}
79 78
80static unsigned int 79static unsigned int
@@ -109,7 +108,7 @@ ip6t_local_hook(unsigned int hook,
109 /* flowlabel and prio (includes version, which shouldn't change either */ 108 /* flowlabel and prio (includes version, which shouldn't change either */
110 flowlabel = *((u_int32_t *)ipv6_hdr(skb)); 109 flowlabel = *((u_int32_t *)ipv6_hdr(skb));
111 110
112 ret = ip6t_do_table(skb, hook, in, out, packet_mangler); 111 ret = ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle);
113 112
114 if (ret != NF_DROP && ret != NF_STOLEN 113 if (ret != NF_DROP && ret != NF_STOLEN
115 && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) 114 && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr))
@@ -159,14 +158,33 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
159 }, 158 },
160}; 159};
161 160
161static int __net_init ip6table_mangle_net_init(struct net *net)
162{
163 /* Register table */
164 net->ipv6.ip6table_mangle =
165 ip6t_register_table(net, &packet_mangler, &initial_table.repl);
166 if (IS_ERR(net->ipv6.ip6table_mangle))
167 return PTR_ERR(net->ipv6.ip6table_mangle);
168 return 0;
169}
170
171static void __net_exit ip6table_mangle_net_exit(struct net *net)
172{
173 ip6t_unregister_table(net->ipv6.ip6table_mangle);
174}
175
176static struct pernet_operations ip6table_mangle_net_ops = {
177 .init = ip6table_mangle_net_init,
178 .exit = ip6table_mangle_net_exit,
179};
180
162static int __init ip6table_mangle_init(void) 181static int __init ip6table_mangle_init(void)
163{ 182{
164 int ret; 183 int ret;
165 184
166 /* Register table */ 185 ret = register_pernet_subsys(&ip6table_mangle_net_ops);
167 packet_mangler = ip6t_register_table(&init_net, &__packet_mangler, &initial_table.repl); 186 if (ret < 0)
168 if (IS_ERR(packet_mangler)) 187 return ret;
169 return PTR_ERR(packet_mangler);
170 188
171 /* Register hooks */ 189 /* Register hooks */
172 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 190 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
@@ -176,14 +194,14 @@ static int __init ip6table_mangle_init(void)
176 return ret; 194 return ret;
177 195
178 cleanup_table: 196 cleanup_table:
179 ip6t_unregister_table(packet_mangler); 197 unregister_pernet_subsys(&ip6table_mangle_net_ops);
180 return ret; 198 return ret;
181} 199}
182 200
183static void __exit ip6table_mangle_fini(void) 201static void __exit ip6table_mangle_fini(void)
184{ 202{
185 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 203 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
186 ip6t_unregister_table(packet_mangler); 204 unregister_pernet_subsys(&ip6table_mangle_net_ops);
187} 205}
188 206
189module_init(ip6table_mangle_init); 207module_init(ip6table_mangle_init);
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 12acd6300903..5cd84203abfe 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -13,7 +13,7 @@ static struct
13 struct ip6t_replace repl; 13 struct ip6t_replace repl;
14 struct ip6t_standard entries[2]; 14 struct ip6t_standard entries[2];
15 struct ip6t_error term; 15 struct ip6t_error term;
16} initial_table __initdata = { 16} initial_table __net_initdata = {
17 .repl = { 17 .repl = {
18 .name = "raw", 18 .name = "raw",
19 .valid_hooks = RAW_VALID_HOOKS, 19 .valid_hooks = RAW_VALID_HOOKS,
@@ -35,14 +35,13 @@ static struct
35 .term = IP6T_ERROR_INIT, /* ERROR */ 35 .term = IP6T_ERROR_INIT, /* ERROR */
36}; 36};
37 37
38static struct xt_table __packet_raw = { 38static struct xt_table packet_raw = {
39 .name = "raw", 39 .name = "raw",
40 .valid_hooks = RAW_VALID_HOOKS, 40 .valid_hooks = RAW_VALID_HOOKS,
41 .lock = RW_LOCK_UNLOCKED, 41 .lock = RW_LOCK_UNLOCKED,
42 .me = THIS_MODULE, 42 .me = THIS_MODULE,
43 .af = AF_INET6, 43 .af = AF_INET6,
44}; 44};
45static struct xt_table *packet_raw;
46 45
47/* The work comes in here from netfilter.c. */ 46/* The work comes in here from netfilter.c. */
48static unsigned int 47static unsigned int
@@ -52,7 +51,7 @@ ip6t_hook(unsigned int hook,
52 const struct net_device *out, 51 const struct net_device *out,
53 int (*okfn)(struct sk_buff *)) 52 int (*okfn)(struct sk_buff *))
54{ 53{
55 return ip6t_do_table(skb, hook, in, out, packet_raw); 54 return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_raw);
56} 55}
57 56
58static struct nf_hook_ops ip6t_ops[] __read_mostly = { 57static struct nf_hook_ops ip6t_ops[] __read_mostly = {
@@ -72,14 +71,33 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
72 }, 71 },
73}; 72};
74 73
74static int __net_init ip6table_raw_net_init(struct net *net)
75{
76 /* Register table */
77 net->ipv6.ip6table_raw =
78 ip6t_register_table(net, &packet_raw, &initial_table.repl);
79 if (IS_ERR(net->ipv6.ip6table_raw))
80 return PTR_ERR(net->ipv6.ip6table_raw);
81 return 0;
82}
83
84static void __net_exit ip6table_raw_net_exit(struct net *net)
85{
86 ip6t_unregister_table(net->ipv6.ip6table_raw);
87}
88
89static struct pernet_operations ip6table_raw_net_ops = {
90 .init = ip6table_raw_net_init,
91 .exit = ip6table_raw_net_exit,
92};
93
75static int __init ip6table_raw_init(void) 94static int __init ip6table_raw_init(void)
76{ 95{
77 int ret; 96 int ret;
78 97
79 /* Register table */ 98 ret = register_pernet_subsys(&ip6table_raw_net_ops);
80 packet_raw = ip6t_register_table(&init_net, &__packet_raw, &initial_table.repl); 99 if (ret < 0)
81 if (IS_ERR(packet_raw)) 100 return ret;
82 return PTR_ERR(packet_raw);
83 101
84 /* Register hooks */ 102 /* Register hooks */
85 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 103 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
@@ -89,14 +107,14 @@ static int __init ip6table_raw_init(void)
89 return ret; 107 return ret;
90 108
91 cleanup_table: 109 cleanup_table:
92 ip6t_unregister_table(packet_raw); 110 unregister_pernet_subsys(&ip6table_raw_net_ops);
93 return ret; 111 return ret;
94} 112}
95 113
96static void __exit ip6table_raw_fini(void) 114static void __exit ip6table_raw_fini(void)
97{ 115{
98 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 116 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops));
99 ip6t_unregister_table(packet_raw); 117 unregister_pernet_subsys(&ip6table_raw_net_ops);
100} 118}
101 119
102module_init(ip6table_raw_init); 120module_init(ip6table_raw_init);