diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_ConntrackListener.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_ConntrackListener.h index 24a2c729..6cc4188b 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_ConntrackListener.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_ConntrackListener.h @@ -68,6 +68,7 @@ private: bool isCTReg; bool isNatThreadStart; bool WanUp; + bool isProcessCTDone; NatApp *nat_inst; int NatIfaceCnt; @@ -77,6 +78,7 @@ private: uint32_t nonnat_iface_ipv4_addr[MAX_IFACE_ADDRESS]; uint32_t sta_clnt_ipv4_addr[MAX_STA_CLNT_IFACES]; IPACM_Config *pConfig; + struct nf_conntrack **ct_entries; #ifdef CT_OPT IPACM_LanToLan *p_lan2lan; #endif @@ -104,6 +106,7 @@ public: char wan_ifname[IPA_IFACE_NAME_LEN]; uint32_t wan_ipaddr; ipacm_wan_iface_type backhaul_mode; + bool isReadCTDone; IPACM_ConntrackListener(); void event_callback(ipa_cm_event_id, void *data); inline bool isWanUp() @@ -116,6 +119,8 @@ public: void HandleSTAClientAddEvt(uint32_t); void HandleSTAClientDelEvt(uint32_t); int CreateConnTrackThreads(void); + void readConntrack(void); + void processConntrack(void); }; extern IPACM_ConntrackListener *CtList; diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h index b1daf353..f1113e8b 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h @@ -109,6 +109,11 @@ extern "C" #define NUM_IPV6_PREFIX_FLT_RULE 1 #define NUM_IPV6_PREFIX_MTU_RULE 1 +#define MAX_CONNTRACK_ENTRIES 100 +#define CT_ENTRIES_BUFFER_SIZE 8096 +#define LOOPBACK_MASK 0xFF000000 +#define LOOPBACK_ADDR 0x7F000000 + /*--------------------------------------------------------------------------- Return values indicating error status ---------------------------------------------------------------------------*/ diff --git a/data-ipa-cfg-mgr/ipacm/src/Android.mk b/data-ipa-cfg-mgr/ipacm/src/Android.mk index d706932f..ad271153 100644 --- a/data-ipa-cfg-mgr/ipacm/src/Android.mk +++ b/data-ipa-cfg-mgr/ipacm/src/Android.mk @@ -19,6 +19,9 @@ BOARD_PLATFORM_LIST := msm8909 BOARD_PLATFORM_LIST += msm8916 BOARD_PLATFORM_LIST += msm8917 BOARD_PLATFORM_LIST += qm215 +ifeq ($(TARGET_BOARD_SUFFIX),_gvmq) +BOARD_PLATFORM_LIST += msmnile +endif BOARD_IPAv3_LIST := msm8998 BOARD_IPAv3_LIST += sdm845 BOARD_IPAv3_LIST += sdm710 diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackClient.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackClient.cpp index 8a2499ce..24f95a33 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackClient.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackClient.cpp @@ -421,6 +421,17 @@ void* IPACM_ConntrackClient::TCPRegisterWithConnTrack(void *) unsigned subscrips = 0; IPACMDBG("\n"); + /* In Android we get conntrack handles once after tethering is enabled but we + loose connections info for embedded traffic if running before. So no NAT + entries are added for embedded traffic due to which we see NAT exception and + data takes S/W path which results in less throughput. Hence for embedded + traffic info, framework sends conntrack dump before providing handles. Here + reading ct entries before creating filter on Fd in order to have NAT entries + for both TCP/UDP embedded traffic. */ + if(CtList != NULL && !CtList->isReadCTDone) + { + CtList->readConntrack(); + } pClient = IPACM_ConntrackClient::GetInstance(); if(pClient == NULL) diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp index e006393c..fff6bfc5 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp @@ -35,6 +35,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "IPACM_EvtDispatcher.h" #include "IPACM_Iface.h" #include "IPACM_Wan.h" +#pragma clang diagnostic ignored "-Wdeprecated-declarations" IPACM_ConntrackListener::IPACM_ConntrackListener() { @@ -43,11 +44,14 @@ IPACM_ConntrackListener::IPACM_ConntrackListener() isNatThreadStart = false; isCTReg = false; WanUp = false; + isReadCTDone = false; + isProcessCTDone = false; nat_inst = NatApp::GetInstance(); NatIfaceCnt = 0; StaClntCnt = 0; pNatIfaces = NULL; + ct_entries = NULL; pConfig = IPACM_Config::GetInstance();; memset(nat_iface_ipv4_addr, 0, sizeof(nat_iface_ipv4_addr)); @@ -97,6 +101,10 @@ void IPACM_ConntrackListener::event_callback(ipa_cm_event_id evt, IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n"); CreateConnTrackThreads(); TriggerWANUp(data); + if(isReadCTDone && !isProcessCTDone) + { + processConntrack(); + } break; case IPA_HANDLE_WAN_DOWN: @@ -1201,3 +1209,157 @@ void IPACM_ConntrackListener::HandleSTAClientDelEvt(uint32_t clnt_ip_addr) nat_inst->FlushTempEntries(clnt_ip_addr, false); return; } + +bool isLocalHostAddr(uint32_t src_ip_addr, uint32_t dst_ip_addr) { + + src_ip_addr = ntohl(src_ip_addr); + dst_ip_addr = ntohl(dst_ip_addr); + if ((src_ip_addr & LOOPBACK_MASK) == LOOPBACK_ADDR || (dst_ip_addr & LOOPBACK_MASK) == LOOPBACK_ADDR) /* (loopback) */ + return true; + return false; +} + +void IPACM_ConntrackListener::readConntrack() { + + IPACM_ConntrackClient *pClient; + int len_fil = 0, recv_bytes = -1, index = 0, len =0; + char buffer[CT_ENTRIES_BUFFER_SIZE]; + char *buf = &buffer[0]; + struct nf_conntrack *ct; + struct nlmsghdr *nl_header; + static struct sockaddr_nl nlAddr = { + .nl_family = AF_NETLINK + }; + unsigned int addr_len = sizeof(nlAddr); + + pClient = IPACM_ConntrackClient::GetInstance(); + len = MAX_CONNTRACK_ENTRIES * sizeof(struct nf_conntrack **); + + ct_entries = (struct nf_conntrack **) malloc(len); + memset(ct_entries, 0, len); + + if( pClient->fd_tcp < 0) + { + IPACMDBG_H("Invalid fd %d \n",pClient->fd_tcp); + return; + } + + IPACMDBG_H("receiving conntrack entries started.\n"); + while(len_fil < sizeof(buffer) && index < MAX_CONNTRACK_ENTRIES) + { + recv_bytes = recvfrom( pClient->fd_tcp, buf, sizeof(buffer)-len_fil, 0, (struct sockaddr *)&nlAddr, (socklen_t *)&addr_len); + if(recv_bytes < 0) + { + IPACMDBG_H("error in receiving conntrack entries %d%s",errno, strerror(errno)); + break; + } + else + { + nl_header = (struct nlmsghdr *)buf; + + if (NLMSG_OK(nl_header, recv_bytes) == 0 || nl_header->nlmsg_type == NLMSG_ERROR) + { + IPACMDBG_H("recv_bytes is %d\n",recv_bytes); + break; + } + ct = nfct_new(); + if (ct != NULL) + { + int parseResult = nfct_parse_conntrack((nf_conntrack_msg_type) NFCT_T_ALL,nl_header, ct); + if(parseResult != NFCT_T_ERROR) + { + ct_entries[index++] = ct; + } + else + { + IPACMDBG_H("error in parsing %d%s \n", errno, strerror(errno)); + } + } + else + { + IPACMDBG_H("ct allocation failed"); + continue; + } + + if((nl_header->nlmsg_type & NLM_F_MULTI) == 0) + { + break; + } + len_fil += recv_bytes; + buf = buf + recv_bytes; + } + } + isReadCTDone = true; + IPACMDBG_H("receiving conntrack entries ended.\n"); + if(isWanUp() && !isProcessCTDone) + { + IPACMDBG_H("wan is up, process ct entries \n"); + processConntrack(); + } + + return ; +} + +void IPACM_ConntrackListener::processConntrack() { + + uint8_t ip_type; + int index = 0; + ipacm_ct_evt_data *ct_data; + enum nf_conntrack_msg_type type = NFCT_T_ALL; + IPACMDBG_H("process conntrack started \n"); + if(ct_entries != NULL) + { + while(ct_entries[index] != NULL) + { + ip_type = nfct_get_attr_u8(ct_entries[index], ATTR_REPL_L3PROTO); + if(!(AF_INET6 == ip_type) && isLocalHostAddr(nfct_get_attr_u32(ct_entries[index], ATTR_ORIG_IPV4_SRC), + nfct_get_attr_u32(ct_entries[index], ATTR_ORIG_IPV4_DST))) + { + IPACMDBG_H(" loopback entry \n"); + goto IGNORE; + } + +#ifndef CT_OPT + if(AF_INET6 == ip_type) + { + IPACMDBG("Ignoring ipv6(%d) connections\n", ip_type); + goto IGNORE; + } +#endif + + ct_data = (ipacm_ct_evt_data *)malloc(sizeof(ipacm_ct_evt_data)); + if(ct_data == NULL) + { + IPACMERR("unable to allocate memory \n"); + goto IGNORE; + } + + ct_data->ct = ct_entries[index]; + ct_data->type = type; + +#ifdef CT_OPT + if(AF_INET6 == ip_type) + { + ProcessCTV6Message(ct_data); + } +#else + ProcessCTMessage(ct_data); +#endif + index++; + free(ct_data); + continue; +IGNORE: + nfct_destroy(ct_entries[index]); + index++; + } + } + else + { + IPACMDBG_H("ct entry is null\n"); + return ; + } + isProcessCTDone = true; + free(ct_entries); + IPACMDBG_H("process conntrack ended \n"); + return; +} diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp index 1828910f..c15fad0b 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp @@ -1855,7 +1855,7 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) { /* treat Q6_MHI_WAN as STA mode also */ IPACMDBG_H("Q6-MHI ipv4/v6-header already constructed \n"); - IPACM_Wan::backhaul_mode = m_is_sta_mode; + IPACM_Wan::backhaul_mode = m_is_sta_mode; IPACMDBG_H("Setting up QMAP ID %d.\n", ext_prop->ext[0].mux_id); IPACM_Iface::ipacmcfg->SetQmapId(ext_prop->ext[0].mux_id); /* sending mux-id info to PCIE-modem for UL */ @@ -2567,7 +2567,7 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) } else { - IPACMDBG_H("in Q6_MHI_WAN mode, skip firewall, use default configuration \n"); + IPACMDBG_H("in Q6_MHI_WAN mode, skip firewall, use default configuration \n"); } /* construct ipa_ioc_add_flt_rule with N firewall rules */ ipa_ioc_add_flt_rule *m_pFilteringTable = NULL; @@ -3059,7 +3059,7 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) } else { - IPACMDBG_H("in Q6_MHI_WAN mode, skip ICMPv6 flt rule \n"); + IPACMDBG_H("in Q6_MHI_WAN mode, skip ICMPv6 flt rule \n"); } /* v6 default route */ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); diff --git a/data-ipa-cfg-mgr/ipanat/src/Android.mk b/data-ipa-cfg-mgr/ipanat/src/Android.mk index bb87e825..fc7b7ea8 100644 --- a/data-ipa-cfg-mgr/ipanat/src/Android.mk +++ b/data-ipa-cfg-mgr/ipanat/src/Android.mk @@ -1,6 +1,9 @@ BOARD_PLATFORM_LIST := msm8909 BOARD_PLATFORM_LIST += msm8916 BOARD_PLATFORM_LIST += msm8917 +ifeq ($(TARGET_BOARD_SUFFIX),_gvmq) +BOARD_PLATFORM_LIST += msmnile +endif TARGET_DISABLE_IPANAT := false ifeq ($(TARGET_USES_QMAA),true)