diff options
| -rw-r--r-- | include/net/netns/ipv6.h | 1 | ||||
| -rw-r--r-- | net/ipv6/fib6_rules.c | 82 |
2 files changed, 47 insertions, 36 deletions
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 5279cd6a00ba..66bf9c0f745b 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h | |||
| @@ -41,6 +41,7 @@ struct netns_ipv6 { | |||
| 41 | struct fib6_table *fib6_main_tbl; | 41 | struct fib6_table *fib6_main_tbl; |
| 42 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 42 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
| 43 | struct fib6_table *fib6_local_tbl; | 43 | struct fib6_table *fib6_local_tbl; |
| 44 | struct fib_rules_ops *fib6_rules_ops; | ||
| 44 | #endif | 45 | #endif |
| 45 | struct sock **icmp_sk; | 46 | struct sock **icmp_sk; |
| 46 | }; | 47 | }; |
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 | ||
| 32 | static struct fib_rules_ops *fib6_rules_ops; | ||
| 33 | |||
| 34 | struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, | 32 | struct 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 | ||
| 254 | static int __init fib6_default_rules_init(void) | 253 | static 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 | |||
| 275 | int __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; |
| 286 | out: | 279 | out: |
| 287 | return ret; | 280 | return err; |
| 288 | 281 | ||
| 289 | out_default_rules_init: | 282 | out_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); | 284 | out_fib6_rules_ops: |
| 285 | kfree(net->ipv6.fib6_rules_ops); | ||
| 292 | goto out; | 286 | goto out; |
| 293 | } | 287 | } |
| 294 | 288 | ||
| 289 | static 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 | |||
| 295 | static struct pernet_operations fib6_rules_net_ops = { | ||
| 296 | .init = fib6_rules_net_init, | ||
| 297 | .exit = fib6_rules_net_exit, | ||
| 298 | }; | ||
| 299 | |||
| 300 | int __init fib6_rules_init(void) | ||
| 301 | { | ||
| 302 | return register_pernet_subsys(&fib6_rules_net_ops); | ||
| 303 | } | ||
| 304 | |||
| 305 | |||
| 295 | void fib6_rules_cleanup(void) | 306 | void 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 | } |
