Merge "ipacm: Fix race condition between nat delete rule and update timestamp"
diff --git a/ipacm/src/Android.mk b/ipacm/src/Android.mk
index 9a4d659..2e3e96f 100644
--- a/ipacm/src/Android.mk
+++ b/ipacm/src/Android.mk
@@ -31,7 +31,7 @@
 LOCAL_CFLAGS += -DDEBUG
 endif
 
-ifeq ($(TARGET_BOARD_PLATFORM),msmcobalt)
+ifeq ($(TARGET_BOARD_PLATFORM),msm8998)
 LOCAL_CFLAGS += -DFEATURE_IPA_V3
 endif
 
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index eb30e0f..4b02b57 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -474,7 +474,7 @@
 
 	if (ipa_nat_iface_entries < ipa_num_ipa_interfaces)
 	{
-		memcpy(pNatIfaces[ipa_nat_iface_entries - 1].iface_name,
+		strlcpy(pNatIfaces[ipa_nat_iface_entries - 1].iface_name,
 					 dev_name, IPA_IFACE_NAME_LEN);
 
 		IPACMDBG_H("Add Nat IfaceName: %s ,update nat-ifaces number: %d\n",
diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp
index 38ab7da..ad3fa1e 100644
--- a/ipacm/src/IPACM_ConntrackListener.cpp
+++ b/ipacm/src/IPACM_ConntrackListener.cpp
@@ -96,10 +96,7 @@
 	 case IPA_HANDLE_WAN_UP:
 			IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
 			CreateConnTrackThreads();
-			if(!isWanUp())
-			{
-				TriggerWANUp(data);
-			}
+			TriggerWANUp(data);
 			break;
 
 	 case IPA_HANDLE_WAN_DOWN:
@@ -213,8 +210,8 @@
 					sizeof(pNatIfaces[i].iface_name)) == 0)
 		{
 			IPACMDBG_H("Nat iface (%s), entry (%d), dont cache",
-						pNatIfaces[i].iface_name, j);
-			iptodot("with ipv4 address: ", nat_iface_ipv4_addr[j]);
+						pNatIfaces[i].iface_name, i);
+			iptodot("with ipv4 address: ", nat_iface_ipv4_addr[i]);
 			*NatIface = true;
 			return IPACM_SUCCESS;
 		}
@@ -356,6 +353,14 @@
 		 return;
 	 }
 
+	 if(isWanUp())
+	 {
+		 if (wan_ipaddr != wanup_data->ipv4_addr)
+			 TriggerWANDown(wan_ipaddr);
+		 else
+			 return;
+	 }
+
 	 WanUp = true;
 	 isStaMode = wanup_data->is_sta;
 	 IPACMDBG("isStaMode: %d\n", isStaMode);
@@ -455,16 +460,20 @@
 
 void IPACM_ConntrackListener::TriggerWANDown(uint32_t wan_addr)
 {
-	 IPACMDBG_H("Deleting ipv4 nat table with");
-	 IPACMDBG_H(" public ip address(0x%x): %d.%d.%d.%d\n", wan_addr,
-		    ((wan_addr>>24) & 0xFF), ((wan_addr>>16) & 0xFF), 
-		    ((wan_addr>>8) & 0xFF), (wan_addr & 0xFF));
-	 
-	 WanUp = false;
+	int ret = 0;
+	IPACMDBG_H("Deleting ipv4 nat table with");
+	IPACMDBG_H(" public ip address(0x%x): %d.%d.%d.%d\n", wan_addr,
+			((wan_addr>>24) & 0xFF), ((wan_addr>>16) & 0xFF),
+			((wan_addr>>8) & 0xFF), (wan_addr & 0xFF));
 
 	 if(nat_inst != NULL)
 	 {
-		 nat_inst->DeleteTable(wan_addr);
+		 ret = nat_inst->DeleteTable(wan_addr);
+		 if (ret)
+			 return;
+
+		 WanUp = false;
+		 wan_ipaddr = 0;
 	 }
 }
 
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index a119746..1727eaf 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -74,6 +74,17 @@
 		return;
 	}
 
+	num_wan_ul_fl_rule_v4 = 0;
+	num_wan_ul_fl_rule_v6 = 0;
+	is_active = true;
+	modem_ul_v4_set = false;
+	modem_ul_v6_set = false;
+	is_mode_switch = false;
+	if_ipv4_subnet =0;
+	each_client_rt_rule_count[IPA_IP_v4] = 0;
+	each_client_rt_rule_count[IPA_IP_v6] = 0;
+	eth_client_len = 0;
+
 	/* support eth multiple clients */
 	if(iface_query != NULL)
 	{
@@ -104,22 +115,14 @@
 		}
 	}
 
-	num_wan_ul_fl_rule_v4 = 0;
-	num_wan_ul_fl_rule_v6 = 0;
-
 	memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
 	memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t));
 
-	is_active = true;
 	memset(ipv4_icmp_flt_rule_hdl, 0, NUM_IPV4_ICMP_FLT_RULE * sizeof(uint32_t));
 
-	is_mode_switch = false;
-	if_ipv4_subnet =0;
 	memset(private_fl_rule_hdl, 0, IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(uint32_t));
 	memset(ipv6_prefix_flt_rule_hdl, 0, NUM_IPV6_PREFIX_FLT_RULE * sizeof(uint32_t));
 	memset(ipv6_icmp_flt_rule_hdl, 0, NUM_IPV6_ICMP_FLT_RULE * sizeof(uint32_t));
-	modem_ul_v4_set = false;
-	modem_ul_v6_set = false;
 	memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
 
 	/* ODU routing table initilization */
@@ -157,8 +160,6 @@
 		}
 	}
 
-	each_client_rt_rule_count[IPA_IP_v4] = 0;
-	each_client_rt_rule_count[IPA_IP_v6] = 0;
 	if(iface_query != NULL && tx_prop != NULL)
 	{
 		for(i=0; i<iface_query->num_tx_props; i++)
@@ -1885,7 +1886,7 @@
 				rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(eth_client, eth_index)->v4_addr;
 				rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
 #ifdef FEATURE_IPA_V3
-				rt_rule_entry->rule.hashable = true;
+				rt_rule_entry->rule.hashable = false;
 #endif
 			    if (false == m_routing.AddRoutingRule(rt_rule))
   	            {
diff --git a/ipacm/src/IPACM_Neighbor.cpp b/ipacm/src/IPACM_Neighbor.cpp
index 5a72c4c..b96cebb 100644
--- a/ipacm/src/IPACM_Neighbor.cpp
+++ b/ipacm/src/IPACM_Neighbor.cpp
@@ -76,7 +76,7 @@
 				IPACMERR("IPA_WLAN_CLIENT_ADD_EVENT_EX: not supported iface id: %d\n", data->if_index);
 				break;
 			}
-			uint8_t client_mac_addr[6];
+			uint8_t client_mac_addr[6] = {0};
 
 			IPACMDBG_H("Received IPA_WLAN_CLIENT_ADD_EVENT\n");
 			for(i = 0; i < data->num_of_attribs; i++)
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 4ee6c10..921ddd6 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -129,6 +129,9 @@
 	is_xlat = false;
 	hdr_hdl_dummy_v6 = 0;
 	hdr_proc_hdl_dummy_v6 = 0;
+	is_default_gateway = false;
+	m_fd_ipa = 0;
+	wan_client_len = 0;
 
 	if(iface_query != NULL)
 	{
@@ -711,6 +714,13 @@
 		{
 			ipacm_event_data_iptype *data = (ipacm_event_data_iptype *)param;
 			ipa_interface_index = iface_ipa_index_query(data->if_index);
+			/* add the check see if tether_iface is valid or not */
+			if (iface_ipa_index_query(data->if_index_tether) == INVALID_IFACE)
+			{
+				IPACMERR("UPSTREAM_ROUTE_ADD tether_if(%d), not valid ignore\n", INVALID_IFACE);
+				return;
+			}
+
 			if (ipa_interface_index == ipa_if_num)
 			{
 				IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT (Android) for ip-type (%d)\n", data->iptype);
@@ -808,6 +818,13 @@
 		{
 			ipacm_event_data_iptype *data = (ipacm_event_data_iptype *)param;
 			ipa_interface_index = iface_ipa_index_query(data->if_index);
+			/* add the check see if tether_iface is valid or not */
+			if (iface_ipa_index_query(data->if_index_tether) == INVALID_IFACE)
+			{
+				IPACMERR("UPSTREAM_ROUTE_DEL tether_if(%d), not valid ignore\n", INVALID_IFACE);
+				return;
+			}
+
 			if (ipa_interface_index == ipa_if_num)
 			{
 				IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT\n");
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index c067550..2152c4d 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -83,6 +83,7 @@
 	num_wifi_client = 0;
 	header_name_count = 0;
 	wlan_client = NULL;
+	wlan_client_len = 0;
 
 	if(iface_query != NULL)
 	{
@@ -1259,7 +1260,7 @@
 				rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wlan_client, wlan_index)->v4_addr;
 				rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
 #ifdef FEATURE_IPA_V3
-				rt_rule_entry->rule.hashable = true;
+				rt_rule_entry->rule.hashable = false;
 #endif
 				if (false == m_routing.AddRoutingRule(rt_rule))
 				{
diff --git a/ipacm/src/IPACM_Xml.cpp b/ipacm/src/IPACM_Xml.cpp
index 073dc98..6b19639 100644
--- a/ipacm/src/IPACM_Xml.cpp
+++ b/ipacm/src/IPACM_Xml.cpp
@@ -268,7 +268,7 @@
 						str_size = strlen(content);
 						memset(content_buf, 0, sizeof(content_buf));
 						memcpy(content_buf, (void *)content, str_size);
-						strlcpy(config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].iface_name, content_buf, str_size+1);
+						strlcpy(config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].iface_name, content_buf, IPA_IFACE_NAME_LEN);
 						IPACMDBG_H("Name %s\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].iface_name);
 					}
 				}