Commit 29f163de authored by Hans Schillstrom's avatar Hans Schillstrom Committed by Ben Hutchings

ipvs: kernel oops - do_ip_vs_get_ctl

commit 8537de8a upstream.

Change order of init so netns init is ready
when register ioctl and netlink.

Ver2
	Whitespace fixes and __init added.
Reported-by: default avatar"Ryan O'Hara" <rohara@redhat.com>
Signed-off-by: default avatarHans Schillstrom <hans.schillstrom@ericsson.com>
Acked-by: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarJesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
Cc: Andreas Unterkircher <unki@netshadow.at>
parent 001b7cc9
...@@ -1202,6 +1202,8 @@ ip_vs_lookup_real_service(struct net *net, int af, __u16 protocol, ...@@ -1202,6 +1202,8 @@ ip_vs_lookup_real_service(struct net *net, int af, __u16 protocol,
extern int ip_vs_use_count_inc(void); extern int ip_vs_use_count_inc(void);
extern void ip_vs_use_count_dec(void); extern void ip_vs_use_count_dec(void);
extern int ip_vs_register_nl_ioctl(void);
extern void ip_vs_unregister_nl_ioctl(void);
extern int ip_vs_control_init(void); extern int ip_vs_control_init(void);
extern void ip_vs_control_cleanup(void); extern void ip_vs_control_cleanup(void);
extern struct ip_vs_dest * extern struct ip_vs_dest *
......
...@@ -2003,10 +2003,18 @@ static int __init ip_vs_init(void) ...@@ -2003,10 +2003,18 @@ static int __init ip_vs_init(void)
goto cleanup_dev; goto cleanup_dev;
} }
ret = ip_vs_register_nl_ioctl();
if (ret < 0) {
pr_err("can't register netlink/ioctl.\n");
goto cleanup_hooks;
}
pr_info("ipvs loaded.\n"); pr_info("ipvs loaded.\n");
return ret; return ret;
cleanup_hooks:
nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
cleanup_dev: cleanup_dev:
unregister_pernet_device(&ipvs_core_dev_ops); unregister_pernet_device(&ipvs_core_dev_ops);
cleanup_sub: cleanup_sub:
...@@ -2022,6 +2030,7 @@ static int __init ip_vs_init(void) ...@@ -2022,6 +2030,7 @@ static int __init ip_vs_init(void)
static void __exit ip_vs_cleanup(void) static void __exit ip_vs_cleanup(void)
{ {
ip_vs_unregister_nl_ioctl();
nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops)); nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
unregister_pernet_device(&ipvs_core_dev_ops); unregister_pernet_device(&ipvs_core_dev_ops);
unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */ unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */
......
...@@ -3754,21 +3754,10 @@ void __net_exit ip_vs_control_net_cleanup(struct net *net) ...@@ -3754,21 +3754,10 @@ void __net_exit ip_vs_control_net_cleanup(struct net *net)
free_percpu(ipvs->tot_stats.cpustats); free_percpu(ipvs->tot_stats.cpustats);
} }
int __init ip_vs_control_init(void) int __init ip_vs_register_nl_ioctl(void)
{ {
int idx;
int ret; int ret;
EnterFunction(2);
/* Initialize svc_table, ip_vs_svc_fwm_table, rs_table */
for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
INIT_LIST_HEAD(&ip_vs_svc_table[idx]);
INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
}
smp_wmb(); /* Do we really need it now ? */
ret = nf_register_sockopt(&ip_vs_sockopts); ret = nf_register_sockopt(&ip_vs_sockopts);
if (ret) { if (ret) {
pr_err("cannot register sockopt.\n"); pr_err("cannot register sockopt.\n");
...@@ -3780,28 +3769,47 @@ int __init ip_vs_control_init(void) ...@@ -3780,28 +3769,47 @@ int __init ip_vs_control_init(void)
pr_err("cannot register Generic Netlink interface.\n"); pr_err("cannot register Generic Netlink interface.\n");
goto err_genl; goto err_genl;
} }
ret = register_netdevice_notifier(&ip_vs_dst_notifier);
if (ret < 0)
goto err_notf;
LeaveFunction(2);
return 0; return 0;
err_notf:
ip_vs_genl_unregister();
err_genl: err_genl:
nf_unregister_sockopt(&ip_vs_sockopts); nf_unregister_sockopt(&ip_vs_sockopts);
err_sock: err_sock:
return ret; return ret;
} }
void ip_vs_unregister_nl_ioctl(void)
{
ip_vs_genl_unregister();
nf_unregister_sockopt(&ip_vs_sockopts);
}
int __init ip_vs_control_init(void)
{
int idx;
int ret;
EnterFunction(2);
/* Initialize svc_table, ip_vs_svc_fwm_table, rs_table */
for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
INIT_LIST_HEAD(&ip_vs_svc_table[idx]);
INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
}
smp_wmb(); /* Do we really need it now ? */
ret = register_netdevice_notifier(&ip_vs_dst_notifier);
if (ret < 0)
return ret;
LeaveFunction(2);
return 0;
}
void ip_vs_control_cleanup(void) void ip_vs_control_cleanup(void)
{ {
EnterFunction(2); EnterFunction(2);
unregister_netdevice_notifier(&ip_vs_dst_notifier); unregister_netdevice_notifier(&ip_vs_dst_notifier);
ip_vs_genl_unregister();
nf_unregister_sockopt(&ip_vs_sockopts);
LeaveFunction(2); LeaveFunction(2);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment