Commit f2431e6e authored by Hans Schillstrom's avatar Hans Schillstrom Committed by Simon Horman

IPVS: netns, trash handling

trash list per namspace,
and reordering of some params in dst struct.

[ horms@verge.net.au: Use cancel_delayed_work_sync() instead of
	              cancel_rearming_delayed_work(). Found during
		      merge conflict resoliution ]
Signed-off-by: default avatarHans Schillstrom <hans.schillstrom@ericsson.com>
Acked-by: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
parent f6340ee0
...@@ -662,8 +662,8 @@ struct ip_vs_dest { ...@@ -662,8 +662,8 @@ struct ip_vs_dest {
struct list_head d_list; /* for table with all the dests */ struct list_head d_list; /* for table with all the dests */
u16 af; /* address family */ u16 af; /* address family */
union nf_inet_addr addr; /* IP address of the server */
__be16 port; /* port number of the server */ __be16 port; /* port number of the server */
union nf_inet_addr addr; /* IP address of the server */
volatile unsigned flags; /* dest status flags */ volatile unsigned flags; /* dest status flags */
atomic_t conn_flags; /* flags to copy to conn */ atomic_t conn_flags; /* flags to copy to conn */
atomic_t weight; /* server weight */ atomic_t weight; /* server weight */
...@@ -690,8 +690,8 @@ struct ip_vs_dest { ...@@ -690,8 +690,8 @@ struct ip_vs_dest {
/* for virtual service */ /* for virtual service */
struct ip_vs_service *svc; /* service it belongs to */ struct ip_vs_service *svc; /* service it belongs to */
__u16 protocol; /* which protocol (TCP/UDP) */ __u16 protocol; /* which protocol (TCP/UDP) */
union nf_inet_addr vaddr; /* virtual IP address */
__be16 vport; /* virtual port number */ __be16 vport; /* virtual port number */
union nf_inet_addr vaddr; /* virtual IP address */
__u32 vfwmark; /* firewall mark of service */ __u32 vfwmark; /* firewall mark of service */
}; };
......
...@@ -82,6 +82,9 @@ struct netns_ipvs { ...@@ -82,6 +82,9 @@ struct netns_ipvs {
rwlock_t rs_lock; /* real services table */ rwlock_t rs_lock; /* real services table */
/* semaphore for IPVS sockopts. And, [gs]etsockopt may sleep. */ /* semaphore for IPVS sockopts. And, [gs]etsockopt may sleep. */
struct lock_class_key ctl_key; /* ctl_mutex debuging */ struct lock_class_key ctl_key; /* ctl_mutex debuging */
/* Trash for destinations */
struct list_head dest_trash;
/* sys-ctl struct */ /* sys-ctl struct */
struct ctl_table_header *sysctl_hdr; struct ctl_table_header *sysctl_hdr;
struct ctl_table *sysctl_tbl; struct ctl_table *sysctl_tbl;
......
...@@ -254,11 +254,6 @@ static struct list_head ip_vs_svc_table[IP_VS_SVC_TAB_SIZE]; ...@@ -254,11 +254,6 @@ static struct list_head ip_vs_svc_table[IP_VS_SVC_TAB_SIZE];
/* the service table hashed by fwmark */ /* the service table hashed by fwmark */
static struct list_head ip_vs_svc_fwm_table[IP_VS_SVC_TAB_SIZE]; static struct list_head ip_vs_svc_fwm_table[IP_VS_SVC_TAB_SIZE];
/*
* Trash for destinations
*/
static LIST_HEAD(ip_vs_dest_trash);
/* /*
* FTP & NULL virtual service counters * FTP & NULL virtual service counters
*/ */
...@@ -650,11 +645,12 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, const union nf_inet_addr *daddr, ...@@ -650,11 +645,12 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, const union nf_inet_addr *daddr,
__be16 dport) __be16 dport)
{ {
struct ip_vs_dest *dest, *nxt; struct ip_vs_dest *dest, *nxt;
struct netns_ipvs *ipvs = net_ipvs(svc->net);
/* /*
* Find the destination in trash * Find the destination in trash
*/ */
list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) { list_for_each_entry_safe(dest, nxt, &ipvs->dest_trash, n_list) {
IP_VS_DBG_BUF(3, "Destination %u/%s:%u still in trash, " IP_VS_DBG_BUF(3, "Destination %u/%s:%u still in trash, "
"dest->refcnt=%d\n", "dest->refcnt=%d\n",
dest->vfwmark, dest->vfwmark,
...@@ -703,11 +699,12 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, const union nf_inet_addr *daddr, ...@@ -703,11 +699,12 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, const union nf_inet_addr *daddr,
* are expired, and the refcnt of each destination in the trash must * are expired, and the refcnt of each destination in the trash must
* be 1, so we simply release them here. * be 1, so we simply release them here.
*/ */
static void ip_vs_trash_cleanup(void) static void ip_vs_trash_cleanup(struct net *net)
{ {
struct ip_vs_dest *dest, *nxt; struct ip_vs_dest *dest, *nxt;
struct netns_ipvs *ipvs = net_ipvs(net);
list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) { list_for_each_entry_safe(dest, nxt, &ipvs->dest_trash, n_list) {
list_del(&dest->n_list); list_del(&dest->n_list);
ip_vs_dst_reset(dest); ip_vs_dst_reset(dest);
__ip_vs_unbind_svc(dest); __ip_vs_unbind_svc(dest);
...@@ -1021,7 +1018,7 @@ static void __ip_vs_del_dest(struct net *net, struct ip_vs_dest *dest) ...@@ -1021,7 +1018,7 @@ static void __ip_vs_del_dest(struct net *net, struct ip_vs_dest *dest)
IP_VS_DBG_ADDR(dest->af, &dest->addr), IP_VS_DBG_ADDR(dest->af, &dest->addr),
ntohs(dest->port), ntohs(dest->port),
atomic_read(&dest->refcnt)); atomic_read(&dest->refcnt));
list_add(&dest->n_list, &ip_vs_dest_trash); list_add(&dest->n_list, &ipvs->dest_trash);
atomic_inc(&dest->refcnt); atomic_inc(&dest->refcnt);
} }
} }
...@@ -3503,6 +3500,8 @@ int __net_init __ip_vs_control_init(struct net *net) ...@@ -3503,6 +3500,8 @@ int __net_init __ip_vs_control_init(struct net *net)
for (idx = 0; idx < IP_VS_RTAB_SIZE; idx++) for (idx = 0; idx < IP_VS_RTAB_SIZE; idx++)
INIT_LIST_HEAD(&ipvs->rs_table[idx]); INIT_LIST_HEAD(&ipvs->rs_table[idx]);
INIT_LIST_HEAD(&ipvs->dest_trash);
/* procfs stats */ /* procfs stats */
ipvs->tot_stats = kzalloc(sizeof(struct ip_vs_stats), GFP_KERNEL); ipvs->tot_stats = kzalloc(sizeof(struct ip_vs_stats), GFP_KERNEL);
if (ipvs->tot_stats == NULL) { if (ipvs->tot_stats == NULL) {
...@@ -3584,13 +3583,14 @@ static void __net_exit __ip_vs_control_cleanup(struct net *net) ...@@ -3584,13 +3583,14 @@ static void __net_exit __ip_vs_control_cleanup(struct net *net)
if (!net_eq(net, &init_net)) /* netns not enabled yet */ if (!net_eq(net, &init_net)) /* netns not enabled yet */
return; return;
ip_vs_trash_cleanup(net);
ip_vs_kill_estimator(net, ipvs->tot_stats); ip_vs_kill_estimator(net, ipvs->tot_stats);
cancel_delayed_work_sync(&ipvs->defense_work);
cancel_work_sync(&ipvs->defense_work.work);
unregister_net_sysctl_table(ipvs->sysctl_hdr); unregister_net_sysctl_table(ipvs->sysctl_hdr);
proc_net_remove(net, "ip_vs_stats_percpu"); proc_net_remove(net, "ip_vs_stats_percpu");
proc_net_remove(net, "ip_vs_stats"); proc_net_remove(net, "ip_vs_stats");
proc_net_remove(net, "ip_vs"); proc_net_remove(net, "ip_vs");
cancel_delayed_work_sync(&ipvs->defense_work);
cancel_work_sync(&ipvs->defense_work.work);
free_percpu(ipvs->cpustats); free_percpu(ipvs->cpustats);
kfree(ipvs->tot_stats); kfree(ipvs->tot_stats);
} }
...@@ -3647,7 +3647,6 @@ int __init ip_vs_control_init(void) ...@@ -3647,7 +3647,6 @@ int __init ip_vs_control_init(void)
void ip_vs_control_cleanup(void) void ip_vs_control_cleanup(void)
{ {
EnterFunction(2); EnterFunction(2);
ip_vs_trash_cleanup();
unregister_pernet_subsys(&ipvs_control_ops); unregister_pernet_subsys(&ipvs_control_ops);
ip_vs_genl_unregister(); ip_vs_genl_unregister();
nf_unregister_sockopt(&ip_vs_sockopts); nf_unregister_sockopt(&ip_vs_sockopts);
......
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