aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/fib6_rules.c
diff options
context:
space:
mode:
authorDaniel Lezcano <dlezcano@fr.ibm.com>2008-03-04 02:33:08 -0500
committerDavid S. Miller <davem@davemloft.net>2008-03-04 02:33:08 -0500
commitdcabb819a6eced95ef531b001e663d0d592c8d9f (patch)
tree1ecd3db4de537c8aad94a43827723668c7e4368c /net/ipv6/fib6_rules.c
parenteb5564b8532eec6b49379095df2b979aab85661f (diff)
[NETNS][IPV6] fib6_rules - handle several network namespaces
The fib6_rules_ops is moved to the network namespace structure. All references are changed to have it relatively to it. Each time a network namespace is created a new fib6_rules_ops is allocated, initialized and stored into the network namespace structure. The common part of the fib rules is namespace aware, so it is quite easy to retrieve the network namespace from the rules and use it in the different callbacks. Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com> Signed-off-by: Benjamin Thery <benjamin.thery@bull.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/fib6_rules.c')
-rw-r--r--net/ipv6/fib6_rules.c82
1 files changed, 46 insertions, 36 deletions
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 60af08f12547..89cb092c9732 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -29,8 +29,6 @@ struct fib6_rule
29 u8 tclass; 29 u8 tclass;
30}; 30};
31 31
32static struct fib_rules_ops *fib6_rules_ops;
33
34struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, 32struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl,
35 int flags, pol_lookup_t lookup) 33 int flags, pol_lookup_t lookup)
36{ 34{
@@ -38,7 +36,7 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl,
38 .lookup_ptr = lookup, 36 .lookup_ptr = lookup,
39 }; 37 };
40 38
41 fib_rules_lookup(fib6_rules_ops, fl, flags, &arg); 39 fib_rules_lookup(net->ipv6.fib6_rules_ops, fl, flags, &arg);
42 if (arg.rule) 40 if (arg.rule)
43 fib_rule_put(arg.rule); 41 fib_rule_put(arg.rule);
44 42
@@ -71,7 +69,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
71 goto discard_pkt; 69 goto discard_pkt;
72 } 70 }
73 71
74 table = fib6_get_table(&init_net, rule->table); 72 table = fib6_get_table(rule->fr_net, rule->table);
75 if (table) 73 if (table)
76 rt = lookup(table, flp, flags); 74 rt = lookup(table, flp, flags);
77 75
@@ -145,13 +143,14 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
145 struct nlattr **tb) 143 struct nlattr **tb)
146{ 144{
147 int err = -EINVAL; 145 int err = -EINVAL;
146 struct net *net = skb->sk->sk_net;
148 struct fib6_rule *rule6 = (struct fib6_rule *) rule; 147 struct fib6_rule *rule6 = (struct fib6_rule *) rule;
149 148
150 if (rule->action == FR_ACT_TO_TBL) { 149 if (rule->action == FR_ACT_TO_TBL) {
151 if (rule->table == RT6_TABLE_UNSPEC) 150 if (rule->table == RT6_TABLE_UNSPEC)
152 goto errout; 151 goto errout;
153 152
154 if (fib6_new_table(&init_net, rule->table) == NULL) { 153 if (fib6_new_table(net, rule->table) == NULL) {
155 err = -ENOBUFS; 154 err = -ENOBUFS;
156 goto errout; 155 goto errout;
157 } 156 }
@@ -251,49 +250,60 @@ static struct fib_rules_ops fib6_rules_ops_template = {
251 .fro_net = &init_net, 250 .fro_net = &init_net,
252}; 251};
253 252
254static int __init fib6_default_rules_init(void) 253static int fib6_rules_net_init(struct net *net)
255{ 254{
256 int err; 255 int err = -ENOMEM;
257 256
258 fib6_rules_ops = kmemdup(&fib6_rules_ops_template, 257 net->ipv6.fib6_rules_ops = kmemdup(&fib6_rules_ops_template,
259 sizeof(*fib6_rules_ops), GFP_KERNEL); 258 sizeof(*net->ipv6.fib6_rules_ops),
260 if (!fib6_rules_ops) 259 GFP_KERNEL);
261 return -ENOMEM; 260 if (!net->ipv6.fib6_rules_ops)
261 goto out;
262 262
263 INIT_LIST_HEAD(&fib6_rules_ops->rules_list); 263 net->ipv6.fib6_rules_ops->fro_net = net;
264 INIT_LIST_HEAD(&net->ipv6.fib6_rules_ops->rules_list);
264 265
265 err = fib_default_rule_add(fib6_rules_ops, 0, 266 err = fib_default_rule_add(net->ipv6.fib6_rules_ops, 0,
266 RT6_TABLE_LOCAL, FIB_RULE_PERMANENT); 267 RT6_TABLE_LOCAL, FIB_RULE_PERMANENT);
267 if (err < 0) 268 if (err)
268 return err; 269 goto out_fib6_rules_ops;
269 err = fib_default_rule_add(fib6_rules_ops, 0x7FFE, RT6_TABLE_MAIN, 0);
270 if (err < 0)
271 return err;
272 return 0;
273}
274
275int __init fib6_rules_init(void)
276{
277 int ret;
278 270
279 ret = fib6_default_rules_init(); 271 err = fib_default_rule_add(net->ipv6.fib6_rules_ops,
280 if (ret) 272 0x7FFE, RT6_TABLE_MAIN, 0);
281 goto out; 273 if (err)
274 goto out_fib6_default_rule_add;
282 275
283 ret = fib_rules_register(fib6_rules_ops); 276 err = fib_rules_register(net->ipv6.fib6_rules_ops);
284 if (ret) 277 if (err)
285 goto out_default_rules_init; 278 goto out_fib6_default_rule_add;
286out: 279out:
287 return ret; 280 return err;
288 281
289out_default_rules_init: 282out_fib6_default_rule_add:
290 fib_rules_cleanup_ops(fib6_rules_ops); 283 fib_rules_cleanup_ops(net->ipv6.fib6_rules_ops);
291 kfree(fib6_rules_ops); 284out_fib6_rules_ops:
285 kfree(net->ipv6.fib6_rules_ops);
292 goto out; 286 goto out;
293} 287}
294 288
289static void fib6_rules_net_exit(struct net *net)
290{
291 fib_rules_unregister(net->ipv6.fib6_rules_ops);
292 kfree(net->ipv6.fib6_rules_ops);
293}
294
295static struct pernet_operations fib6_rules_net_ops = {
296 .init = fib6_rules_net_init,
297 .exit = fib6_rules_net_exit,
298};
299
300int __init fib6_rules_init(void)
301{
302 return register_pernet_subsys(&fib6_rules_net_ops);
303}
304
305
295void fib6_rules_cleanup(void) 306void fib6_rules_cleanup(void)
296{ 307{
297 fib_rules_unregister(fib6_rules_ops); 308 return unregister_pernet_subsys(&fib6_rules_net_ops);
298 kfree(fib6_rules_ops);
299} 309}