extern int fib_rules_register(struct fib_rules_ops *);
extern int fib_rules_unregister(struct fib_rules_ops *);
+extern void fib_rules_cleanup_ops(struct fib_rules_ops *);
extern int fib_rules_lookup(struct fib_rules_ops *,
struct flowi *, int flags,
extern int fib6_init(void);
-extern void fib6_rules_init(void);
+extern int fib6_rules_init(void);
extern void fib6_rules_cleanup(void);
#endif
EXPORT_SYMBOL_GPL(fib_rules_register);
-static void cleanup_ops(struct fib_rules_ops *ops)
+void fib_rules_cleanup_ops(struct fib_rules_ops *ops)
{
struct fib_rule *rule, *tmp;
fib_rule_put(rule);
}
}
+EXPORT_SYMBOL_GPL(fib_rules_cleanup_ops);
int fib_rules_unregister(struct fib_rules_ops *ops)
{
list_for_each_entry(o, &rules_ops, list) {
if (o == ops) {
list_del_rcu(&o->list);
- cleanup_ops(ops);
+ fib_rules_cleanup_ops(ops);
goto out;
}
}
return 0;
}
-void __init fib6_rules_init(void)
+int __init fib6_rules_init(void)
{
- BUG_ON(fib6_default_rules_init());
- fib_rules_register(&fib6_rules_ops);
+ int ret;
+
+ ret = fib6_default_rules_init();
+ if (ret)
+ goto out;
+
+ ret = fib_rules_register(&fib6_rules_ops);
+ if (ret)
+ goto out_default_rules_init;
+out:
+ return ret;
+
+out_default_rules_init:
+ fib_rules_cleanup_ops(&fib6_rules_ops);
+ goto out;
}
void fib6_rules_cleanup(void)