aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/fib6_rules.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 03ad23a5fd3c..60af08f12547 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -29,7 +29,7 @@ struct fib6_rule
29 u8 tclass; 29 u8 tclass;
30}; 30};
31 31
32static struct fib_rules_ops fib6_rules_ops; 32static struct fib_rules_ops *fib6_rules_ops;
33 33
34struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, 34struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl,
35 int flags, pol_lookup_t lookup) 35 int flags, pol_lookup_t lookup)
@@ -38,7 +38,7 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl,
38 .lookup_ptr = lookup, 38 .lookup_ptr = lookup,
39 }; 39 };
40 40
41 fib_rules_lookup(&fib6_rules_ops, fl, flags, &arg); 41 fib_rules_lookup(fib6_rules_ops, fl, flags, &arg);
42 if (arg.rule) 42 if (arg.rule)
43 fib_rule_put(arg.rule); 43 fib_rule_put(arg.rule);
44 44
@@ -234,7 +234,7 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule)
234 + nla_total_size(16); /* src */ 234 + nla_total_size(16); /* src */
235} 235}
236 236
237static struct fib_rules_ops fib6_rules_ops = { 237static struct fib_rules_ops fib6_rules_ops_template = {
238 .family = AF_INET6, 238 .family = AF_INET6,
239 .rule_size = sizeof(struct fib6_rule), 239 .rule_size = sizeof(struct fib6_rule),
240 .addr_size = sizeof(struct in6_addr), 240 .addr_size = sizeof(struct in6_addr),
@@ -247,7 +247,6 @@ static struct fib_rules_ops fib6_rules_ops = {
247 .nlmsg_payload = fib6_rule_nlmsg_payload, 247 .nlmsg_payload = fib6_rule_nlmsg_payload,
248 .nlgroup = RTNLGRP_IPV6_RULE, 248 .nlgroup = RTNLGRP_IPV6_RULE,
249 .policy = fib6_rule_policy, 249 .policy = fib6_rule_policy,
250 .rules_list = LIST_HEAD_INIT(fib6_rules_ops.rules_list),
251 .owner = THIS_MODULE, 250 .owner = THIS_MODULE,
252 .fro_net = &init_net, 251 .fro_net = &init_net,
253}; 252};
@@ -256,11 +255,18 @@ static int __init fib6_default_rules_init(void)
256{ 255{
257 int err; 256 int err;
258 257
259 err = fib_default_rule_add(&fib6_rules_ops, 0, 258 fib6_rules_ops = kmemdup(&fib6_rules_ops_template,
259 sizeof(*fib6_rules_ops), GFP_KERNEL);
260 if (!fib6_rules_ops)
261 return -ENOMEM;
262
263 INIT_LIST_HEAD(&fib6_rules_ops->rules_list);
264
265 err = fib_default_rule_add(fib6_rules_ops, 0,
260 RT6_TABLE_LOCAL, FIB_RULE_PERMANENT); 266 RT6_TABLE_LOCAL, FIB_RULE_PERMANENT);
261 if (err < 0) 267 if (err < 0)
262 return err; 268 return err;
263 err = fib_default_rule_add(&fib6_rules_ops, 0x7FFE, RT6_TABLE_MAIN, 0); 269 err = fib_default_rule_add(fib6_rules_ops, 0x7FFE, RT6_TABLE_MAIN, 0);
264 if (err < 0) 270 if (err < 0)
265 return err; 271 return err;
266 return 0; 272 return 0;
@@ -274,18 +280,20 @@ int __init fib6_rules_init(void)
274 if (ret) 280 if (ret)
275 goto out; 281 goto out;
276 282
277 ret = fib_rules_register(&fib6_rules_ops); 283 ret = fib_rules_register(fib6_rules_ops);
278 if (ret) 284 if (ret)
279 goto out_default_rules_init; 285 goto out_default_rules_init;
280out: 286out:
281 return ret; 287 return ret;
282 288
283out_default_rules_init: 289out_default_rules_init:
284 fib_rules_cleanup_ops(&fib6_rules_ops); 290 fib_rules_cleanup_ops(fib6_rules_ops);
291 kfree(fib6_rules_ops);
285 goto out; 292 goto out;
286} 293}
287 294
288void fib6_rules_cleanup(void) 295void fib6_rules_cleanup(void)
289{ 296{
290 fib_rules_unregister(&fib6_rules_ops); 297 fib_rules_unregister(fib6_rules_ops);
298 kfree(fib6_rules_ops);
291} 299}