diff options
author | Skylar Chang <chiaweic@codeaurora.org> | 2014-09-06 22:51:12 -0700 |
---|---|---|
committer | Skylar Chang <chiaweic@codeaurora.org> | 2014-09-15 18:47:37 -0700 |
commit | 2c7d9623ee8cad5a6cfcd6b91cb474bbfb66f717 (patch) | |
tree | da1ebddc22b24429a805a2ffb487c6ebdd4efd3c /ipacm/src/IPACM_ConntrackListener.cpp | |
parent | e36f3320a8cd36eb76d611989c67ae7184868da1 (diff) | |
download | ipacfg-mgr-2c7d9623ee8cad5a6cfcd6b91cb474bbfb66f717.tar.gz |
IPACM: Fix AP+STA mode FTP loca-subnet disconnect issue
In AP+STA mode, usb-client can download FTP if FTP server
outside the subnet of external AP. However if the FTP server
is insided the same subnet as external-AP, the FTP download
will failed, also TCP UL/DL is not working properly. The fix
is to construct headers/routing rules for each wifi-client
which is connected to the same external AP's subnet.
Change-Id: I839d33d34b4fd544381b9cf7bd2ba20b51a17551
Diffstat (limited to 'ipacm/src/IPACM_ConntrackListener.cpp')
-rw-r--r-- | ipacm/src/IPACM_ConntrackListener.cpp | 96 |
1 files changed, 92 insertions, 4 deletions
diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp index 3559a8c..3a2041a 100644 --- a/ipacm/src/IPACM_ConntrackListener.cpp +++ b/ipacm/src/IPACM_ConntrackListener.cpp @@ -44,11 +44,13 @@ IPACM_ConntrackListener::IPACM_ConntrackListener() nat_inst = NatApp::GetInstance(); NatIfaceCnt = 0; + StaClntCnt = 0; pNatIfaces = NULL; pConfig = NULL; memset(nat_iface_ipv4_addr, 0, sizeof(nat_iface_ipv4_addr)); memset(nonnat_iface_ipv4_addr, 0, sizeof(nonnat_iface_ipv4_addr)); + memset(sta_clnt_ipv4_addr, 0, sizeof(sta_clnt_ipv4_addr)); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, this); IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, this); @@ -857,12 +859,46 @@ void IPACM_ConntrackListener::ProcessTCPorUDPMsg( 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("Not matching with STA Clnt Ip Addrs 0x%x\n", + rule.target_ip); + goto IGNORE; + + +ADD: IPACMDBG("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); @@ -963,8 +999,60 @@ IGNORE: return; } +void IPACM_ConntrackListener::HandleSTAClientAddEvt(uint32_t clnt_ip_addr) +{ + int cnt; + IPACMDBG("Received STA client 0x%x\n", clnt_ip_addr); + + if(StaClntCnt >= MAX_STA_CLNT_IFACES) + { + IPACMDBG("Max STA client reached, ignore 0x%x\n", clnt_ip_addr); + return; + } + + for(cnt=0; cnt<MAX_STA_CLNT_IFACES; cnt++) + { + if(sta_clnt_ipv4_addr[cnt] != 0 && + sta_clnt_ipv4_addr[cnt] == clnt_ip_addr) + { + IPACMDBG("Ignoring duplicate one 0x%x\n", clnt_ip_addr); + break; + } + if(sta_clnt_ipv4_addr[cnt] == 0) + { + IPACMDBG("Adding STA client 0x%x at Index: %d\n", + clnt_ip_addr, cnt); + sta_clnt_ipv4_addr[cnt] = clnt_ip_addr; + StaClntCnt++; + IPACMDBG("STA client cnt %d\n", StaClntCnt); + break; + } + } + return; +} +void IPACM_ConntrackListener::HandleSTAClientDelEvt(uint32_t clnt_ip_addr) +{ + int cnt; + IPACMDBG("Received STA client 0x%x\n", clnt_ip_addr); + for(cnt=0; cnt<MAX_STA_CLNT_IFACES; cnt++) + { + if(sta_clnt_ipv4_addr[cnt] != 0 && + sta_clnt_ipv4_addr[cnt] == clnt_ip_addr) + { + IPACMDBG("Deleting STA client 0x%x at index: %d\n", + clnt_ip_addr, cnt); + sta_clnt_ipv4_addr[cnt] = 0; + nat_inst->DelEntriesOnSTAClntDiscon(clnt_ip_addr); + StaClntCnt--; + IPACMDBG("STA client cnt %d\n", StaClntCnt); + break; + } + } + + return; +} |