IPACM: Add support for non IPA data path

Add dummy nat rules to avoid exception
for DL packets that takes non IPA HW data
path.

Change-Id: I008f90a9fea9e9bcff3f4adcdc499c7f897af963
Acked-by: Sunil Paidimarri <hisunil@qti.qualcomm.com>
CRs-Fixed: 946920
diff --git a/ipacm/inc/IPACM_ConntrackListener.h b/ipacm/inc/IPACM_ConntrackListener.h
index db83598..cdf3ef5 100644
--- a/ipacm/inc/IPACM_ConntrackListener.h
+++ b/ipacm/inc/IPACM_ConntrackListener.h
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2013, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2016, 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
@@ -46,11 +46,21 @@
 #include "IPACM_LanToLan.h"
 #endif
 
-#define MAX_NAT_IFACES 50
+#define MAX_IFACE_ADDRESS 50
 #define MAX_STA_CLNT_IFACES 10
+#define STA_CLNT_SUBNET_MASK 0xFFFFFF00
 
 using namespace std;
 
+typedef struct _nat_entry_bundle
+{
+	struct nf_conntrack *ct;
+	enum nf_conntrack_msg_type type;
+	nat_table_entry *rule;
+	bool isTempEntry;
+
+}nat_entry_bundle;
+
 class IPACM_ConntrackListener : public IPACM_Listener
 {
 
@@ -63,8 +73,8 @@
 	int NatIfaceCnt;
 	int StaClntCnt;
 	NatIfaces *pNatIfaces;
-	uint32_t nat_iface_ipv4_addr[MAX_NAT_IFACES];
-	uint32_t nonnat_iface_ipv4_addr[MAX_NAT_IFACES];
+	uint32_t nat_iface_ipv4_addr[MAX_IFACE_ADDRESS];
+	uint32_t nonnat_iface_ipv4_addr[MAX_IFACE_ADDRESS];
 	uint32_t sta_clnt_ipv4_addr[MAX_STA_CLNT_IFACES];
 	IPACM_Config *pConfig;
 #ifdef CT_OPT
@@ -78,9 +88,17 @@
 	void TriggerWANDown(uint32_t);
 	int  CreateNatThreads(void);
 	int  CreateConnTrackThreads(void);
+	bool AddIface(nat_table_entry *, bool *);
+	void AddORDeleteNatEntry(const nat_entry_bundle *);
+	void PopulateTCPorUDPEntry(struct nf_conntrack *, uint32_t, nat_table_entry *);
+	void CheckSTAClient(const nat_table_entry *, bool *);
+	int CheckNatIface(ipacm_event_data_all *, bool *);
+	void HandleNonNatIPAddr(void *, bool);
 
 #ifdef CT_OPT
 	void ProcessCTV6Message(void *);
+	void HandleLan2Lan(struct nf_conntrack *,
+		enum nf_conntrack_msg_type, nat_table_entry* );
 #endif
 
 public:
diff --git a/ipacm/inc/IPACM_Conntrack_NATApp.h b/ipacm/inc/IPACM_Conntrack_NATApp.h
index e6c27af..e50b316 100644
--- a/ipacm/inc/IPACM_Conntrack_NATApp.h
+++ b/ipacm/inc/IPACM_Conntrack_NATApp.h
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2016, 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
@@ -125,7 +125,7 @@
 	void AddTempEntry(const nat_table_entry *);
 	void CacheEntry(const nat_table_entry *);
 	void DeleteTempEntry(const nat_table_entry *);
-	void FlushTempEntries(uint32_t, bool);
+	void FlushTempEntries(uint32_t, bool, bool isDummy = false);
 };
 
 
diff --git a/ipacm/src/IPACM_ConntrackClient.cpp b/ipacm/src/IPACM_ConntrackClient.cpp
index 2a670c8..146cedb 100644
--- a/ipacm/src/IPACM_ConntrackClient.cpp
+++ b/ipacm/src/IPACM_ConntrackClient.cpp
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2013, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2016, 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
@@ -524,9 +524,9 @@
 	/* Register callback with netfilter handler */
 	IPACMDBG_H("udp handle:%p, fd:%d\n", pClient->udp_hdl, nfct_fd(pClient->udp_hdl));
 	nfct_callback_register(pClient->udp_hdl,
-												 (nf_conntrack_msg_type)(NFCT_T_NEW | NFCT_T_DESTROY),
-												 IPAConntrackEventCB,
-												 NULL);
+			(nf_conntrack_msg_type)(NFCT_T_NEW | NFCT_T_DESTROY),
+			IPAConntrackEventCB,
+			NULL);
 
 	/* Block to catch events from net filter connection track */
 ctcatch:
diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp
index ab25bde..33023cb 100644
--- a/ipacm/src/IPACM_ConntrackListener.cpp
+++ b/ipacm/src/IPACM_ConntrackListener.cpp
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2016, 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
@@ -46,7 +46,7 @@
 	 NatIfaceCnt = 0;
 	 StaClntCnt = 0;
 	 pNatIfaces = NULL;
-	 pConfig = NULL;
+	 pConfig = IPACM_Config::GetInstance();;
 
 	 memset(nat_iface_ipv4_addr, 0, sizeof(nat_iface_ipv4_addr));
 	 memset(nonnat_iface_ipv4_addr, 0, sizeof(nonnat_iface_ipv4_addr));
@@ -58,6 +58,8 @@
 	 IPACM_EvtDispatcher::registr(IPA_PROCESS_CT_MESSAGE_V6, this);
 	 IPACM_EvtDispatcher::registr(IPA_HANDLE_WLAN_UP, this);
 	 IPACM_EvtDispatcher::registr(IPA_HANDLE_LAN_UP, this);
+	 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, this);
+	 IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, this);
 
 #ifdef CT_OPT
 	 p_lan2lan = IPACM_LanToLan::getLan2LanInstance();
@@ -65,7 +67,7 @@
 }
 
 void IPACM_ConntrackListener::event_callback(ipa_cm_event_id evt,
-																						 void *data)
+						void *data)
 {
 	 ipacm_event_iface_up *wan_down = NULL;
 
@@ -119,168 +121,232 @@
 			IPACM_ConntrackClient::UpdateTCPFilters(data, false);
 			break;
 
+	 case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
+		 IPACMDBG("Received IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT event\n");
+		 HandleNonNatIPAddr(data, true);
+		 break;
+
+	 case IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT:
+		 IPACMDBG("Received IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT event\n");
+		 HandleNonNatIPAddr(data, false);
+		 break;
+
 	 default:
 			IPACMDBG("Ignore cmd %d\n", evt);
 			break;
 	 }
 }
-void IPACM_ConntrackListener::HandleNeighIpAddrAddEvt(ipacm_event_data_all *data)
+
+int IPACM_ConntrackListener::CheckNatIface(
+   ipacm_event_data_all *data, bool *NatIface)
 {
 	int fd = 0, len = 0, cnt, i, j;
 	struct ifreq ifr;
-	bool isNatIface = false;
+	*NatIface = false;
 
-	if(data->ipv4_addr == 0 || data->iptype != IPA_IP_v4)
+	if (data->ipv4_addr == 0 || data->iptype != IPA_IP_v4)
 	{
-		IPACMDBG("Ignoring IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT EVENT\n");
-		return;
+		IPACMDBG("Ignoring\n");
+		return IPACM_FAILURE;
 	}
 
-	IPACMDBG("\n");
 	IPACMDBG("Received interface index %d with ip type: %d", data->if_index, data->iptype);
 	iptodot(" and ipv4 address", data->ipv4_addr);
 
-	if(pConfig == NULL)
+	if (pConfig == NULL)
 	{
 		pConfig = IPACM_Config::GetInstance();
-		if(pConfig == NULL)
+		if (pConfig == NULL)
 		{
 			IPACMERR("Unable to get Config instance\n");
-			return;
+			return IPACM_FAILURE;
 		}
 	}
 
-
 	cnt = pConfig->GetNatIfacesCnt();
 	NatIfaceCnt = cnt;
-	if (pNatIfaces != NULL) {
+	IPACMDBG("Total Nat ifaces: %d\n", NatIfaceCnt);
+	if (pNatIfaces != NULL)
+	{
 		free(pNatIfaces);
 		pNatIfaces = NULL;
 	}
 
 	len = (sizeof(NatIfaces) * NatIfaceCnt);
 	pNatIfaces = (NatIfaces *)malloc(len);
-	if (pNatIfaces == NULL) {
+	if (pNatIfaces == NULL)
+	{
 		IPACMERR("Unable to allocate memory for non nat ifaces\n");
-		return;
+		return IPACM_FAILURE;
 	}
+
 	memset(pNatIfaces, 0, len);
-
-	if (pConfig->GetNatIfaces(NatIfaceCnt, pNatIfaces) != 0) {
+	if (pConfig->GetNatIfaces(NatIfaceCnt, pNatIfaces) != 0)
+	{
 		IPACMERR("Unable to retrieve non nat ifaces\n");
-		return;
+		return IPACM_FAILURE;
 	}
-	IPACMDBG("Update %d Nat ifaces\n", NatIfaceCnt); 
-
 
 	/* Search/Configure linux interface-index and map it to IPA interface-index */
-	if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
 	{
 		PERROR("get interface name socket create failed");
-		return;
+		return IPACM_FAILURE;
 	}
 
 	memset(&ifr, 0, sizeof(struct ifreq));
 	ifr.ifr_ifindex = data->if_index;
-
-	if(ioctl(fd, SIOCGIFNAME, &ifr) < 0)
+	if (ioctl(fd, SIOCGIFNAME, &ifr) < 0)
 	{
 		PERROR("call_ioctl_on_dev: ioctl failed:");
 		close(fd);
-		return;
+		return IPACM_FAILURE;
 	}
 	close(fd);
 
-	for(i = 0; i < NatIfaceCnt; i++)
+	for (i = 0; i < NatIfaceCnt; i++)
 	{
-		if(strncmp(ifr.ifr_name,
-							 pNatIfaces[i].iface_name,
-							 sizeof(pNatIfaces[i].iface_name)) == 0)
+		if (strncmp(ifr.ifr_name,
+					pNatIfaces[i].iface_name,
+					sizeof(pNatIfaces[i].iface_name)) == 0)
 		{
 			/* copy the ipv4 address to filter out downlink connections
 				 ignore downlink after listening connection event from
 				 conntrack as it is not destinated to private ip address */
 			IPACMDBG("Interface (%s) is nat\n", ifr.ifr_name);
-			for(j = 0; j < MAX_NAT_IFACES; j++)
+			for (j = 0; j < MAX_IFACE_ADDRESS; j++)
 			{
 				/* check if duplicate NAT ip */
-				if(nat_iface_ipv4_addr[j] == data->ipv4_addr)
-					break;
+				if (nat_iface_ipv4_addr[j] == data->ipv4_addr)
+				{
+					*NatIface = true;
+					return IPACM_SUCCESS;
+				}
 
-				if(nat_iface_ipv4_addr[j] == 0)
+				if (nat_iface_ipv4_addr[j] == 0)
 				{
 					nat_iface_ipv4_addr[j] = data->ipv4_addr;
-					nat_inst->ResetPwrSaveIf(data->ipv4_addr);
-					nat_inst->FlushTempEntries(data->ipv4_addr, true);
-					break;
+					IPACMDBG_H("Nating connections of Interface (%s), entry (%d) ",
+						pNatIfaces[i].iface_name, j);
+					iptodot("with ipv4 address: ", nat_iface_ipv4_addr[j]);
+
+					*NatIface = true;
+					return IPACM_SUCCESS;
 				}
 			}
-
-			if(j == MAX_NAT_IFACES)
-			{
-				IPACMERR("Nat ifaces(%d) exceed maximum\n", j);
-				break;
-			}
-
-
-			isNatIface = true;
-			IPACMDBG_H("Nating connections of Interface (%s), entry (%d) ", pNatIfaces[i].iface_name, j);
-			IPACMDBG_H(" with ipv4 address(0x%x): %d.%d.%d.%d\n", nat_iface_ipv4_addr[j],
-					    ((nat_iface_ipv4_addr[j]>>24) & 0xFF), ((nat_iface_ipv4_addr[j]>>16) & 0xFF), 
-					    ((nat_iface_ipv4_addr[j]>>8) & 0xFF), (nat_iface_ipv4_addr[j] & 0xFF));
-			break;
 		}
 	}
 
-	/* Cache the non nat iface ip address */
-	if(isNatIface != true)
-	{
-		for(i = 0; i < MAX_NAT_IFACES; i++)
-		{
-			if(nonnat_iface_ipv4_addr[i] == 0)
-			{
-				nonnat_iface_ipv4_addr[i] = data->ipv4_addr;
-				nat_inst->FlushTempEntries(data->ipv4_addr, false);
-				break;
-			}
-		}
-	}
-
+	return IPACM_SUCCESS;
 }
 
-void IPACM_ConntrackListener::HandleNeighIpAddrDelEvt(uint32_t ipv4_addr)
+void IPACM_ConntrackListener::HandleNonNatIPAddr(
+   void *inParam, bool AddOp)
+{
+	ipacm_event_data_all *data = (ipacm_event_data_all *)inParam;
+	bool NatIface = false;
+	int cnt, ret;
+
+	/* Handle only non nat ifaces, NAT iface should be handle
+	   separately to avoid race conditions between route/nat
+	   rules add/delete operations */
+	if (AddOp)
+	{
+		ret = CheckNatIface(data, &NatIface);
+		if (!NatIface && ret == IPACM_SUCCESS)
+		{
+			/* Cache the non nat iface ip address */
+			for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++)
+			{
+				if (nonnat_iface_ipv4_addr[cnt] == 0)
+				{
+					nonnat_iface_ipv4_addr[cnt] = data->ipv4_addr;
+					/* Add dummy nat rule for non nat ifaces */
+					nat_inst->FlushTempEntries(data->ipv4_addr, true, true);
+					return;
+				}
+			}
+		}
+	}
+	else
+	{
+		/* for delete operation */
+		for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++)
+		{
+			if (nonnat_iface_ipv4_addr[cnt] == data->ipv4_addr)
+			{
+				IPACMDBG("Reseting ct filters, entry (%d) ", cnt);
+				iptodot("with ipv4 address", nonnat_iface_ipv4_addr[cnt]);
+				nonnat_iface_ipv4_addr[cnt] = 0;
+				nat_inst->FlushTempEntries(data->ipv4_addr, false);
+				nat_inst->DelEntriesOnClntDiscon(data->ipv4_addr);
+				return;
+			}
+		}
+
+	}
+
+	return;
+}
+
+void IPACM_ConntrackListener::HandleNeighIpAddrAddEvt(
+   ipacm_event_data_all *data)
+{
+	bool NatIface = false;
+	int j, ret;
+
+	ret = CheckNatIface(data, &NatIface);
+	if (NatIface && ret == IPACM_SUCCESS)
+	{
+		for (j = 0; j < MAX_IFACE_ADDRESS; j++)
+		{
+			/* check if duplicate NAT ip */
+			if (nat_iface_ipv4_addr[j] == data->ipv4_addr)
+				break;
+
+			/* Cache the new nat iface address */
+			if (nat_iface_ipv4_addr[j] == 0)
+			{
+				nat_iface_ipv4_addr[j] = data->ipv4_addr;
+				iptodot("Nating connections of addr: ", nat_iface_ipv4_addr[j]);
+				break;
+			}
+		}
+
+		/* Add the cached temp entries to NAT table */
+		if (j != MAX_IFACE_ADDRESS)
+		{
+			nat_inst->ResetPwrSaveIf(data->ipv4_addr);
+			nat_inst->FlushTempEntries(data->ipv4_addr, true);
+		}
+	}
+	return;
+}
+
+void IPACM_ConntrackListener::HandleNeighIpAddrDelEvt(
+   uint32_t ipv4_addr)
 {
 	int cnt;
 
 	if(ipv4_addr == 0)
 	{
-		IPACMDBG("Ignoring IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT EVENT\n");
+		IPACMDBG("Ignoring\n");
 		return;
 	}
 
-  IPACMDBG("\n");
-  iptodot("Received ip addr", ipv4_addr);
-	IPACMDBG("Entering NAT entry deletion checking\n");
-
-	for(cnt = 0; cnt<MAX_NAT_IFACES; cnt++)
+	iptodot("HandleNeighIpAddrDelEvt(): Received ip addr", ipv4_addr);
+	for(cnt = 0; cnt<MAX_IFACE_ADDRESS; cnt++)
 	{
-		if(nat_iface_ipv4_addr[cnt] == ipv4_addr)
+		if (nat_iface_ipv4_addr[cnt] == ipv4_addr)
 		{
 			IPACMDBG("Reseting ct nat iface, entry (%d) ", cnt);
 			iptodot("with ipv4 address", nat_iface_ipv4_addr[cnt]);
 			nat_iface_ipv4_addr[cnt] = 0;
-		}
-
-		if(nonnat_iface_ipv4_addr[cnt] == ipv4_addr)
-		{
-			IPACMDBG("Reseting ct filters, entry (%d) ", cnt);
-			iptodot("with ipv4 address", nonnat_iface_ipv4_addr[cnt]);
-			nonnat_iface_ipv4_addr[cnt] = 0;
+			nat_inst->FlushTempEntries(ipv4_addr, false);
+			nat_inst->DelEntriesOnClntDiscon(ipv4_addr);
 		}
 	}
 
-	nat_inst->FlushTempEntries(ipv4_addr, false);
-	nat_inst->DelEntriesOnClntDiscon(ipv4_addr);
 	return;
 }
 
@@ -467,7 +533,7 @@
 
 void ParseCTV6Message(struct nf_conntrack *ct)
 {
-	 uint32_t status, timeout, secmark;
+	 uint32_t status, timeout;
 	 struct nfct_attr_grp_ipv6 orig_params;
 	 uint8_t l4proto, tcp_flags, tcp_state;
 
@@ -628,6 +694,320 @@
 	 return;
 }
 
+bool IPACM_ConntrackListener::AddIface(
+   nat_table_entry *rule, bool *isTempEntry)
+{
+	int cnt;
+
+	*isTempEntry = false;
+	/* check whether nat iface or not */
+	for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++)
+	{
+		if (nat_iface_ipv4_addr[cnt] != 0)
+		{
+			if (rule->private_ip == nat_iface_ipv4_addr[cnt] ||
+				rule->target_ip == nat_iface_ipv4_addr[cnt])
+			{
+				IPACMDBG("matched nat_iface_ipv4_addr entry(%d)\n", cnt);
+				iptodot("AddIface(): Nat entry match with ip addr",
+						nat_iface_ipv4_addr[cnt]);
+				return true;
+			}
+		}
+	}
+
+	/* check whether non nat iface or not, on Nat iface
+	   add dummy rule by copying public ip to private ip */
+	for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++)
+	{
+		if (nonnat_iface_ipv4_addr[cnt] != 0)
+		{
+			if (rule->private_ip == nonnat_iface_ipv4_addr[cnt] ||
+				rule->target_ip == nonnat_iface_ipv4_addr[cnt])
+			{
+				IPACMDBG("matched non_nat_iface_ipv4_addr entry(%d)\n", cnt);
+				iptodot("AddIface(): Non Nat entry match with ip addr",
+						nat_iface_ipv4_addr[cnt]);
+
+				rule->private_ip = rule->public_ip;
+				rule->private_port = rule->public_port;
+				return true;
+			}
+		}
+	}
+
+	IPACMDBG_H("Not mtaching with non-nat ifaces\n");
+	if(pConfig == NULL)
+	{
+		pConfig = IPACM_Config::GetInstance();
+		if(pConfig == NULL)
+		{
+			IPACMERR("Unable to get Config instance\n");
+			return false;
+		}
+	}
+
+	if (pConfig->isPrivateSubnet(rule->private_ip) ||
+		pConfig->isPrivateSubnet(rule->target_ip))
+	{
+		IPACMDBG("Matching with Private subnet\n");
+		*isTempEntry = true;
+		return true;
+	}
+
+	return false;
+}
+
+void IPACM_ConntrackListener::AddORDeleteNatEntry(const nat_entry_bundle *input)
+{
+	u_int8_t tcp_state;
+
+	if (nat_inst == NULL)
+	{
+		IPACMERR("Nat instance is NULL, unable to add or delete\n");
+		return;
+	}
+
+	IPACMDBG_H("Below Nat Entry will either be added or deleted\n");
+	iptodot("AddORDeleteNatEntry(): target ip or dst ip",
+			input->rule->target_ip);
+	IPACMDBG("target port or dst port: 0x%x Decimal:%d\n",
+			 input->rule->target_port, input->rule->target_port);
+	iptodot("AddORDeleteNatEntry(): private ip or src ip",
+			input->rule->private_ip);
+	IPACMDBG("private port or src port: 0x%x, Decimal:%d\n",
+			 input->rule->private_port, input->rule->private_port);
+	IPACMDBG("public port or reply dst port: 0x%x, Decimal:%d\n",
+			 input->rule->public_port, input->rule->public_port);
+	IPACMDBG("Protocol: %d, destination nat flag: %d\n",
+			 input->rule->protocol, input->rule->dst_nat);
+
+	if (IPPROTO_TCP == input->rule->protocol)
+	{
+		tcp_state = nfct_get_attr_u8(input->ct, ATTR_TCP_STATE);
+		if (TCP_CONNTRACK_ESTABLISHED == tcp_state)
+		{
+			IPACMDBG("TCP state TCP_CONNTRACK_ESTABLISHED(%d)\n", tcp_state);
+			if (!CtList->isWanUp())
+			{
+				IPACMDBG("Wan is not up, cache connections\n");
+				nat_inst->CacheEntry(input->rule);
+			}
+			else if (input->isTempEntry)
+			{
+				nat_inst->AddTempEntry(input->rule);
+			}
+			else
+			{
+				nat_inst->AddEntry(input->rule);
+			}
+		}
+		else if (TCP_CONNTRACK_FIN_WAIT == tcp_state ||
+				   input->type == NFCT_T_DESTROY)
+		{
+			IPACMDBG("TCP state TCP_CONNTRACK_FIN_WAIT(%d) "
+					 "or type NFCT_T_DESTROY(%d)\n", tcp_state, input->type);
+
+			nat_inst->DeleteEntry(input->rule);
+			nat_inst->DeleteTempEntry(input->rule);
+		}
+		else
+		{
+			IPACMDBG("Ignore tcp state: %d and type: %d\n",
+					 tcp_state, input->type);
+		}
+
+	}
+	else if (IPPROTO_UDP == input->rule->protocol)
+	{
+		if (NFCT_T_NEW == input->type)
+		{
+			IPACMDBG("New UDP connection at time %ld\n", time(NULL));
+			if (!CtList->isWanUp())
+			{
+				IPACMDBG("Wan is not up, cache connections\n");
+				nat_inst->CacheEntry(input->rule);
+			}
+			else if (input->isTempEntry)
+			{
+				nat_inst->AddTempEntry(input->rule);
+			}
+			else
+			{
+				nat_inst->AddEntry(input->rule);
+			}
+		}
+		else if (NFCT_T_DESTROY == input->type)
+		{
+			IPACMDBG("UDP connection close at time %ld\n", time(NULL));
+			nat_inst->DeleteEntry(input->rule);
+			nat_inst->DeleteTempEntry(input->rule);
+		}
+	}
+
+	return;
+}
+
+void IPACM_ConntrackListener::PopulateTCPorUDPEntry(
+	 struct nf_conntrack *ct,
+	 uint32_t status,
+	 nat_table_entry *rule)
+{
+	if (IPS_DST_NAT == status)
+	{
+		IPACMDBG("Destination NAT\n");
+		rule->dst_nat = true;
+
+		IPACMDBG("Parse reply tuple\n");
+		rule->target_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC);
+		rule->target_ip = ntohl(rule->target_ip);
+		iptodot("PopulateTCPorUDPEntry(): target ip", rule->target_ip);
+
+		/* Retriev target/dst port */
+		rule->target_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC);
+		rule->target_port = ntohs(rule->target_port);
+		if (0 == rule->target_port)
+		{
+			IPACMDBG("unable to retrieve target port\n");
+		}
+
+		rule->public_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST);
+		rule->public_port = ntohs(rule->public_port);
+
+		/* Retriev src/private ip address */
+		rule->private_ip = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC);
+		rule->private_ip = ntohl(rule->private_ip);
+		iptodot("PopulateTCPorUDPEntry(): private ip", rule->private_ip);
+		if (0 == rule->private_ip)
+		{
+			IPACMDBG("unable to retrieve private ip address\n");
+		}
+
+		/* Retriev src/private port */
+		rule->private_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC);
+		rule->private_port = ntohs(rule->private_port);
+		if (0 == rule->private_port)
+		{
+			IPACMDBG("unable to retrieve private port\n");
+		}
+	}
+	else if (IPS_SRC_NAT == status)
+	{
+		IPACMDBG("Source NAT\n");
+		rule->dst_nat = false;
+
+		/* Retriev target/dst ip address */
+		IPACMDBG("Parse source tuple\n");
+		rule->target_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST);
+		rule->target_ip = ntohl(rule->target_ip);
+		iptodot("PopulateTCPorUDPEntry(): target ip", rule->target_ip);
+		if (0 == rule->target_ip)
+		{
+			IPACMDBG("unable to retrieve target ip address\n");
+		}
+		/* Retriev target/dst port */
+		rule->target_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST);
+		rule->target_port = ntohs(rule->target_port);
+		if (0 == rule->target_port)
+		{
+			IPACMDBG("unable to retrieve target port\n");
+		}
+
+		/* Retriev public port */
+		rule->public_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST);
+		rule->public_port = ntohs(rule->public_port);
+		if (0 == rule->public_port)
+		{
+			IPACMDBG("unable to retrieve public port\n");
+		}
+
+		/* Retriev src/private ip address */
+		rule->private_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC);
+		rule->private_ip = ntohl(rule->private_ip);
+		iptodot("PopulateTCPorUDPEntry(): private ip", rule->private_ip);
+		if (0 == rule->private_ip)
+		{
+			IPACMDBG("unable to retrieve private ip address\n");
+		}
+
+		/* Retriev src/private port */
+		rule->private_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC);
+		rule->private_port = ntohs(rule->private_port);
+		if (0 == rule->private_port)
+		{
+			IPACMDBG("unable to retrieve private port\n");
+		}
+	}
+
+	return;
+}
+
+#ifdef CT_OPT
+void IPACM_ConntrackListener::HandleLan2Lan(struct nf_conntrack *ct,
+	enum nf_conntrack_msg_type type,
+	 nat_table_entry *rule)
+{
+	ipacm_event_connection lan2lan_conn = { 0 };
+
+	if (p_lan2lan == NULL)
+	{
+		IPACMERR("Lan2Lan Instance is null\n");
+		return;
+	}
+
+	lan2lan_conn.iptype = IPA_IP_v4;
+	lan2lan_conn.src_ipv4_addr = orig_src_ip;
+	lan2lan_conn.dst_ipv4_addr = orig_dst_ip;
+
+	if (((IPPROTO_UDP == rule->protocol) && (NFCT_T_NEW == type)) ||
+		((IPPROTO_TCP == rule->protocol) && (nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_ESTABLISHED)))
+	{
+		p_lan2lan->handle_new_connection(&lan2lan_conn);
+	}
+	else if ((IPPROTO_UDP == rule->protocol && NFCT_T_DESTROY == type) ||
+			   (IPPROTO_TCP == rule->protocol &&
+				nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_FIN_WAIT))
+	{
+		p_lan2lan->handle_del_connection(&lan2lan_conn);
+	}
+}
+#endif
+
+void IPACM_ConntrackListener::CheckSTAClient(
+   const nat_table_entry *rule, bool *isTempEntry)
+{
+	int nCnt;
+
+	/* Check whether target is in STA client list or not
+      if not ignore the connection */
+	 if(!isStaMode || (StaClntCnt == 0))
+	 {
+		return;
+	 }
+
+	 if((sta_clnt_ipv4_addr[0] & STA_CLNT_SUBNET_MASK) !=
+		 (rule->target_ip & STA_CLNT_SUBNET_MASK))
+	 {
+		IPACMDBG("STA client subnet mask not matching\n");
+		return;
+	 }
+
+	 IPACMDBG("StaClntCnt %d\n", StaClntCnt);
+	 for(nCnt = 0; nCnt < StaClntCnt; nCnt++)
+	 {
+		IPACMDBG("Comparing trgt_ip 0x%x with sta clnt ip: 0x%x\n",
+			 rule->target_ip, sta_clnt_ipv4_addr[nCnt]);
+		if(rule->target_ip == sta_clnt_ipv4_addr[nCnt])
+		{
+			IPACMDBG("Match index %d\n", nCnt);
+			return;
+		}
+	 }
+
+	IPACMDBG_H("Not matching with STA Clnt Ip Addrs 0x%x\n",
+		rule->target_ip);
+	*isTempEntry = true;
+}
 
 /* conntrack send in host order and ipa expects in host order */
 void IPACM_ConntrackListener::ProcessTCPorUDPMsg(
@@ -636,19 +1016,16 @@
 	 u_int8_t l4proto)
 {
 	 nat_table_entry rule;
-	 u_int8_t tcp_state;
 	 uint32_t status = 0;
-	 IPACM_Config *pConfig;
 	 uint32_t orig_src_ip, orig_dst_ip;
-	 bool isTempEntry = false;
+	 bool isAdd = false;
+
+	 nat_entry_bundle nat_entry;
+	 nat_entry.isTempEntry = false;
+	 nat_entry.ct = ct;
+	 nat_entry.type = type;
 
  	 memset(&rule, 0, sizeof(rule));
-	 pConfig = IPACM_Config::GetInstance();
-	 if(pConfig == NULL)
-	 {
-		 IPACMERR("Unable to get Config instance\n");
-	 }
-
 	 IPACMDBG("Received type:%d with proto:%d\n", type, l4proto);
 	 status = nfct_get_attr_u32(ct, ATTR_STATUS);
 
@@ -695,116 +1072,19 @@
 		else
 		{
 			IPACMDBG_H("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);
+					   orig_src_ip, orig_dst_ip, wan_ipaddr);
 
 #ifdef CT_OPT
-		if(p_lan2lan == NULL)
-		{
-			IPACMERR("Lan2Lan Instance is null\n");
-			goto IGNORE;
-		}
-
-			 ipacm_event_connection lan2lan_conn = { 0 };
-			 lan2lan_conn.iptype = IPA_IP_v4;
-			 lan2lan_conn.src_ipv4_addr = orig_src_ip;
-			 lan2lan_conn.dst_ipv4_addr = orig_dst_ip;
-
-			 if(((IPPROTO_UDP == rule.protocol) && (NFCT_T_NEW == type)) ||
-					((IPPROTO_TCP == rule.protocol) && (nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_ESTABLISHED)))
-			 {
-				 p_lan2lan->handle_new_connection(&lan2lan_conn);
-			 }
-			 else if((IPPROTO_UDP == rule.protocol && NFCT_T_DESTROY == type) ||
-							 (IPPROTO_TCP == rule.protocol &&
-								nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_FIN_WAIT))
-			 {
-				 p_lan2lan->handle_del_connection(&lan2lan_conn);
-			 }
+			HandleLan2Lan(ct, type, &rule);
 #endif
-					 return;
-		 }
+			return;
+		}
 	 }
 
-	 if(IPS_DST_NAT == status)
+	 if(IPS_DST_NAT == status || IPS_SRC_NAT == status)
 	 {
-			IPACMDBG("Destination NAT\n");
-			rule.dst_nat = true;
-
-			IPACMDBG("Parse reply tuple\n");
-			rule.target_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC);
-			rule.target_ip = ntohl(rule.target_ip);
-
-			/* Retriev target/dst port */
-			rule.target_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC);
-			rule.target_port = ntohs(rule.target_port);
-			if(0 == rule.target_port)
-			{
-				 IPACMDBG("unable to retrieve target port\n");
-			}
-
-			rule.public_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST);
-			rule.public_port = ntohs(rule.public_port);
-
-			/* Retriev src/private ip address */
-			rule.private_ip = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC);
-			rule.private_ip = ntohl(rule.private_ip);
-			if(0 == rule.private_ip)
-			{
-				 IPACMDBG("unable to retrieve private ip address\n");
-			}
-
-			/* Retriev src/private port */
-			rule.private_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC);
-			rule.private_port = ntohs(rule.private_port);
-			if(0 == rule.private_port)
-			{
-				 IPACMDBG("unable to retrieve private port\n");
-			}
-	 }
-	 else if(IPS_SRC_NAT == status)
-	 {
-			IPACMDBG("Source NAT\n");
-			rule.dst_nat = false;
-
-			/* Retriev target/dst ip address */
-			IPACMDBG("Parse source tuple\n");
-			rule.target_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST);
-			rule.target_ip = ntohl(rule.target_ip);
-			if(0 == rule.target_ip)
-			{
-				 IPACMDBG("unable to retrieve target ip address\n");
-			}
-			/* Retriev target/dst port */
-			rule.target_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST);
-			rule.target_port = ntohs(rule.target_port);
-			if(0 == rule.target_port)
-			{
-				 IPACMDBG("unable to retrieve target port\n");
-			}
-
-			/* Retriev public port */
-			rule.public_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST);
-			rule.public_port = ntohs(rule.public_port);
-			if(0 == rule.public_port)
-			{
-				 IPACMDBG("unable to retrieve public port\n");
-			}
-
-			/* Retriev src/private ip address */
-			rule.private_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC);
-			rule.private_ip = ntohl(rule.private_ip);
-			if(0 == rule.private_ip)
-			{
-				 IPACMDBG("unable to retrieve private ip address\n");
-			}
-
-			/* Retriev src/private port */
-			rule.private_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC);
-			rule.private_port = ntohs(rule.private_port);
-			if(0 == rule.private_port)
-			{
-				 IPACMDBG("unable to retrieve private port\n");
-			}
+		 PopulateTCPorUDPEntry(ct, status, &rule);
+		 rule.public_ip = wan_ipaddr;
 	 }
 	 else
 	 {
@@ -812,188 +1092,41 @@
 		 goto IGNORE;
 	 }
 
-	 if(rule.private_ip != wan_ipaddr)
+	 if (rule.private_ip != wan_ipaddr)
 	 {
-		 int cnt;
-		 for(cnt = 0; cnt < MAX_NAT_IFACES; cnt++)
+		 isAdd = AddIface(&rule, &nat_entry.isTempEntry);
+		 if (!isAdd)
 		 {
-			 if(nat_iface_ipv4_addr[cnt] != 0)
-			 {
-				 if(rule.private_ip == nat_iface_ipv4_addr[cnt] ||
-						rule.target_ip == nat_iface_ipv4_addr[cnt])
-				 {
-					 IPACMDBG("matched nat_iface_ipv4_addr entry(%d)\n", cnt);
-					 iptodot("ProcessTCPorUDPMsg(): Nat entry match with ip addr",
-									nat_iface_ipv4_addr[cnt]);
-					 break;
-				 }
-			 }
+			 goto IGNORE;
 		 }
-
-		if(cnt == MAX_NAT_IFACES)
-		{
-			IPACMDBG_H("Not mtaching with nat ifaces\n");
-			if(pConfig == NULL)
-			{
-				goto IGNORE;
-			}
-
-			 if(pConfig->isPrivateSubnet(rule.private_ip) ||
-						pConfig->isPrivateSubnet(rule.target_ip))
-			 {
-				 IPACMDBG("Matching with Private subnet\n");
-				 isTempEntry = true;
-			 }
-			 else
-			 {
-				 goto IGNORE;
-			 }
-		 }
-
 	 }
 	 else
 	 {
-		 if(isStaMode) {
+		 if (isStaMode)
+		 {
 			 IPACMDBG("In STA mode, ignore connections destinated to STA interface\n");
 			 goto IGNORE;
 		 }
 
-     IPACMDBG("For embedded connections add dummy nat rule\n");
-     IPACMDBG("Change private port %d to %d\n",
-              rule.private_port, rule.public_port);
-     rule.private_port = rule.public_port;
+		 IPACMDBG("For embedded connections add dummy nat rule\n");
+		 IPACMDBG("Change private port %d to %d\n",
+				  rule.private_port, rule.public_port);
+		 rule.private_port = rule.public_port;
 	 }
 
-	 /* Check whether target is in STA client list or not
-      if not ignore the connection */
-	 int nCnt;
-
-	 if(!isStaMode || (StaClntCnt == 0))
-	 {
-		goto ADD;
-	 }
-
-	 if((sta_clnt_ipv4_addr[0] & 0xFFFFFF00) !=
-		 (rule.target_ip & 0xFFFFFF00))
-	 {
-		IPACMDBG("STA client subnet mask not matching\n");
-		goto ADD;
-	 }
-
-	 IPACMDBG("StaClntCnt %d\n", StaClntCnt);
-	 for(nCnt = 0; nCnt < StaClntCnt; nCnt++)
-	 {
-		IPACMDBG("Comparing trgt_ip 0x%x with sta clnt ip: 0x%x\n",
-			 rule.target_ip, sta_clnt_ipv4_addr[nCnt]);
-		if(rule.target_ip == sta_clnt_ipv4_addr[nCnt])
-		{
-			IPACMDBG("Match index %d\n", nCnt);
-			goto ADD;
-		}
-	 }
-
-	IPACMDBG_H("Not matching with STA Clnt Ip Addrs 0x%x\n",
-		rule.target_ip);
-	isTempEntry = true;
-
-
-ADD:
-	 IPACMDBG_H("Nat Entry with below information will either be added or deleted\n");
-	 iptodot("target ip or dst ip", rule.target_ip);
-	 IPACMDBG("target port or dst port: 0x%x Decimal:%d\n", rule.target_port, rule.target_port);
-	 iptodot("private ip or src ip", rule.private_ip);
-	 IPACMDBG("private port or src port: 0x%x, Decimal:%d\n", rule.private_port, rule.private_port);
-	 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);
-
-	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)
-			{
-				 IPACMDBG("TCP state TCP_CONNTRACK_ESTABLISHED(%d)\n", tcp_state);
-				 if(!CtList->isWanUp())
-				 {
-				 	 IPACMDBG("Wan is not up, cache connections\n");
-					 nat_inst->CacheEntry(&rule);
-				 }
-				 else if(isTempEntry)
-				 {
-					 nat_inst->AddTempEntry(&rule);
-				 }
-				 else
-				 {
-					 nat_inst->AddEntry(&rule);
-				 }
-			}
-			else if(TCP_CONNTRACK_FIN_WAIT == tcp_state ||
-			        type == NFCT_T_DESTROY)
-			{
-				 IPACMDBG("TCP state TCP_CONNTRACK_FIN_WAIT(%d) "
-						"or type NFCT_T_DESTROY(%d)\n", tcp_state, type);
-
-				 nat_inst->DeleteEntry(&rule);
-				 nat_inst->DeleteTempEntry(&rule);
-			}
-			else
-			{
-				 IPACMDBG("Ignore tcp state: %d and type: %d\n", tcp_state, type);
-			}
-
-	 }
-	 else if(IPPROTO_UDP == rule.protocol)
-	 {
-			if(nat_inst == NULL)
-			{
-				return;
-			}
-
-			if(NFCT_T_NEW == type)
-			{
-				 IPACMDBG("New UDP connection at time %ld\n", time(NULL));
-				 if(!CtList->isWanUp())
-				 {
-				 	 IPACMDBG("Wan is not up, cache connections\n");
-					 nat_inst->CacheEntry(&rule);
-				 }
-				 else if(isTempEntry)
-				 {
-					 nat_inst->AddTempEntry(&rule);
-				 }
-				 else
-				 {
-					 nat_inst->AddEntry(&rule);
-				 }
-			}
-			else if(NFCT_T_DESTROY == type)
-			{
-				 IPACMDBG("UDP connection close at time %ld\n", time(NULL));
-				 nat_inst->DeleteEntry(&rule);
-				 nat_inst->DeleteTempEntry(&rule);
-			}
-	 }
-	 else
-	 {
-			IPACMDBG("Ignore protocol: %d and type: %d\n", rule.protocol, type);
-	 }
-
+	 CheckSTAClient(&rule, &nat_entry.isTempEntry);
+	 nat_entry.rule = &rule;
+	 AddORDeleteNatEntry(&nat_entry);
 	 return;
 
 IGNORE:
 	IPACMDBG_H("ignoring below Nat Entry\n");
-	iptodot("target ip or dst ip", rule.target_ip);
+	iptodot("ProcessTCPorUDPMsg(): target ip or dst ip", rule.target_ip);
 	IPACMDBG("target port or dst port: 0x%x Decimal:%d\n", rule.target_port, rule.target_port);
-	iptodot("private ip or src ip", rule.private_ip);
+	iptodot("ProcessTCPorUDPMsg(): private ip or src ip", rule.private_ip);
 	IPACMDBG("private port or src port: 0x%x, Decimal:%d\n", rule.private_port, rule.private_port);
 	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);
-
 	return;
 }
 
diff --git a/ipacm/src/IPACM_Conntrack_NATApp.cpp b/ipacm/src/IPACM_Conntrack_NATApp.cpp
index 6efb475..93627bb 100644
--- a/ipacm/src/IPACM_Conntrack_NATApp.cpp
+++ b/ipacm/src/IPACM_Conntrack_NATApp.cpp
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2016, 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
@@ -149,7 +149,7 @@
 		return ret;
 	}
 
-	/* Add back the cashed NAT-entry */
+	/* Add back the cached NAT-entry */
 	if (pub_ip == pub_ip_addr_pre)
 	{
 		IPACMDBG("Restore the cache to ipa NAT-table\n");
@@ -197,7 +197,7 @@
 	/* NAT tbl deleted, reset enabled bit */
 	for(cnt = 0; cnt < max_entries; cnt++)
 	{
-		cache[cnt].enabled ==false;
+		cache[cnt].enabled = false;
 	}
 }
 
@@ -295,9 +295,9 @@
 /* Add new entry to the nat table on new connection */
 int NatApp::AddEntry(const nat_table_entry *rule)
 {
-
 	int cnt = 0;
 	ipa_nat_ipv4_rule nat_rule;
+
 	IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
 
 	CHK_TBL_HDL();
@@ -490,7 +490,8 @@
 	for(cnt = 0; cnt < max_entries; cnt++)
 	{
 		ts = 0;
-		if(cache[cnt].enabled == true)
+		if(cache[cnt].enabled == true &&
+		   (cache[cnt].private_ip != cache[cnt].public_ip))
 		{
 			IPACMDBG("\n");
 			if(ipa_nat_query_timestamp(nat_table_hdl, cache[cnt].rule_hdl, &ts) < 0)
@@ -724,8 +725,8 @@
 	IPACMDBG("Received below nat entry\n");
 	iptodot("Private IP", entry->private_ip);
 	iptodot("Target IP", entry->target_ip);
-	IPACMDBG("Private Port: %d\t Target Port: %d\t", entry->private_port, entry->target_port);
-	IPACMDBG("protocolcol: %d\n", entry->protocol);
+	IPACMDBG("Private Port: %d\t Target Port: %d\n", entry->private_port, entry->target_port);
+	IPACMDBG("protocol: %d\n", entry->protocol);
 
 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
 	{
@@ -745,13 +746,14 @@
 	return;
 }
 
-void NatApp::FlushTempEntries(uint32_t ip_addr, bool isAdd)
+void NatApp::FlushTempEntries(uint32_t ip_addr, bool isAdd,
+		bool isDummy)
 {
 	int cnt;
 	int ret;
 
 	IPACMDBG_H("Received below with isAdd:%d ", isAdd);
-	IPACMDBG_H("IP Address: (ox%x)\n", ip_addr);
+	iptodot("IP Address: ", ip_addr);
 
 	for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
 	{
@@ -762,6 +764,14 @@
 			{
 				if(temp[cnt].public_ip == pub_ip_addr)
 				{
+					if (isDummy) {
+						/* To avoild DL expections for non IPA path */
+						temp[cnt].private_ip = temp[cnt].public_ip;
+						temp[cnt].private_port = temp[cnt].public_port;
+						IPACMDBG("Flushing dummy temp rule");
+						iptodot("Private IP", temp[cnt].private_ip);
+					}
+
 					ret = AddEntry(&temp[cnt]);
 					if(ret)
 					{
@@ -861,6 +871,7 @@
 void NatApp::CacheEntry(const nat_table_entry *rule)
 {
 	int cnt;
+
 	if(rule->private_ip == 0 ||
 		 rule->target_ip == 0 ||
 		 rule->private_port == 0  ||
@@ -873,7 +884,7 @@
 
 	if(!ChkForDup(rule))
 	{
-		for(; cnt < max_entries; cnt++)
+		for(cnt=0; cnt < max_entries; cnt++)
 		{
 			if(cache[cnt].private_ip == 0 &&
 				 cache[cnt].target_ip == 0 &&
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index 2faf4e4..831243f 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -734,7 +734,6 @@
 
 void IPACM_Sig_Handler(int sig)
 {
-	int cnt;
 	ipacm_cmd_q_data evt_data;
 
 	printf("Received Signal: %d\n", sig);