path: root/net/ipv4/fib_rules.c
diff options
authorEric W. Biederman <ebiederm@xmission.com>2009-12-03 12:22:55 -0800
committerDavid S. Miller <davem@davemloft.net>2009-12-03 12:22:55 -0800
commite9c5158ac26affd5d8ce006521bdfb7148090e18 (patch)
treea8d43fb446a1908175923f4109c977dcb84e4f91 /net/ipv4/fib_rules.c
parentnetns: Add an explicit rcu_barrier to unregister_pernet_{device|subsys} (diff)
net: Allow fib_rule_unregister to batch
Refactor the code so fib_rules_register always takes a template instead of the actual fib_rules_ops structure that will be used. This is required for network namespace support so 2 out of the 3 callers already do this, it allows the error handling to be made common, and it allows fib_rules_unregister to free the template for hte caller. Modify fib_rules_unregister to use call_rcu instead of syncrhonize_rcu to allw multiple namespaces to be cleaned up in the same rcu grace period. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/fib_rules.c')
1 files changed, 3 insertions, 9 deletions
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 1239ed23cab6..ca2d07b1c706 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -301,13 +301,9 @@ int __net_init fib4_rules_init(struct net *net)
int err;
struct fib_rules_ops *ops;
- ops = kmemdup(&fib4_rules_ops_template, sizeof(*ops), GFP_KERNEL);
- if (ops == NULL)
- return -ENOMEM;
- INIT_LIST_HEAD(&ops->rules_list);
- ops->fro_net = net;
- fib_rules_register(ops);
+ ops = fib_rules_register(&fib4_rules_ops_template, net);
+ if (IS_ERR(ops))
+ return PTR_ERR(ops);
err = fib_default_rules_init(ops);
if (err < 0)
@@ -318,12 +314,10 @@ int __net_init fib4_rules_init(struct net *net)
/* also cleans all rules already added */
- kfree(ops);
return err;
void __net_exit fib4_rules_exit(struct net *net)
- kfree(net->ipv4.rules_ops);