Commit 5414fc12 authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://1984.lsi.us.es/net

parents 3885ca78 6cf51852
...@@ -393,7 +393,7 @@ struct ip_vs_protocol { ...@@ -393,7 +393,7 @@ struct ip_vs_protocol {
void (*exit)(struct ip_vs_protocol *pp); void (*exit)(struct ip_vs_protocol *pp);
void (*init_netns)(struct net *net, struct ip_vs_proto_data *pd); int (*init_netns)(struct net *net, struct ip_vs_proto_data *pd);
void (*exit_netns)(struct net *net, struct ip_vs_proto_data *pd); void (*exit_netns)(struct net *net, struct ip_vs_proto_data *pd);
...@@ -1203,6 +1203,8 @@ ip_vs_lookup_real_service(struct net *net, int af, __u16 protocol, ...@@ -1203,6 +1203,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 *
......
...@@ -1924,6 +1924,7 @@ static int __net_init __ip_vs_init(struct net *net) ...@@ -1924,6 +1924,7 @@ static int __net_init __ip_vs_init(struct net *net)
control_fail: control_fail:
ip_vs_estimator_net_cleanup(net); ip_vs_estimator_net_cleanup(net);
estimator_fail: estimator_fail:
net->ipvs = NULL;
return -ENOMEM; return -ENOMEM;
} }
...@@ -1936,6 +1937,7 @@ static void __net_exit __ip_vs_cleanup(struct net *net) ...@@ -1936,6 +1937,7 @@ static void __net_exit __ip_vs_cleanup(struct net *net)
ip_vs_control_net_cleanup(net); ip_vs_control_net_cleanup(net);
ip_vs_estimator_net_cleanup(net); ip_vs_estimator_net_cleanup(net);
IP_VS_DBG(2, "ipvs netns %d released\n", net_ipvs(net)->gen); IP_VS_DBG(2, "ipvs netns %d released\n", net_ipvs(net)->gen);
net->ipvs = NULL;
} }
static void __net_exit __ip_vs_dev_cleanup(struct net *net) static void __net_exit __ip_vs_dev_cleanup(struct net *net)
...@@ -1993,10 +1995,18 @@ static int __init ip_vs_init(void) ...@@ -1993,10 +1995,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:
...@@ -2012,6 +2022,7 @@ static int __init ip_vs_init(void) ...@@ -2012,6 +2022,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 */
......
...@@ -3680,7 +3680,7 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net) ...@@ -3680,7 +3680,7 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net)
return 0; return 0;
} }
void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net) void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net)
{ {
struct netns_ipvs *ipvs = net_ipvs(net); struct netns_ipvs *ipvs = net_ipvs(net);
...@@ -3692,7 +3692,7 @@ void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net) ...@@ -3692,7 +3692,7 @@ void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net)
#else #else
int __net_init ip_vs_control_net_init_sysctl(struct net *net) { return 0; } int __net_init ip_vs_control_net_init_sysctl(struct net *net) { return 0; }
void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net) { } void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) { }
#endif #endif
...@@ -3750,21 +3750,10 @@ void __net_exit ip_vs_control_net_cleanup(struct net *net) ...@@ -3750,21 +3750,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");
...@@ -3776,28 +3765,47 @@ int __init ip_vs_control_init(void) ...@@ -3776,28 +3765,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);
} }
...@@ -439,6 +439,8 @@ static int __net_init __ip_vs_ftp_init(struct net *net) ...@@ -439,6 +439,8 @@ static int __net_init __ip_vs_ftp_init(struct net *net)
struct ip_vs_app *app; struct ip_vs_app *app;
struct netns_ipvs *ipvs = net_ipvs(net); struct netns_ipvs *ipvs = net_ipvs(net);
if (!ipvs)
return -ENOENT;
app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL); app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL);
if (!app) if (!app)
return -ENOMEM; return -ENOMEM;
......
...@@ -551,6 +551,9 @@ static int __net_init __ip_vs_lblc_init(struct net *net) ...@@ -551,6 +551,9 @@ static int __net_init __ip_vs_lblc_init(struct net *net)
{ {
struct netns_ipvs *ipvs = net_ipvs(net); struct netns_ipvs *ipvs = net_ipvs(net);
if (!ipvs)
return -ENOENT;
if (!net_eq(net, &init_net)) { if (!net_eq(net, &init_net)) {
ipvs->lblc_ctl_table = kmemdup(vs_vars_table, ipvs->lblc_ctl_table = kmemdup(vs_vars_table,
sizeof(vs_vars_table), sizeof(vs_vars_table),
......
...@@ -745,6 +745,9 @@ static int __net_init __ip_vs_lblcr_init(struct net *net) ...@@ -745,6 +745,9 @@ static int __net_init __ip_vs_lblcr_init(struct net *net)
{ {
struct netns_ipvs *ipvs = net_ipvs(net); struct netns_ipvs *ipvs = net_ipvs(net);
if (!ipvs)
return -ENOENT;
if (!net_eq(net, &init_net)) { if (!net_eq(net, &init_net)) {
ipvs->lblcr_ctl_table = kmemdup(vs_vars_table, ipvs->lblcr_ctl_table = kmemdup(vs_vars_table,
sizeof(vs_vars_table), sizeof(vs_vars_table),
......
...@@ -59,9 +59,6 @@ static int __used __init register_ip_vs_protocol(struct ip_vs_protocol *pp) ...@@ -59,9 +59,6 @@ static int __used __init register_ip_vs_protocol(struct ip_vs_protocol *pp)
return 0; return 0;
} }
#if defined(CONFIG_IP_VS_PROTO_TCP) || defined(CONFIG_IP_VS_PROTO_UDP) || \
defined(CONFIG_IP_VS_PROTO_SCTP) || defined(CONFIG_IP_VS_PROTO_AH) || \
defined(CONFIG_IP_VS_PROTO_ESP)
/* /*
* register an ipvs protocols netns related data * register an ipvs protocols netns related data
*/ */
...@@ -81,12 +78,18 @@ register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp) ...@@ -81,12 +78,18 @@ register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp)
ipvs->proto_data_table[hash] = pd; ipvs->proto_data_table[hash] = pd;
atomic_set(&pd->appcnt, 0); /* Init app counter */ atomic_set(&pd->appcnt, 0); /* Init app counter */
if (pp->init_netns != NULL) if (pp->init_netns != NULL) {
pp->init_netns(net, pd); int ret = pp->init_netns(net, pd);
if (ret) {
/* unlink an free proto data */
ipvs->proto_data_table[hash] = pd->next;
kfree(pd);
return ret;
}
}
return 0; return 0;
} }
#endif
/* /*
* unregister an ipvs protocol * unregister an ipvs protocol
...@@ -316,22 +319,35 @@ ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp, ...@@ -316,22 +319,35 @@ ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
*/ */
int __net_init ip_vs_protocol_net_init(struct net *net) int __net_init ip_vs_protocol_net_init(struct net *net)
{ {
int i, ret;
static struct ip_vs_protocol *protos[] = {
#ifdef CONFIG_IP_VS_PROTO_TCP #ifdef CONFIG_IP_VS_PROTO_TCP
register_ip_vs_proto_netns(net, &ip_vs_protocol_tcp); &ip_vs_protocol_tcp,
#endif #endif
#ifdef CONFIG_IP_VS_PROTO_UDP #ifdef CONFIG_IP_VS_PROTO_UDP
register_ip_vs_proto_netns(net, &ip_vs_protocol_udp); &ip_vs_protocol_udp,
#endif #endif
#ifdef CONFIG_IP_VS_PROTO_SCTP #ifdef CONFIG_IP_VS_PROTO_SCTP
register_ip_vs_proto_netns(net, &ip_vs_protocol_sctp); &ip_vs_protocol_sctp,
#endif #endif
#ifdef CONFIG_IP_VS_PROTO_AH #ifdef CONFIG_IP_VS_PROTO_AH
register_ip_vs_proto_netns(net, &ip_vs_protocol_ah); &ip_vs_protocol_ah,
#endif #endif
#ifdef CONFIG_IP_VS_PROTO_ESP #ifdef CONFIG_IP_VS_PROTO_ESP
register_ip_vs_proto_netns(net, &ip_vs_protocol_esp); &ip_vs_protocol_esp,
#endif #endif
};
for (i = 0; i < ARRAY_SIZE(protos); i++) {
ret = register_ip_vs_proto_netns(net, protos[i]);
if (ret < 0)
goto cleanup;
}
return 0; return 0;
cleanup:
ip_vs_protocol_net_cleanup(net);
return ret;
} }
void __net_exit ip_vs_protocol_net_cleanup(struct net *net) void __net_exit ip_vs_protocol_net_cleanup(struct net *net)
......
...@@ -1090,7 +1090,7 @@ static int sctp_app_conn_bind(struct ip_vs_conn *cp) ...@@ -1090,7 +1090,7 @@ static int sctp_app_conn_bind(struct ip_vs_conn *cp)
* timeouts is netns related now. * timeouts is netns related now.
* --------------------------------------------- * ---------------------------------------------
*/ */
static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd) static int __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
{ {
struct netns_ipvs *ipvs = net_ipvs(net); struct netns_ipvs *ipvs = net_ipvs(net);
...@@ -1098,6 +1098,9 @@ static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd) ...@@ -1098,6 +1098,9 @@ static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
spin_lock_init(&ipvs->sctp_app_lock); spin_lock_init(&ipvs->sctp_app_lock);
pd->timeout_table = ip_vs_create_timeout_table((int *)sctp_timeouts, pd->timeout_table = ip_vs_create_timeout_table((int *)sctp_timeouts,
sizeof(sctp_timeouts)); sizeof(sctp_timeouts));
if (!pd->timeout_table)
return -ENOMEM;
return 0;
} }
static void __ip_vs_sctp_exit(struct net *net, struct ip_vs_proto_data *pd) static void __ip_vs_sctp_exit(struct net *net, struct ip_vs_proto_data *pd)
......
...@@ -677,7 +677,7 @@ void ip_vs_tcp_conn_listen(struct net *net, struct ip_vs_conn *cp) ...@@ -677,7 +677,7 @@ void ip_vs_tcp_conn_listen(struct net *net, struct ip_vs_conn *cp)
* timeouts is netns related now. * timeouts is netns related now.
* --------------------------------------------- * ---------------------------------------------
*/ */
static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd) static int __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
{ {
struct netns_ipvs *ipvs = net_ipvs(net); struct netns_ipvs *ipvs = net_ipvs(net);
...@@ -685,7 +685,10 @@ static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd) ...@@ -685,7 +685,10 @@ static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
spin_lock_init(&ipvs->tcp_app_lock); spin_lock_init(&ipvs->tcp_app_lock);
pd->timeout_table = ip_vs_create_timeout_table((int *)tcp_timeouts, pd->timeout_table = ip_vs_create_timeout_table((int *)tcp_timeouts,
sizeof(tcp_timeouts)); sizeof(tcp_timeouts));
if (!pd->timeout_table)
return -ENOMEM;
pd->tcp_state_table = tcp_states; pd->tcp_state_table = tcp_states;
return 0;
} }
static void __ip_vs_tcp_exit(struct net *net, struct ip_vs_proto_data *pd) static void __ip_vs_tcp_exit(struct net *net, struct ip_vs_proto_data *pd)
......
...@@ -467,7 +467,7 @@ udp_state_transition(struct ip_vs_conn *cp, int direction, ...@@ -467,7 +467,7 @@ udp_state_transition(struct ip_vs_conn *cp, int direction,
cp->timeout = pd->timeout_table[IP_VS_UDP_S_NORMAL]; cp->timeout = pd->timeout_table[IP_VS_UDP_S_NORMAL];
} }
static void __udp_init(struct net *net, struct ip_vs_proto_data *pd) static int __udp_init(struct net *net, struct ip_vs_proto_data *pd)
{ {
struct netns_ipvs *ipvs = net_ipvs(net); struct netns_ipvs *ipvs = net_ipvs(net);
...@@ -475,6 +475,9 @@ static void __udp_init(struct net *net, struct ip_vs_proto_data *pd) ...@@ -475,6 +475,9 @@ static void __udp_init(struct net *net, struct ip_vs_proto_data *pd)
spin_lock_init(&ipvs->udp_app_lock); spin_lock_init(&ipvs->udp_app_lock);
pd->timeout_table = ip_vs_create_timeout_table((int *)udp_timeouts, pd->timeout_table = ip_vs_create_timeout_table((int *)udp_timeouts,
sizeof(udp_timeouts)); sizeof(udp_timeouts));
if (!pd->timeout_table)
return -ENOMEM;
return 0;
} }
static void __udp_exit(struct net *net, struct ip_vs_proto_data *pd) static void __udp_exit(struct net *net, struct ip_vs_proto_data *pd)
......
...@@ -227,7 +227,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) ...@@ -227,7 +227,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
} }
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
if (info->timeout) { if (info->timeout[0]) {
typeof(nf_ct_timeout_find_get_hook) timeout_find_get; typeof(nf_ct_timeout_find_get_hook) timeout_find_get;
struct nf_conn_timeout *timeout_ext; struct nf_conn_timeout *timeout_ext;
......
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