Merge "IPACM: get upstream and tethered iface in Android"
diff --git a/ipacm/inc/IPACM_ConntrackListener.h b/ipacm/inc/IPACM_ConntrackListener.h
index e5827f2..c1249c2 100644
--- a/ipacm/inc/IPACM_ConntrackListener.h
+++ b/ipacm/inc/IPACM_ConntrackListener.h
@@ -76,8 +76,6 @@
int CreateNatThreads(void);
int CreateConnTrackThreads(void);
- void HandleNeighIpAddrAddEvt(void *);
- void HandleNeighIpAddrDelEvt(void *);
#ifdef CT_OPT
void ProcessCTV6Message(void *);
#endif
@@ -93,6 +91,9 @@
{
return WanUp;
}
+
+ void HandleNeighIpAddrAddEvt(ipacm_event_data_all *);
+ void HandleNeighIpAddrDelEvt(uint32_t);
};
extern IPACM_ConntrackListener *CtList;
diff --git a/ipacm/inc/IPACM_Conntrack_NATApp.h b/ipacm/inc/IPACM_Conntrack_NATApp.h
index 63af013..9eb9b4f 100644
--- a/ipacm/inc/IPACM_Conntrack_NATApp.h
+++ b/ipacm/inc/IPACM_Conntrack_NATApp.h
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (c) 2013, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -112,6 +112,7 @@
int UpdatePwrSaveIf(uint32_t);
int ResetPwrSaveIf(uint32_t);
+ int DelEntriesOnClntDiscon(uint32_t);
void UpdateTcpUdpTo(uint32_t, int proto);
diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp
index ae11d34..3559a8c 100644
--- a/ipacm/src/IPACM_ConntrackListener.cpp
+++ b/ipacm/src/IPACM_ConntrackListener.cpp
@@ -56,10 +56,6 @@
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);
-
- IPACMDBG("creating conntrack threads\n");
#ifdef CT_OPT
p_lan2lan = IPACM_LanToLan::getLan2LanInstance();
@@ -121,28 +117,13 @@
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");
- HandleNeighIpAddrAddEvt(data);
- }
- break;
-
- case IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT:
- {
- IPACMDBG("Received IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT event\n");
- HandleNeighIpAddrDelEvt(data);
- }
- break;
-
default:
IPACMDBG("Ignore cmd %d\n", evt);
break;
}
}
-void IPACM_ConntrackListener::HandleNeighIpAddrAddEvt(void *in_param)
+void IPACM_ConntrackListener::HandleNeighIpAddrAddEvt(ipacm_event_data_all *data)
{
- ipacm_event_data_all *data = (ipacm_event_data_all *)in_param;
int fd = 0, len = 0, cnt, i, j;
struct ifreq ifr;
bool isNatIface = false;
@@ -152,6 +133,8 @@
IPACMDBG("Ignoring IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT EVENT\n");
return;
}
+
+ IPACMDBG("\n");
IPACMDBG("Received interface index %d with ip type: %d", data->if_index, data->iptype);
iptodot(" and ipv4 address", data->ipv4_addr);
@@ -165,9 +148,8 @@
}
}
+
cnt = pConfig->GetNatIfacesCnt();
- if(NatIfaceCnt != cnt)
- {
NatIfaceCnt = cnt;
if(pNatIfaces != NULL)
{
@@ -189,9 +171,8 @@
IPACMERR("Unable to retrieve non nat ifaces\n");
return;
}
+ IPACMDBG("Update %d Nat ifaces\n", NatIfaceCnt);
- IPACMDBG("Update %d Nat ifaces", NatIfaceCnt);
- }
/* Search/Configure linux interface-index and map it to IPA interface-index */
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
@@ -265,37 +246,39 @@
}
-void IPACM_ConntrackListener::HandleNeighIpAddrDelEvt(void *in_param)
+void IPACM_ConntrackListener::HandleNeighIpAddrDelEvt(uint32_t ipv4_addr)
{
- ipacm_event_data_all *data = (ipacm_event_data_all *)in_param;
int cnt;
- if(data->ipv4_addr == 0 || data->iptype != IPA_IP_v4)
+ if(ipv4_addr == 0)
{
IPACMDBG("Ignoring IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT EVENT\n");
return;
}
- IPACMDBG("Received interface index %d with ip type:%d", data->if_index, data->iptype);
+
+ IPACMDBG("\n");
+ iptodot("Received ip addr", ipv4_addr);
IPACMDBG("Entering NAT entry deletion checking\n");
for(cnt = 0; cnt<MAX_NAT_IFACES; cnt++)
{
- if(nat_iface_ipv4_addr[cnt] == data->ipv4_addr)
+ if(nat_iface_ipv4_addr[cnt] == ipv4_addr)
{
- IPACMDBG("Reseting ct filters of Interface (%d), entry (%d) ", data->if_index, cnt);
+ 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] == data->ipv4_addr)
+ if(nonnat_iface_ipv4_addr[cnt] == ipv4_addr)
{
- IPACMDBG("Reseting ct filters of Interface (%d), entry (%d) ", data->if_index, cnt);
+ 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->FlushTempEntries(ipv4_addr, false);
+ nat_inst->DelEntriesOnClntDiscon(ipv4_addr);
return;
}
@@ -303,7 +286,7 @@
{
ipacm_event_iface_up *wanup_data = (ipacm_event_iface_up *)in_param;
- IPACMDBG("Recevied below information during wanup, ");
+ IPACMDBG("Recevied below information during wanup,\n");
IPACMDBG("if_name:%s, ipv4_address:0x%x\n",
wanup_data->ifname, wanup_data->ipv4_addr);
@@ -362,6 +345,7 @@
IPACMDBG("created UDP conntrack event listner thread\n");
}
+
isCTReg = true;
}
diff --git a/ipacm/src/IPACM_Conntrack_NATApp.cpp b/ipacm/src/IPACM_Conntrack_NATApp.cpp
index d6bbc19..b55d7e9 100644
--- a/ipacm/src/IPACM_Conntrack_NATApp.cpp
+++ b/ipacm/src/IPACM_Conntrack_NATApp.cpp
@@ -714,3 +714,49 @@
return;
}
+
+int NatApp::DelEntriesOnClntDiscon(uint32_t ip_addr)
+{
+ int cnt, tmp = curCnt;
+ IPACMDBG("Received IP address: 0x%x\n", ip_addr);
+
+ if(ip_addr == INVALID_IP_ADDR)
+ {
+ IPACMERR("Invalid ip address received\n");
+ return -1;
+ }
+
+ CHK_TBL_HDL();
+
+ 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)
+ {
+
+ 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;
+ }
+ }
+
+ memset(&cache[cnt], 0, sizeof(cache[cnt]));
+ curCnt--;
+ }
+ }
+
+ IPACMDBG("Deleted %d entries\n", (tmp - curCnt));
+ return 0;
+}
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 0bfe4c7..851b181 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -49,6 +49,8 @@
#include "linux/rmnet_ipa_fd_ioctl.h"
#include "linux/ipa_qmi_service_v01.h"
#include "linux/msm_ipa.h"
+#include "IPACM_ConntrackListener.h"
+
IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
{
@@ -413,6 +415,11 @@
return;
}
handle_eth_client_route_rule(data->mac_addr, data->iptype);
+ if (data->iptype == IPA_IP_v4)
+ {
+ /* Add NAT rules after ipv4 RT rules are set */
+ CtList->HandleNeighIpAddrAddEvt(data);
+ }
return;
}
}
@@ -1284,11 +1291,13 @@
}
else
{
- IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx);
- delete_eth_rtrules(clnt_indx,IPA_IP_v4);
- get_client_memptr(eth_client, clnt_indx)->route_rule_set_v4 = false;
- get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr;
- }
+ IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx);
+ /* delete NAT rules first */
+ CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, clnt_indx)->v4_addr);
+ delete_eth_rtrules(clnt_indx,IPA_IP_v4);
+ get_client_memptr(eth_client, clnt_indx)->route_rule_set_v4 = false;
+ get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr;
+ }
}
}
else
@@ -1555,19 +1564,19 @@
/* First reset nat rules and then route rules */
if(get_client_memptr(eth_client, clt_indx)->ipv4_set == true)
{
- IPACMDBG_H("Deleting Nat Rules\n");
- Nat_App->UpdatePwrSaveIf(get_client_memptr(eth_client, clt_indx)->v4_addr);
+ IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, clt_indx)->v4_addr);
+ CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, clt_indx)->v4_addr);
}
if (delete_eth_rtrules(clt_indx, IPA_IP_v4))
{
- IPACMERR("unbale to delete ecm-client v4 route rules\n");
+ IPACMERR("unbale to delete ecm-client v4 route rules for index: %d\n", clt_indx);
return IPACM_FAILURE;
}
if (delete_eth_rtrules(clt_indx, IPA_IP_v6))
{
- IPACMERR("unbale to delete ecm-client v6 route rules\n");
+ IPACMERR("unbale to delete ecm-client v6 route rules for index: %d\n", clt_indx);
return IPACM_FAILURE;
}
@@ -1704,8 +1713,26 @@
IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
for (i = 0; i < num_eth_client; i++)
{
- delete_eth_rtrules(i, IPA_IP_v4);
- delete_eth_rtrules(i, IPA_IP_v6);
+ /* First reset nat rules and then route rules */
+ if(get_client_memptr(eth_client, i)->ipv4_set == true)
+ {
+ IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, i)->v4_addr);
+ CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, i)->v4_addr);
+ }
+
+ if (delete_eth_rtrules(i, IPA_IP_v4))
+ {
+ IPACMERR("unbale to delete ecm-client v4 route rules for index %d\n", i);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if (delete_eth_rtrules(i, IPA_IP_v6))
+ {
+ IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
IPACMDBG_H("Delete %d client header\n", num_eth_client);
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index 670599a..badcc7e 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -707,7 +707,8 @@
===========================================================================*/
/*!
@brief
- Determine if IPACM process exists from its previous Process ID
+ Determine whether there's already an IPACM process running, if so, terminate
+ the current one
@return
None
@@ -724,62 +725,43 @@
void ipa_is_ipacm_running(void) {
- FILE *fp = NULL;
- pid_t ipacm_pid =0;
- char string[IPA_MAX_FILE_LEN];
+ int fd;
+ struct flock lock;
+ int retval;
- /* find the latest pid of executed IPACM */
- fp = fopen(IPACM_PID_FILE, "r");
- if ( fp == NULL )
+ fd = open(IPACM_PID_FILE, O_RDWR | O_CREAT, 0600);
+ if ( fd <= 0 )
{
- IPACMDBG_H("1st IPACM running \n");
+ IPACMERR("Failed to open %s, error is %d - %s\n",
+ IPACM_PID_FILE, errno, strerror(errno));
+ exit(0);
}
- else if (fscanf(fp, "%d", &ipacm_pid) != 1)
+
+ /*
+ * Getting an exclusive Write lock on the file, if it fails,
+ * it means that another instance of IPACM is running and it
+ * got the lock before us.
+ */
+ memset(&lock, 0, sizeof(lock));
+ lock.l_type = F_WRLCK;
+ retval = fcntl(fd, F_SETLK, &lock);
+
+ if (retval != 0)
{
- IPACMERR("Error reading ipacm_pid file \n");
- ipacm_pid = 0;
- fclose(fp);
+ retval = fcntl(fd, F_GETLK, &lock);
+ if (retval == 0)
+ {
+ IPACMERR("Unable to get lock on file %s (my PID %d), PID %d already has it\n",
+ IPACM_PID_FILE, getpid(), lock.l_pid);
+ close(fd);
+ exit(0);
+ }
}
else
{
- IPACMDBG_H("Primary IPACM PID = %d\n",ipacm_pid);
- fclose(fp);
- if (0 == kill(ipacm_pid, 0)) /* Process exists */
- {
- /* check that process is IPACM */
- memset(string, 0, IPA_MAX_FILE_LEN);
- snprintf(string, IPA_MAX_FILE_LEN, "/proc/%d/cmdline", ipacm_pid);
- IPACMDBG_H("open pid file %s \n",string);
- fp = fopen(string, "r");
- if ( fp == NULL )
- {
- IPACMDBG_H("open pid file failed \n");
- return;
- }
- else if (fgets(string, IPA_MAX_FILE_LEN, fp) != NULL)
- {
- IPACMDBG_H("get pid process name (%s)\n",string);
- if( strcmp(string, IPACM_NAME) == 0)
- {
- if(ipacm_pid != getpid())
- {
- IPACMDBG_H("found IPACM already in PID (%d), new PID(%d) exit(0)\n",ipacm_pid, getpid());
- exit(0);
- }
- IPACMDBG_H("same IPACM PID(%d) is running\n", getpid());
- }
- }
- fclose(fp);
- }
+ IPACMERR("PID %d is IPACM main process\n", getpid());
}
- ipacm_pid = getpid();
- fp = fopen(IPACM_PID_FILE, "w");
- if ( fp != NULL )
- {
- IPACMDBG_H(" IPACM current PID: %d \n",ipacm_pid);
- fprintf(fp, "%d", ipacm_pid);
- fclose(fp);
- }
+
return;
}
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 5cbcc4c..8c23025 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -48,6 +48,8 @@
#include <IPACM_Wan.h>
#include <IPACM_Lan.h>
#include <IPACM_IfaceManager.h>
+#include <IPACM_ConntrackListener.h>
+
/* static member to store the number of total wifi clients within all APs*/
int IPACM_Wlan::total_num_wifi_clients = 0;
@@ -496,7 +498,9 @@
handle_wlan_client_route_rule(data->mac_addr, data->iptype);
if (data->iptype == IPA_IP_v4)
{
- Nat_App->ResetPwrSaveIf(data->ipv4_addr);
+ /* Add NAT rules after ipv4 RT rules are set */
+ CtList->HandleNeighIpAddrAddEvt(data);
+// Nat_App->ResetPwrSaveIf(data->ipv4_addr);
}
}
}
@@ -1407,6 +1411,8 @@
else
{
IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx);
+ /* delete NAT rules first */
+ CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, clnt_indx)->v4_addr);
delete_default_qos_rtrules(clnt_indx,IPA_IP_v4);
get_client_memptr(wlan_client, clnt_indx)->route_rule_set_v4 = false;
get_client_memptr(wlan_client, clnt_indx)->v4_addr = data->ipv4_addr;
@@ -1721,19 +1727,19 @@
/* First reset nat rules and then route rules */
if(get_client_memptr(wlan_client, clt_indx)->ipv4_set == true)
{
- IPACMDBG_H("Deleting Nat Rules\n");
- Nat_App->UpdatePwrSaveIf(get_client_memptr(wlan_client, clt_indx)->v4_addr);
+ IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wlan_client, clt_indx)->v4_addr);
+ CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, clt_indx)->v4_addr);
}
if (delete_default_qos_rtrules(clt_indx, IPA_IP_v4))
{
- IPACMERR("unbale to delete v4 default qos route rules\n");
+ IPACMERR("unbale to delete v4 default qos route rules for index: %d\n", clt_indx);
return IPACM_FAILURE;
}
if (delete_default_qos_rtrules(clt_indx, IPA_IP_v6))
{
- IPACMERR("unbale to delete v6 default qos route rules\n");
+ IPACMERR("unbale to delete v6 default qos route rules for indexn: %d\n", clt_indx);
return IPACM_FAILURE;
}
@@ -1996,8 +2002,26 @@
for (i = 0; i < num_wifi_client; i++)
{
- delete_default_qos_rtrules(i, IPA_IP_v4);
- delete_default_qos_rtrules(i, IPA_IP_v6);
+ /* First reset nat rules and then route rules */
+ if(get_client_memptr(wlan_client, i)->ipv4_set == true)
+ {
+ IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wlan_client, i)->v4_addr);
+ CtList->HandleNeighIpAddrDelEvt(get_client_memptr(wlan_client, i)->v4_addr);
+ }
+
+ if (delete_default_qos_rtrules(i, IPA_IP_v4))
+ {
+ IPACMERR("unbale to delete v4 default qos route rules for index: %d\n", i);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if (delete_default_qos_rtrules(i, IPA_IP_v6))
+ {
+ IPACMERR("unbale to delete v6 default qos route rules for index: %d\n", i);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
IPACMDBG_H("Delete %d client header\n", num_wifi_client);