mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 23:19:34 +02:00
batman-adv: handle errors in batadv_init()
batadv_init() ignores errors from several initialization helpers, so the module can load without those registrations in place. Check the fallible init steps and unwind prior initialization in reverse order of acquisition on failure. Signed-off-by: Minhong He <heminhong@kylinos.cn> Signed-off-by: Sven Eckelmann <sven@narfation.org>
This commit is contained in:
@@ -2802,3 +2802,11 @@ handler_unregister:
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_iv_deinit() - B.A.T.M.A.N. IV deinitialization function
|
||||
*/
|
||||
void batadv_iv_deinit(void)
|
||||
{
|
||||
batadv_recv_handler_unregister(BATADV_IV_OGM);
|
||||
}
|
||||
|
||||
@@ -10,5 +10,6 @@
|
||||
#include "main.h"
|
||||
|
||||
int batadv_iv_init(void);
|
||||
void batadv_iv_deinit(void);
|
||||
|
||||
#endif /* _NET_BATMAN_ADV_BAT_IV_OGM_H_ */
|
||||
|
||||
@@ -947,3 +947,12 @@ elp_unregister:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_v_deinit() - B.A.T.M.A.N. V deinitialization function
|
||||
*/
|
||||
void batadv_v_deinit(void)
|
||||
{
|
||||
batadv_recv_handler_unregister(BATADV_OGM2);
|
||||
batadv_recv_handler_unregister(BATADV_ELP);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#ifdef CONFIG_BATMAN_ADV_BATMAN_V
|
||||
|
||||
int batadv_v_init(void);
|
||||
void batadv_v_deinit(void);
|
||||
void batadv_v_hardif_init(struct batadv_hard_iface *hardif);
|
||||
int batadv_v_mesh_init(struct batadv_priv *bat_priv);
|
||||
void batadv_v_mesh_free(struct batadv_priv *bat_priv);
|
||||
@@ -23,6 +24,10 @@ static inline int batadv_v_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void batadv_v_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void batadv_v_hardif_init(struct batadv_hard_iface *hardif)
|
||||
{
|
||||
}
|
||||
|
||||
+34
-11
@@ -102,35 +102,58 @@ static int __init batadv_init(void)
|
||||
|
||||
batadv_recv_handler_init();
|
||||
|
||||
batadv_v_init();
|
||||
batadv_iv_init();
|
||||
ret = batadv_v_init();
|
||||
if (ret < 0)
|
||||
goto err_tt;
|
||||
|
||||
ret = batadv_iv_init();
|
||||
if (ret < 0)
|
||||
goto err_v;
|
||||
|
||||
batadv_tp_meter_init();
|
||||
|
||||
ret = batadv_wifi_net_devices_init();
|
||||
if (ret < 0)
|
||||
goto err_iv;
|
||||
|
||||
batadv_event_workqueue = create_singlethread_workqueue("bat_events");
|
||||
if (!batadv_event_workqueue) {
|
||||
ret = -ENOMEM;
|
||||
goto err_create_wq;
|
||||
goto err_wifi;
|
||||
}
|
||||
|
||||
ret = batadv_wifi_net_devices_init();
|
||||
ret = register_netdevice_notifier(&batadv_hard_if_notifier);
|
||||
if (ret < 0)
|
||||
goto err_init_wifi;
|
||||
goto err_wq;
|
||||
|
||||
register_netdevice_notifier(&batadv_hard_if_notifier);
|
||||
rtnl_link_register(&batadv_link_ops);
|
||||
batadv_netlink_register();
|
||||
ret = rtnl_link_register(&batadv_link_ops);
|
||||
if (ret < 0)
|
||||
goto err_notifier;
|
||||
|
||||
ret = batadv_netlink_register();
|
||||
if (ret < 0)
|
||||
goto err_rtnl;
|
||||
|
||||
pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n",
|
||||
init_utsname()->release, BATADV_COMPAT_VERSION);
|
||||
|
||||
return 0;
|
||||
|
||||
err_init_wifi:
|
||||
err_rtnl:
|
||||
rtnl_link_unregister(&batadv_link_ops);
|
||||
err_notifier:
|
||||
unregister_netdevice_notifier(&batadv_hard_if_notifier);
|
||||
err_wq:
|
||||
destroy_workqueue(batadv_event_workqueue);
|
||||
batadv_event_workqueue = NULL;
|
||||
rcu_barrier();
|
||||
|
||||
err_create_wq:
|
||||
err_wifi:
|
||||
batadv_wifi_net_devices_deinit();
|
||||
err_iv:
|
||||
batadv_iv_deinit();
|
||||
err_v:
|
||||
batadv_v_deinit();
|
||||
err_tt:
|
||||
batadv_tt_cache_destroy();
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -1556,14 +1556,18 @@ struct genl_family batadv_netlink_family __ro_after_init = {
|
||||
|
||||
/**
|
||||
* batadv_netlink_register() - register batadv genl netlink family
|
||||
*
|
||||
* Return: 0 on success or negative error number in case of failure
|
||||
*/
|
||||
void __init batadv_netlink_register(void)
|
||||
int __init batadv_netlink_register(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = genl_register_family(&batadv_netlink_family);
|
||||
if (ret)
|
||||
pr_warn("unable to register netlink family\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
void batadv_netlink_register(void);
|
||||
int batadv_netlink_register(void);
|
||||
void batadv_netlink_unregister(void);
|
||||
struct net_device *batadv_netlink_get_meshif(struct netlink_callback *cb);
|
||||
struct batadv_hard_iface *
|
||||
|
||||
Reference in New Issue
Block a user