aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Schillstrom <hans.schillstrom@ericsson.com>2011-01-03 08:45:00 -0500
committerSimon Horman <horms@verge.net.au>2011-01-12 20:30:28 -0500
commitf2431e6e9255461eb1476340a89ad32ad4b38b03 (patch)
tree934974c80d2c01b44768369ca9b188f64c6ab979
parentf6340ee0c6b9498ec918a7bb2f44e20abb8b2833 (diff)
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: Hans Schillstrom <hans.schillstrom@ericsson.com> Acked-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r--include/net/ip_vs.h4
-rw-r--r--include/net/netns/ip_vs.h3
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c23
3 files changed, 16 insertions, 14 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index fbe660f95873..b23bea62f708 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -662,8 +662,8 @@ struct ip_vs_dest {
662 struct list_head d_list; /* for table with all the dests */ 662 struct list_head d_list; /* for table with all the dests */
663 663
664 u16 af; /* address family */ 664 u16 af; /* address family */
665 union nf_inet_addr addr; /* IP address of the server */
666 __be16 port; /* port number of the server */ 665 __be16 port; /* port number of the server */
666 union nf_inet_addr addr; /* IP address of the server */
667 volatile unsigned flags; /* dest status flags */ 667 volatile unsigned flags; /* dest status flags */
668 atomic_t conn_flags; /* flags to copy to conn */ 668 atomic_t conn_flags; /* flags to copy to conn */
669 atomic_t weight; /* server weight */ 669 atomic_t weight; /* server weight */
@@ -690,8 +690,8 @@ struct ip_vs_dest {
690 /* for virtual service */ 690 /* for virtual service */
691 struct ip_vs_service *svc; /* service it belongs to */ 691 struct ip_vs_service *svc; /* service it belongs to */
692 __u16 protocol; /* which protocol (TCP/UDP) */ 692 __u16 protocol; /* which protocol (TCP/UDP) */
693 union nf_inet_addr vaddr; /* virtual IP address */
694 __be16 vport; /* virtual port number */ 693 __be16 vport; /* virtual port number */
694 union nf_inet_addr vaddr; /* virtual IP address */
695 __u32 vfwmark; /* firewall mark of service */ 695 __u32 vfwmark; /* firewall mark of service */
696}; 696};
697 697
diff --git a/include/net/netns/ip_vs.h b/include/net/netns/ip_vs.h
index 41332619142c..67ca1cf55af8 100644
--- a/include/net/netns/ip_vs.h
+++ b/include/net/netns/ip_vs.h
@@ -82,6 +82,9 @@ struct netns_ipvs {
82 rwlock_t rs_lock; /* real services table */ 82 rwlock_t rs_lock; /* real services table */
83 /* semaphore for IPVS sockopts. And, [gs]etsockopt may sleep. */ 83 /* semaphore for IPVS sockopts. And, [gs]etsockopt may sleep. */
84 struct lock_class_key ctl_key; /* ctl_mutex debuging */ 84 struct lock_class_key ctl_key; /* ctl_mutex debuging */
85 /* Trash for destinations */
86 struct list_head dest_trash;
87
85 /* sys-ctl struct */ 88 /* sys-ctl struct */
86 struct ctl_table_header *sysctl_hdr; 89 struct ctl_table_header *sysctl_hdr;
87 struct ctl_table *sysctl_tbl; 90 struct ctl_table *sysctl_tbl;
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 6a963d44df48..442edf4be644 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -255,11 +255,6 @@ static struct list_head ip_vs_svc_table[IP_VS_SVC_TAB_SIZE];
255static struct list_head ip_vs_svc_fwm_table[IP_VS_SVC_TAB_SIZE]; 255static struct list_head ip_vs_svc_fwm_table[IP_VS_SVC_TAB_SIZE];
256 256
257/* 257/*
258 * Trash for destinations
259 */
260static LIST_HEAD(ip_vs_dest_trash);
261
262/*
263 * FTP & NULL virtual service counters 258 * FTP & NULL virtual service counters
264 */ 259 */
265static atomic_t ip_vs_ftpsvc_counter = ATOMIC_INIT(0); 260static atomic_t ip_vs_ftpsvc_counter = ATOMIC_INIT(0);
@@ -650,11 +645,12 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, const union nf_inet_addr *daddr,
650 __be16 dport) 645 __be16 dport)
651{ 646{
652 struct ip_vs_dest *dest, *nxt; 647 struct ip_vs_dest *dest, *nxt;
648 struct netns_ipvs *ipvs = net_ipvs(svc->net);
653 649
654 /* 650 /*
655 * Find the destination in trash 651 * Find the destination in trash
656 */ 652 */
657 list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) { 653 list_for_each_entry_safe(dest, nxt, &ipvs->dest_trash, n_list) {
658 IP_VS_DBG_BUF(3, "Destination %u/%s:%u still in trash, " 654 IP_VS_DBG_BUF(3, "Destination %u/%s:%u still in trash, "
659 "dest->refcnt=%d\n", 655 "dest->refcnt=%d\n",
660 dest->vfwmark, 656 dest->vfwmark,
@@ -703,11 +699,12 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, const union nf_inet_addr *daddr,
703 * are expired, and the refcnt of each destination in the trash must 699 * are expired, and the refcnt of each destination in the trash must
704 * be 1, so we simply release them here. 700 * be 1, so we simply release them here.
705 */ 701 */
706static void ip_vs_trash_cleanup(void) 702static void ip_vs_trash_cleanup(struct net *net)
707{ 703{
708 struct ip_vs_dest *dest, *nxt; 704 struct ip_vs_dest *dest, *nxt;
705 struct netns_ipvs *ipvs = net_ipvs(net);
709 706
710 list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) { 707 list_for_each_entry_safe(dest, nxt, &ipvs->dest_trash, n_list) {
711 list_del(&dest->n_list); 708 list_del(&dest->n_list);
712 ip_vs_dst_reset(dest); 709 ip_vs_dst_reset(dest);
713 __ip_vs_unbind_svc(dest); 710 __ip_vs_unbind_svc(dest);
@@ -1021,7 +1018,7 @@ static void __ip_vs_del_dest(struct net *net, struct ip_vs_dest *dest)
1021 IP_VS_DBG_ADDR(dest->af, &dest->addr), 1018 IP_VS_DBG_ADDR(dest->af, &dest->addr),
1022 ntohs(dest->port), 1019 ntohs(dest->port),
1023 atomic_read(&dest->refcnt)); 1020 atomic_read(&dest->refcnt));
1024 list_add(&dest->n_list, &ip_vs_dest_trash); 1021 list_add(&dest->n_list, &ipvs->dest_trash);
1025 atomic_inc(&dest->refcnt); 1022 atomic_inc(&dest->refcnt);
1026 } 1023 }
1027} 1024}
@@ -3503,6 +3500,8 @@ int __net_init __ip_vs_control_init(struct net *net)
3503 for (idx = 0; idx < IP_VS_RTAB_SIZE; idx++) 3500 for (idx = 0; idx < IP_VS_RTAB_SIZE; idx++)
3504 INIT_LIST_HEAD(&ipvs->rs_table[idx]); 3501 INIT_LIST_HEAD(&ipvs->rs_table[idx]);
3505 3502
3503 INIT_LIST_HEAD(&ipvs->dest_trash);
3504
3506 /* procfs stats */ 3505 /* procfs stats */
3507 ipvs->tot_stats = kzalloc(sizeof(struct ip_vs_stats), GFP_KERNEL); 3506 ipvs->tot_stats = kzalloc(sizeof(struct ip_vs_stats), GFP_KERNEL);
3508 if (ipvs->tot_stats == NULL) { 3507 if (ipvs->tot_stats == NULL) {
@@ -3584,13 +3583,14 @@ static void __net_exit __ip_vs_control_cleanup(struct net *net)
3584 if (!net_eq(net, &init_net)) /* netns not enabled yet */ 3583 if (!net_eq(net, &init_net)) /* netns not enabled yet */
3585 return; 3584 return;
3586 3585
3586 ip_vs_trash_cleanup(net);
3587 ip_vs_kill_estimator(net, ipvs->tot_stats); 3587 ip_vs_kill_estimator(net, ipvs->tot_stats);
3588 cancel_delayed_work_sync(&ipvs->defense_work);
3589 cancel_work_sync(&ipvs->defense_work.work);
3588 unregister_net_sysctl_table(ipvs->sysctl_hdr); 3590 unregister_net_sysctl_table(ipvs->sysctl_hdr);
3589 proc_net_remove(net, "ip_vs_stats_percpu"); 3591 proc_net_remove(net, "ip_vs_stats_percpu");
3590 proc_net_remove(net, "ip_vs_stats"); 3592 proc_net_remove(net, "ip_vs_stats");
3591 proc_net_remove(net, "ip_vs"); 3593 proc_net_remove(net, "ip_vs");
3592 cancel_delayed_work_sync(&ipvs->defense_work);
3593 cancel_work_sync(&ipvs->defense_work.work);
3594 free_percpu(ipvs->cpustats); 3594 free_percpu(ipvs->cpustats);
3595 kfree(ipvs->tot_stats); 3595 kfree(ipvs->tot_stats);
3596} 3596}
@@ -3647,7 +3647,6 @@ err:
3647void ip_vs_control_cleanup(void) 3647void ip_vs_control_cleanup(void)
3648{ 3648{
3649 EnterFunction(2); 3649 EnterFunction(2);
3650 ip_vs_trash_cleanup();
3651 unregister_pernet_subsys(&ipvs_control_ops); 3650 unregister_pernet_subsys(&ipvs_control_ops);
3652 ip_vs_genl_unregister(); 3651 ip_vs_genl_unregister();
3653 nf_unregister_sockopt(&ip_vs_sockopts); 3652 nf_unregister_sockopt(&ip_vs_sockopts);