Merge 86dd5c30e20d4eb3aee12996d7aa5f3ad975d858 on remote branch

Change-Id: I99c149f49fb0842dfc293bf226e53b02eb09c480
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 4201624..88d38bc 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -773,6 +773,32 @@
 		{
 			IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n");
 
+			/* Delete existing downstream if it exists */
+			if (is_downstream_set[data->prefix.iptype] == true)
+			{
+				if (ipv6_prefix[0] != data->prefix.v6Addr[0] ||
+					ipv6_prefix[1] != data->prefix.v6Addr[1])
+				{
+					IPACMDBG_H("Del existing downstream for IP iptype %d.\n", data->prefix.iptype);
+					is_downstream_set[data->prefix.iptype] = false;
+					store_downstream_state(false, data->prefix.iptype);
+					if (is_upstream_set[data->prefix.iptype] == true)
+					{
+						IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
+						if (data->prefix.iptype == IPA_IP_v4)
+						{
+							/* LTE STA */
+							handle_wan_down(IPACM_Wan::backhaul_mode);
+						} else {
+							handle_lan_client_reset_rt(IPA_IP_v6);
+
+							 /* LTE STA */
+							handle_wan_down_v6(IPACM_Wan::backhaul_mode);
+						}
+					}
+				}
+			}
+
 			if (data->prefix.iptype < IPA_IP_MAX && is_downstream_set[data->prefix.iptype] == false)
 			{
 				IPACMDBG_H("Add downstream for IP iptype %d\n", data->prefix.iptype);
@@ -829,18 +855,23 @@
 			IPACMDBG_H("Received IPA_DOWNSTREAM_DEL event.\n");
 			if (is_downstream_set[data->prefix.iptype] == true)
 			{
-				IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
-				is_downstream_set[data->prefix.iptype] = false;
-				store_downstream_state(false, data->prefix.iptype);
-				if (is_upstream_set[data->prefix.iptype] == true)
+				/* Handle downstream del event only when the prefix matches */
+				if (ipv6_prefix[0] == data->prefix.v6Addr[0] &&
+					ipv6_prefix[1] == data->prefix.v6Addr[1])
 				{
-					IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
-					if (data->prefix.iptype == IPA_IP_v4)
+					IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
+					is_downstream_set[data->prefix.iptype] = false;
+					store_downstream_state(false, data->prefix.iptype);
+					if (is_upstream_set[data->prefix.iptype] == true)
 					{
-						handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
-					} else {
-						handle_lan_client_reset_rt(IPA_IP_v6);
-						handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
+						IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
+						if (data->prefix.iptype == IPA_IP_v4)
+						{
+							handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
+						} else {
+							handle_lan_client_reset_rt(IPA_IP_v6);
+							handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
+						}
 					}
 				}
 			}
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 1e01e5e..1d9d0bc 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -1147,13 +1147,6 @@
 
 				if (is_global_ipv6_addr(data->ipv6_addr) && sec_num_dft_rt_v6 > 0)
 				{
-					if (active_v6)
-					{
-						post_wan_down_tether_evt(IPA_IP_v6, 0);
-						del_wan_firewall_rule(IPA_IP_v6);
-						handle_route_del_evt_ex(IPA_IP_v6);
-						wan_active = true;
-					}
 					/* Copy Secondary Address onto Primary. */
 					ipv6_addr[rt_idx][0] = sec_ipv6_addr[sec_num_dft_rt_v6-1][0];
 					ipv6_addr[rt_idx][1] = sec_ipv6_addr[sec_num_dft_rt_v6-1][1];
@@ -1163,10 +1156,6 @@
 					memset(sec_ipv6_addr[sec_num_dft_rt_v6-1], 0, sizeof(sec_ipv6_addr[sec_num_dft_rt_v6-1]));
 					sec_num_dft_rt_v6--;
 					IPACMDBG_H("Secondary v6 num %d: \n",sec_num_dft_rt_v6);
-					if (wan_active)
-					{
-						handle_route_add_evt(IPA_IP_v6);
-					}
 				}
 				else
 				{
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 58bbeee..c596256 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -562,6 +562,33 @@
 		if(ipa_interface_index == ipa_if_num)
 		{
 			IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n");
+
+			/* Delete any existing downstream before adding a new one*/
+			if(is_downstream_set[data->prefix.iptype] == true)
+			{
+				if (ipv6_prefix[0] != data->prefix.v6Addr[0] ||
+					ipv6_prefix[1] != data->prefix.v6Addr[1])
+				{
+					IPACMDBG_H("Del existing downstream for IP iptype %d.\n", data->prefix.iptype);
+					is_downstream_set[data->prefix.iptype] = false;
+					store_downstream_state(false, data->prefix.iptype);
+					if(is_upstream_set[data->prefix.iptype] == true)
+					{
+						IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
+						if (data->prefix.iptype == IPA_IP_v4)
+						{
+							/* LTE STA */
+							handle_wan_down(IPACM_Wan::backhaul_mode);
+						} else {
+							handle_wlan_client_reset_rt(IPA_IP_v6);
+
+							/* LTE STA */
+							handle_wan_down_v6(IPACM_Wan::backhaul_mode);
+						}
+					}
+				}
+			}
+
 			if(data->prefix.iptype < IPA_IP_MAX && is_downstream_set[data->prefix.iptype] == false)
 			{
 				IPACMDBG_H("Add downstream for IP iptype %d.\n", data->prefix.iptype);
@@ -615,18 +642,23 @@
 			IPACMDBG_H("Received IPA_DOWNSTREAM_DEL event.\n");
 			if(is_downstream_set[data->prefix.iptype] == true)
 			{
-				IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
-				is_downstream_set[data->prefix.iptype] = false;
-				store_downstream_state(false, data->prefix.iptype);
-				if(is_upstream_set[data->prefix.iptype] == true)
+				/* Handle downstream del event only when the prefix matches */
+				if (ipv6_prefix[0] == data->prefix.v6Addr[0] &&
+					ipv6_prefix[1] == data->prefix.v6Addr[1])
 				{
-					IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
-					if (data->prefix.iptype == IPA_IP_v4)
+					IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype);
+					is_downstream_set[data->prefix.iptype] = false;
+					store_downstream_state(false, data->prefix.iptype);
+					if(is_upstream_set[data->prefix.iptype] == true)
 					{
-						handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
-					} else {
-						handle_wlan_client_reset_rt(IPA_IP_v6);
-						handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
+						IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
+						if (data->prefix.iptype == IPA_IP_v4)
+						{
+							handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
+						} else {
+							handle_wlan_client_reset_rt(IPA_IP_v6);
+							handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
+						}
 					}
 				}
 			}