[RFC PATCH net-next 3/4] ipvs: check return value of add_dest

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If the scheduler's add_dest function fails, free the newly allocated or
reclaimed dest and then return the error code to the user.

Signed-off-by: Alex Gartrell <agartrell@xxxxxx>
---
 net/netfilter/ipvs/ip_vs_ctl.c | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 6341e3f..d384b7f 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -787,7 +787,7 @@ ip_vs_zero_stats(struct ip_vs_stats *stats)
 /*
  *	Update a destination in the given service
  */
-static void
+static int
 __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
 		    struct ip_vs_dest_user_kern *udest, int add)
 {
@@ -795,6 +795,7 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
 	struct ip_vs_service *old_svc;
 	struct ip_vs_scheduler *sched;
 	int conn_flags;
+	int ret = 0;
 
 	/* We cannot modify an address and change the address family */
 	BUG_ON(!add && udest->af != dest->af);
@@ -850,12 +851,20 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
 		ip_vs_start_estimator(svc->net, &dest->stats);
 		list_add_rcu(&dest->n_list, &svc->destinations);
 		svc->num_dests++;
-		if (sched->add_dest)
-			sched->add_dest(svc, dest);
+		if (sched->add_dest) {
+			ret = sched->add_dest(svc, dest);
+			if (ret) {
+				ip_vs_stop_estimator(svc->net, &dest->stats);
+				list_del_rcu(&dest->n_list);
+				svc->num_dests--;
+			}
+		}
 	} else {
 		if (sched->upd_dest)
 			sched->upd_dest(svc, dest);
 	}
+
+	return ret;
 }
 
 
@@ -867,6 +876,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
 {
 	struct ip_vs_dest *dest;
 	unsigned int atype, i;
+	int ret;
 
 	EnterFunction(2);
 
@@ -915,10 +925,13 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
 	INIT_HLIST_NODE(&dest->d_list);
 	spin_lock_init(&dest->dst_lock);
 	spin_lock_init(&dest->stats.lock);
-	__ip_vs_update_dest(svc, dest, udest, 1);
+
+	ret = __ip_vs_update_dest(svc, dest, udest, 1);
+	if (ret)
+		kfree(dest);
 
 	LeaveFunction(2);
-	return 0;
+	return ret;
 
 err_alloc:
 	kfree(dest);
@@ -977,8 +990,9 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
 			      IP_VS_DBG_ADDR(svc->af, &dest->vaddr),
 			      ntohs(dest->vport));
 
-		__ip_vs_update_dest(svc, dest, udest, 1);
-		ret = 0;
+		ret = __ip_vs_update_dest(svc, dest, udest, 1);
+		if (ret)
+			ip_vs_trash_put_dest(net_ipvs(svc->net), dest, false);
 	} else {
 		/*
 		 * Allocate and initialize the dest structure
-- 
Alex Gartrell <agartrell@xxxxxx>

--
To unsubscribe from this list: send the line "unsubscribe lvs-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Filesystem Devel]     [Linux NFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]     [X.Org]

  Powered by Linux