diff options
Diffstat (limited to 'net/ipv4/fib_rules.c')
-rw-r--r-- | net/ipv4/fib_rules.c | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 49819fe7e4c3..72232ab4ecb1 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include <net/ip_fib.h> | 32 | #include <net/ip_fib.h> |
33 | #include <net/fib_rules.h> | 33 | #include <net/fib_rules.h> |
34 | 34 | ||
35 | static struct fib_rules_ops fib4_rules_ops; | ||
36 | |||
37 | struct fib4_rule | 35 | struct fib4_rule |
38 | { | 36 | { |
39 | struct fib_rule common; | 37 | struct fib_rule common; |
@@ -63,7 +61,7 @@ int fib_lookup(struct flowi *flp, struct fib_result *res) | |||
63 | }; | 61 | }; |
64 | int err; | 62 | int err; |
65 | 63 | ||
66 | err = fib_rules_lookup(&fib4_rules_ops, flp, 0, &arg); | 64 | err = fib_rules_lookup(init_net.ipv4.rules_ops, flp, 0, &arg); |
67 | res->r = arg.rule; | 65 | res->r = arg.rule; |
68 | 66 | ||
69 | return err; | 67 | return err; |
@@ -149,6 +147,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
149 | struct nlmsghdr *nlh, struct fib_rule_hdr *frh, | 147 | struct nlmsghdr *nlh, struct fib_rule_hdr *frh, |
150 | struct nlattr **tb) | 148 | struct nlattr **tb) |
151 | { | 149 | { |
150 | struct net *net = skb->sk->sk_net; | ||
152 | int err = -EINVAL; | 151 | int err = -EINVAL; |
153 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; | 152 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; |
154 | 153 | ||
@@ -159,7 +158,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
159 | if (rule->action == FR_ACT_TO_TBL) { | 158 | if (rule->action == FR_ACT_TO_TBL) { |
160 | struct fib_table *table; | 159 | struct fib_table *table; |
161 | 160 | ||
162 | table = fib_empty_table(&init_net); | 161 | table = fib_empty_table(net); |
163 | if (table == NULL) { | 162 | if (table == NULL) { |
164 | err = -ENOBUFS; | 163 | err = -ENOBUFS; |
165 | goto errout; | 164 | goto errout; |
@@ -250,9 +249,9 @@ static u32 fib4_rule_default_pref(struct fib_rules_ops *ops) | |||
250 | struct list_head *pos; | 249 | struct list_head *pos; |
251 | struct fib_rule *rule; | 250 | struct fib_rule *rule; |
252 | 251 | ||
253 | if (!list_empty(&fib4_rules_ops.rules_list)) { | 252 | if (!list_empty(&ops->rules_list)) { |
254 | pos = fib4_rules_ops.rules_list.next; | 253 | pos = ops->rules_list.next; |
255 | if (pos->next != &fib4_rules_ops.rules_list) { | 254 | if (pos->next != &ops->rules_list) { |
256 | rule = list_entry(pos->next, struct fib_rule, list); | 255 | rule = list_entry(pos->next, struct fib_rule, list); |
257 | if (rule->pref) | 256 | if (rule->pref) |
258 | return rule->pref - 1; | 257 | return rule->pref - 1; |
@@ -274,7 +273,7 @@ static void fib4_rule_flush_cache(void) | |||
274 | rt_cache_flush(-1); | 273 | rt_cache_flush(-1); |
275 | } | 274 | } |
276 | 275 | ||
277 | static struct fib_rules_ops fib4_rules_ops = { | 276 | static struct fib_rules_ops fib4_rules_ops_template = { |
278 | .family = AF_INET, | 277 | .family = AF_INET, |
279 | .rule_size = sizeof(struct fib4_rule), | 278 | .rule_size = sizeof(struct fib4_rule), |
280 | .addr_size = sizeof(u32), | 279 | .addr_size = sizeof(u32), |
@@ -288,24 +287,20 @@ static struct fib_rules_ops fib4_rules_ops = { | |||
288 | .flush_cache = fib4_rule_flush_cache, | 287 | .flush_cache = fib4_rule_flush_cache, |
289 | .nlgroup = RTNLGRP_IPV4_RULE, | 288 | .nlgroup = RTNLGRP_IPV4_RULE, |
290 | .policy = fib4_rule_policy, | 289 | .policy = fib4_rule_policy, |
291 | .rules_list = LIST_HEAD_INIT(fib4_rules_ops.rules_list), | ||
292 | .owner = THIS_MODULE, | 290 | .owner = THIS_MODULE, |
293 | }; | 291 | }; |
294 | 292 | ||
295 | static int __init fib_default_rules_init(void) | 293 | static int fib_default_rules_init(struct fib_rules_ops *ops) |
296 | { | 294 | { |
297 | int err; | 295 | int err; |
298 | 296 | ||
299 | err = fib_default_rule_add(&fib4_rules_ops, 0, | 297 | err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, FIB_RULE_PERMANENT); |
300 | RT_TABLE_LOCAL, FIB_RULE_PERMANENT); | ||
301 | if (err < 0) | 298 | if (err < 0) |
302 | return err; | 299 | return err; |
303 | err = fib_default_rule_add(&fib4_rules_ops, 0x7FFE, | 300 | err = fib_default_rule_add(ops, 0x7FFE, RT_TABLE_MAIN, 0); |
304 | RT_TABLE_MAIN, 0); | ||
305 | if (err < 0) | 301 | if (err < 0) |
306 | return err; | 302 | return err; |
307 | err = fib_default_rule_add(&fib4_rules_ops, 0x7FFF, | 303 | err = fib_default_rule_add(ops, 0x7FFF, RT_TABLE_DEFAULT, 0); |
308 | RT_TABLE_DEFAULT, 0); | ||
309 | if (err < 0) | 304 | if (err < 0) |
310 | return err; | 305 | return err; |
311 | return 0; | 306 | return 0; |
@@ -314,20 +309,29 @@ static int __init fib_default_rules_init(void) | |||
314 | int __net_init fib4_rules_init(struct net *net) | 309 | int __net_init fib4_rules_init(struct net *net) |
315 | { | 310 | { |
316 | int err; | 311 | int err; |
312 | struct fib_rules_ops *ops; | ||
313 | |||
314 | ops = kmemdup(&fib4_rules_ops_template, sizeof(*ops), GFP_KERNEL); | ||
315 | if (ops == NULL) | ||
316 | return -ENOMEM; | ||
317 | INIT_LIST_HEAD(&ops->rules_list); | ||
318 | fib_rules_register(net, ops); | ||
317 | 319 | ||
318 | fib_rules_register(net, &fib4_rules_ops); | 320 | err = fib_default_rules_init(ops); |
319 | err = fib_default_rules_init(); | ||
320 | if (err < 0) | 321 | if (err < 0) |
321 | goto fail; | 322 | goto fail; |
323 | net->ipv4.rules_ops = ops; | ||
322 | return 0; | 324 | return 0; |
323 | 325 | ||
324 | fail: | 326 | fail: |
325 | /* also cleans all rules already added */ | 327 | /* also cleans all rules already added */ |
326 | fib_rules_unregister(net, &fib4_rules_ops); | 328 | fib_rules_unregister(net, ops); |
329 | kfree(ops); | ||
327 | return err; | 330 | return err; |
328 | } | 331 | } |
329 | 332 | ||
330 | void __net_exit fib4_rules_exit(struct net *net) | 333 | void __net_exit fib4_rules_exit(struct net *net) |
331 | { | 334 | { |
332 | fib_rules_unregister(net, &fib4_rules_ops); | 335 | fib_rules_unregister(net, net->ipv4.rules_ops); |
336 | kfree(net->ipv4.rules_ops); | ||
333 | } | 337 | } |