Merge "msm: ipa: Compile ipacm for specific targets only"
diff --git a/ipacm/inc/IPACM_Conntrack_NATApp.h b/ipacm/inc/IPACM_Conntrack_NATApp.h
index 1fb12bf..836241a 100644
--- a/ipacm/inc/IPACM_Conntrack_NATApp.h
+++ b/ipacm/inc/IPACM_Conntrack_NATApp.h
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2013, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -52,7 +52,7 @@
 	uint32_t target_ip;
 	uint16_t target_port;
 
-	uint16_t public_ip;
+	uint32_t public_ip;
 	uint16_t public_port;
 
 	u_int8_t  protocol;
diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp
index 9e66a00..4ad0164 100644
--- a/ipacm/src/IPACM_ConntrackListener.cpp
+++ b/ipacm/src/IPACM_ConntrackListener.cpp
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2013, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -699,22 +699,20 @@
 			 return;
 		 }
 
-		 if(orig_src_ip == wan_ipaddr)
-		 {
-			 IPACMDBG("orig src ip:0x%x equal to wan ip\n",orig_src_ip);
-			 status = IPS_SRC_NAT;
-			 rule.public_ip = wan_ipaddr;
-		 }
-		 else if(orig_dst_ip == wan_ipaddr)
-		 {
-			 IPACMDBG("orig Dst IP:0x%x equal to wan ip\n",orig_dst_ip);
-			 status = IPS_DST_NAT;
-	 	 	 rule.public_ip = wan_ipaddr;
-		 }
-		 else
-		 {
-			 IPACMDBG("Neither orig src ip:0x%x Nor orig Dst IP:0x%x equal to wan ip:0x%x\n",
-						orig_src_ip, orig_dst_ip, wan_ipaddr);
+		if(orig_src_ip == wan_ipaddr)
+		{
+			IPACMDBG("orig src ip:0x%x equal to wan ip\n",orig_src_ip);
+			status = IPS_SRC_NAT;
+		}
+		else if(orig_dst_ip == wan_ipaddr)
+		{
+			IPACMDBG("orig Dst IP:0x%x equal to wan ip\n",orig_dst_ip);
+			status = IPS_DST_NAT;
+		}
+		else
+		{
+			IPACMDBG("Neither orig src ip:0x%x Nor orig Dst IP:0x%x equal to wan ip:0x%x\n",
+					orig_src_ip, orig_dst_ip, wan_ipaddr);
 
 #ifdef CT_OPT
 		if(p_lan2lan == NULL)
@@ -849,13 +847,13 @@
 			 }
 		 }
 
-		 if(cnt == MAX_NAT_IFACES)
-		 {
-			 IPACMDBG("Not mtaching with nat ifaces\n")
-			 if(pConfig == NULL)
-			 {
-				 goto IGNORE;
-			 }
+		if(cnt == MAX_NAT_IFACES)
+		{
+			IPACMDBG("Not mtaching with nat ifaces\n");
+			if(pConfig == NULL)
+			{
+				goto IGNORE;
+			}
 
 			 if(pConfig->isPrivateSubnet(rule.private_ip) ||
 						pConfig->isPrivateSubnet(rule.target_ip))
@@ -911,9 +909,9 @@
 		}
 	 }
 
-	 IPACMDBG("Not matching with STA Clnt Ip Addrs 0x%x\n",
-			 rule.target_ip);
-	 goto IGNORE;
+	IPACMDBG("Not matching with STA Clnt Ip Addrs 0x%x\n",
+		rule.target_ip);
+	isTempEntry = true;
 
 
 ADD:
@@ -925,12 +923,13 @@
 	 IPACMDBG("public port or reply dst port: 0x%x, Decimal:%d\n", rule.public_port, rule.public_port);
 	 IPACMDBG("Protocol: %d, destination nat flag: %d\n", rule.protocol, rule.dst_nat);
 
-	 if(IPPROTO_TCP == rule.protocol)
-	 {
-			if(nat_inst == NULL)
-			{
-				return;
-			}
+	rule.public_ip = wan_ipaddr;
+	if(IPPROTO_TCP == rule.protocol)
+	{
+		if(nat_inst == NULL)
+		{
+			return;
+		}
 
 			tcp_state = nfct_get_attr_u8(ct, ATTR_TCP_STATE);
 			if(TCP_CONNTRACK_ESTABLISHED == tcp_state)
@@ -1059,6 +1058,7 @@
 
 	 }
 
+	 nat_inst->FlushTempEntries(clnt_ip_addr, true);
 	 return;
 }
 
@@ -1082,5 +1082,6 @@
 		}
 	 }
 
-  return;
+	 nat_inst->FlushTempEntries(clnt_ip_addr, false);
+   return;
 }
diff --git a/ipacm/src/IPACM_Conntrack_NATApp.cpp b/ipacm/src/IPACM_Conntrack_NATApp.cpp
index 0915fda..bf0daac 100644
--- a/ipacm/src/IPACM_Conntrack_NATApp.cpp
+++ b/ipacm/src/IPACM_Conntrack_NATApp.cpp
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2013, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -573,7 +573,6 @@
 		}
 	}
 
-
 	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
 	{
 		if(PwrSaveIfs[cnt] == 0)
@@ -772,7 +771,7 @@
 
 int NatApp::DelEntriesOnClntDiscon(uint32_t ip_addr)
 {
- 	int cnt, tmp = curCnt;
+	int cnt, tmp = 0;
 	IPACMDBG("Received IP address: 0x%x\n", ip_addr);
 
 	if(ip_addr == INVALID_IP_ADDR)
@@ -781,39 +780,40 @@
 		return -1;
 	}
 
-
-  for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
-  {
-    if(PwrSaveIfs[cnt] == ip_addr)
-    {
-      PwrSaveIfs[cnt] = 0;
-      IPACMDBG("Remove %d power save entry\n", cnt);
-      break;
-    }
-  }
-
-  for(cnt = 0; cnt < max_entries; cnt++)
-  {
-	if(cache[cnt].private_ip == ip_addr)
+	for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
 	{
-		if(cache[cnt].enabled == true)
-      		{
-			if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
-			{
-				IPACMERR("unable to delete the rule\n");
-				continue;
-			}
-			else
-			{
-				IPACMDBG("won't delete the rule\n");
-				cache[cnt].enabled = false;
-		        }
-	        }
-		IPACMDBG("won't delete the rule for entry %d, enabled %d\n",cnt, cache[cnt].enabled);
+		if(PwrSaveIfs[cnt] == ip_addr)
+		{
+			PwrSaveIfs[cnt] = 0;
+			IPACMDBG("Remove %d power save entry\n", cnt);
+			break;
+		}
 	}
-  }
-  IPACMDBG("Deleted %d entries\n", (tmp - curCnt));
-  return 0;
+
+	for(cnt = 0; cnt < max_entries; cnt++)
+	{
+		if(cache[cnt].private_ip == ip_addr)
+		{
+			if(cache[cnt].enabled == true)
+			{
+				if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
+				{
+					IPACMERR("unable to delete the rule\n");
+					continue;
+				}
+				else
+				{
+					IPACMDBG("won't delete the rule\n");
+					cache[cnt].enabled = false;
+					tmp++;
+				}
+			}
+			IPACMDBG("won't delete the rule for entry %d, enabled %d\n",cnt, cache[cnt].enabled);
+		}
+	}
+
+	IPACMDBG("Deleted (but cached) %d entries\n", tmp);
+	return 0;
 }
 
 int NatApp::DelEntriesOnSTAClntDiscon(uint32_t ip_addr)
@@ -827,7 +827,6 @@
 		return -1;
 	}
 
-
 	for(cnt = 0; cnt < max_entries; cnt++)
 	{
 		if(cache[cnt].target_ip == ip_addr)
@@ -893,6 +892,7 @@
 			cache[cnt].protocol = rule->protocol;
 			cache[cnt].timestamp = 0;
 			cache[cnt].public_port = rule->public_port;
+			cache[cnt].public_ip = rule->public_ip;
 			cache[cnt].dst_nat = rule->dst_nat;
 			curCnt++;
 		}
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index fa8c1a1..823879b 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -437,20 +437,20 @@
 						|| ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES)))
 					{
 						IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
+						if(handle_addr_evt(data) == IPACM_FAILURE)
+						{
+							return;
+						}
 						/* ADD ipv4 icmp rule */
 						if (data->iptype == IPA_IP_v4)
 						{
 							install_ipv4_icmp_flt_rule();
 						}
 						/* ADD ipv6 icmp rule */
-						if ((num_dft_rt_v6 == 0) && (data->iptype == IPA_IP_v6))
+						if ((num_dft_rt_v6 == 1) && (data->iptype == IPA_IP_v6))
 						{
 							install_ipv6_icmp_flt_rule();
 						}
-						if(handle_addr_evt(data) == IPACM_FAILURE)
-						{
-							return;
-						}
 						handle_private_subnet(data->iptype);
 
 						if (IPACM_Wan::isWanUP())
@@ -2878,7 +2878,7 @@
 			flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0;
 			flt_rule_entry.rule.eq_attrib.metadata_meq32.value = (value & 0xFF) << 16;
 			flt_rule_entry.rule.eq_attrib.metadata_meq32.mask = 0x00FF0000;
-			IPACMDBG_H("xlat meta-data is modified fur rult: %d has index %d with xlat_mux_id: %d\n",
+			IPACMDBG_H("xlat meta-data is modified for rule: %d has index %d with xlat_mux_id: %d\n",
 					cnt, index, xlat_mux_id);
 		}
 		memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry));
@@ -4168,7 +4168,7 @@
 		flt_rule_entry.rule.retain_hdr = 1;
 		flt_rule_entry.rule.to_uc = 0;
 		flt_rule_entry.rule.eq_attrib_type = 0;
-		flt_rule_entry.at_rear = false;
+		flt_rule_entry.at_rear = true;
 		flt_rule_entry.flt_rule_hdl = -1;
 		flt_rule_entry.status = -1;
 		flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
@@ -4569,7 +4569,7 @@
 		flt_rule_entry.rule.retain_hdr = 1;
 		flt_rule_entry.rule.to_uc = 0;
 		flt_rule_entry.rule.eq_attrib_type = 0;
-		flt_rule_entry.at_rear = false;
+		flt_rule_entry.at_rear = true;
 		flt_rule_entry.flt_rule_hdl = -1;
 		flt_rule_entry.status = -1;
 		flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index cc80847..e5cc958 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -876,6 +876,14 @@
 						del_wan_firewall_rule(IPA_IP_v4);
 						install_wan_filtering_rule(false);
 						handle_route_del_evt_ex(IPA_IP_v4);
+
+						if(is_xlat && active_v6 == true)
+						{
+							IPACMDBG_H("XLAT enabled: Delete IPv6 routing table dev (%s)\n", dev_name);
+							del_wan_firewall_rule(IPA_IP_v6);
+							install_wan_filtering_rule(false);
+							handle_route_del_evt_ex(IPA_IP_v6);
+						}
 					}
 					else
 					{
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index ef58227..fa3b6af 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -320,17 +320,17 @@
 										 info->ipv4_addr, info->addr_mask);
 						IPACM_EvtDispatcher::PostEvt(&evt_data);
 					}
+					if(handle_addr_evt(data) == IPACM_FAILURE)
+					{
+						return;
+					}
 					if ((data->iptype == IPA_IP_v4) && (wlan_ap_index == 0))
 					{
 						IPACM_Lan::install_ipv4_icmp_flt_rule();
 					}
-					if ((num_dft_rt_v6 == 0) && (data->iptype == IPA_IP_v6) && (wlan_ap_index == 0))
+					if ((num_dft_rt_v6 == 1) && (data->iptype == IPA_IP_v6) && (wlan_ap_index == 0))
 					{
-							install_ipv6_icmp_flt_rule();
-					}
-					if(handle_addr_evt(data) == IPACM_FAILURE)
-					{
-						return;
+						install_ipv6_icmp_flt_rule();
 					}
 
 #ifdef FEATURE_IPA_ANDROID