aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2013-03-22 05:46:38 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2013-04-01 18:23:48 -0400
commitfca9c20ae1e510525f8a2aaa25861789fd721193 (patch)
tree810ace8990d277c3dbad6632919b605c85ad316e /net/netfilter
parent6b6df46663e7aa6f7b1d82435a3488f9b81316b3 (diff)
ipvs: add ip_vs_dest_hold and ip_vs_dest_put
ip_vs_dest_hold will be used under RCU lock while ip_vs_dest_put can be called even after dest is removed from service, as it happens for conns and some schedulers. Signed-off-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c9
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c4
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c4
3 files changed, 6 insertions, 11 deletions
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index e3e2b4d3b6d8..1b29e4a2b26c 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -554,7 +554,7 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
554 return; 554 return;
555 555
556 /* Increase the refcnt counter of the dest */ 556 /* Increase the refcnt counter of the dest */
557 atomic_inc(&dest->refcnt); 557 ip_vs_dest_hold(dest);
558 558
559 conn_flags = atomic_read(&dest->conn_flags); 559 conn_flags = atomic_read(&dest->conn_flags);
560 if (cp->protocol != IPPROTO_UDP) 560 if (cp->protocol != IPPROTO_UDP)
@@ -700,12 +700,7 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp)
700 dest->flags &= ~IP_VS_DEST_F_OVERLOAD; 700 dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
701 } 701 }
702 702
703 /* 703 ip_vs_dest_put(dest);
704 * Simply decrease the refcnt of the dest, because the
705 * dest will be either in service's destination list
706 * or in the trash.
707 */
708 atomic_dec(&dest->refcnt);
709} 704}
710 705
711static int expire_quiescent_template(struct netns_ipvs *ipvs, 706static int expire_quiescent_template(struct netns_ipvs *ipvs,
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index d64f800a3426..a4f638880470 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -616,7 +616,7 @@ struct ip_vs_dest *ip_vs_find_dest(struct net *net, int af,
616 if (!dest) 616 if (!dest)
617 dest = ip_vs_lookup_dest(svc, daddr, port ^ dport); 617 dest = ip_vs_lookup_dest(svc, daddr, port ^ dport);
618 if (dest) 618 if (dest)
619 atomic_inc(&dest->refcnt); 619 ip_vs_dest_hold(dest);
620 ip_vs_service_put(svc); 620 ip_vs_service_put(svc);
621 return dest; 621 return dest;
622} 622}
@@ -1056,7 +1056,7 @@ static void __ip_vs_del_dest(struct net *net, struct ip_vs_dest *dest)
1056 ntohs(dest->port), 1056 ntohs(dest->port),
1057 atomic_read(&dest->refcnt)); 1057 atomic_read(&dest->refcnt));
1058 list_add(&dest->n_list, &ipvs->dest_trash); 1058 list_add(&dest->n_list, &ipvs->dest_trash);
1059 atomic_inc(&dest->refcnt); 1059 ip_vs_dest_hold(dest);
1060 } 1060 }
1061} 1061}
1062 1062
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 44fd10c539ac..6cc3e52f1f35 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -861,7 +861,7 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
861 if (!dest) { 861 if (!dest) {
862 dest = ip_vs_try_bind_dest(cp); 862 dest = ip_vs_try_bind_dest(cp);
863 if (dest) 863 if (dest)
864 atomic_dec(&dest->refcnt); 864 ip_vs_dest_put(dest);
865 } 865 }
866 } else { 866 } else {
867 /* 867 /*
@@ -874,7 +874,7 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
874 874
875 cp = ip_vs_conn_new(param, daddr, dport, flags, dest, fwmark); 875 cp = ip_vs_conn_new(param, daddr, dport, flags, dest, fwmark);
876 if (dest) 876 if (dest)
877 atomic_dec(&dest->refcnt); 877 ip_vs_dest_put(dest);
878 if (!cp) { 878 if (!cp) {
879 if (param->pe_data) 879 if (param->pe_data)
880 kfree(param->pe_data); 880 kfree(param->pe_data);