IPACM: Fix the nat iface missing when cfg change

In AP+AP mode swtich, IPACM_cfg.xml will be updated
on the fly when netdev interface already up while
IPACM loses the NAT ifaces in its config cache and
resulted in NAT-miss for all these pre-existing
netdev interfaces. Also we see more frequent NETBIOS_NS
embedded traffic on port 138 which exhausted our
nat cache. The fix is to add prot 138 traffic as ALG
port, also did the ALG port checking on NAT cache and
those existing ifaces will add itself to NAT ifaces
when receiving the cfg_change event.

Change-Id: I42921b29d70a345b20a71aaf35711c005849ef31
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index 69e2b41..24890ed 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -238,6 +238,7 @@
 		pNatIfaces = NULL;
 		IPACMDBG_H("RESET IPACM_Config::pNatIfaces \n");
 	}
+	ipa_nat_iface_entries = 0;
 	pNatIfaces = (NatIfaces *)calloc(ipa_num_ipa_interfaces, sizeof(NatIfaces));
 	if (pNatIfaces == NULL)
 	{
@@ -423,6 +424,19 @@
 
 int IPACM_Config::AddNatIfaces(char *dev_name)
 {
+	int i;
+	/* Check if this iface already in NAT-iface*/
+	for(i = 0; i < ipa_nat_iface_entries; i++)
+	{
+		if(strncmp(dev_name,
+							 pNatIfaces[i].iface_name,
+							 sizeof(pNatIfaces[i].iface_name)) == 0)
+		{
+			IPACMDBG("Interface (%s) is add to nat iface already\n", dev_name);
+				return 0;
+		}
+	}
+
 	IPACMDBG_H("Add iface %s to NAT-ifaces, origin it has %d nat ifaces\n",
 					          dev_name, ipa_nat_iface_entries);
 	ipa_nat_iface_entries++;
diff --git a/ipacm/src/IPACM_Conntrack_NATApp.cpp b/ipacm/src/IPACM_Conntrack_NATApp.cpp
index 4e7338e..348faa9 100644
--- a/ipacm/src/IPACM_Conntrack_NATApp.cpp
+++ b/ipacm/src/IPACM_Conntrack_NATApp.cpp
@@ -684,6 +684,13 @@
 	IPACMDBG("Private Port: %d\t Target Port: %d\t", new_entry->private_port, new_entry->target_port);
 	IPACMDBG("protocolcol: %d\n", new_entry->protocol);
 
+	if(isAlgPort(new_entry->protocol, new_entry->private_port) ||
+		 isAlgPort(new_entry->protocol, new_entry->target_port))
+	{
+		IPACMDBG("connection using ALG Port. Dont insert into nat cache\n");
+		return;
+	}
+
 	if(ChkForDup(new_entry))
 	{
 		return;
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 6e5f006..1d65a9f 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -347,6 +347,12 @@
 				is_mode_switch = true; // need post internal usb-link up event
 				return;
 			}
+			/* Add Natting iface to IPACM_Config if there is  Rx/Tx property */
+			if (rx_prop != NULL || tx_prop != NULL)
+			{
+				IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
+				IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name);
+			}
 		}
 		break;
 
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 38f4308..7de85a2 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -823,6 +823,13 @@
 				IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name,
 				(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == 0) ? "full" : "internet",
 				(is_guest_ap == true) ? "internet" : "full");
+		/* Add Natting iface to IPACM_Config if there is  Rx/Tx property */
+		if (rx_prop != NULL || tx_prop != NULL)
+		{
+			IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
+			IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name);
+		}
+
 		if (is_guest_ap == true && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == FULL))
 		{
 			is_guest_ap = false;
diff --git a/ipacm/src/IPACM_cfg.xml b/ipacm/src/IPACM_cfg.xml
index b4a236e..d16d2ed 100644
--- a/ipacm/src/IPACM_cfg.xml
+++ b/ipacm/src/IPACM_cfg.xml
@@ -140,6 +140,11 @@
 			   <Description>NETBIOS_NS</Description>
 		    </ALG>
 			<ALG>
+			   <Protocol>UDP</Protocol>
+			   <Port>138</Port>
+			   <Description>NETBIOS_NS</Description>
+		    </ALG>
+			<ALG>
   			   <Protocol>TCP</Protocol>
   			   <Port>6566</Port>
 			   <Description>SANE</Description>