From b22549698cb2afeaa16eb851bbfdd97852789b45 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Mon, 6 Apr 2020 22:20:50 -0700 Subject: ipacm: Fix installing ipv6 coalescing rules Make changes to ensure index is not going out of bounds when installing ipv6 coalescing rules. Change-Id: Ib35964152e71dd129431e5eece9629b69defe86d --- ipacm/src/IPACM_Wan.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp index 847e08d..a475894 100644 --- a/ipacm/src/IPACM_Wan.cpp +++ b/ipacm/src/IPACM_Wan.cpp @@ -7342,10 +7342,10 @@ fail: rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = false; rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; - rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = ipv6_addr[num_dft_rt_v6][0]; - rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = ipv6_addr[num_dft_rt_v6][1]; - rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = ipv6_addr[num_dft_rt_v6][2]; - rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = ipv6_addr[num_dft_rt_v6][3]; + rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = ipv6_addr[i][0]; + rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = ipv6_addr[i][1]; + rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = ipv6_addr[i][2]; + rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = ipv6_addr[i][3]; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; -- cgit v1.2.3 From f56cda8be4b567dac075d01c402a81f51516be55 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Tue, 28 Apr 2020 17:39:20 -0700 Subject: ipacm: add support for diag logging Add changes to enable DEBUG flag to enable ipacm-diag logging. Change-Id: I15e75c41a8a3096c41167c0194bbbb39e861056f --- ipacm/Android.bp | 1 + 1 file changed, 1 insertion(+) diff --git a/ipacm/Android.bp b/ipacm/Android.bp index b0d705b..0ce21f7 100644 --- a/ipacm/Android.bp +++ b/ipacm/Android.bp @@ -7,6 +7,7 @@ cc_binary { cflags: ["-v"] + ["-DFEATURE_IPA_ANDROID"] + ["-DFEATURE_IPACM_RESTART"] + [ "-DFEATURE_IPACM_HAL", + "-DDEBUG", "-Wall", "-Werror", "-Wno-error=macro-redefined", -- cgit v1.2.3 From 5a520856fbd2e3978564dceefa6ed7a5c33841e5 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Thu, 7 May 2020 12:23:37 -0700 Subject: ipacm: Fix resetting NAT ifaces for WLAN interface Starting from HST and HSP, WLAN doesn't restart when Q6 is restarting. So there is no need to resetting the NAT ifaces for Q6 SSR. Make a change to skip posting IPA_SSR_NOTICE to WLAN iface. Change-Id: I32fc1528d67912a7e90d716cc51378c64d50ba70 --- ipacm/src/IPACM_Main.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp index 696f518..ec5de34 100644 --- a/ipacm/src/IPACM_Main.cpp +++ b/ipacm/src/IPACM_Main.cpp @@ -760,10 +760,19 @@ void* ipa_driver_msg_notifier(void *param) IPACMERR("calling OffloadMng->elrInstance->onOffloadStopped \n"); OffloadMng->elrInstance->onOffloadStopped(IpaEventRelay::ERROR); } - /* WA to clean up wlan instances during SSR */ - evt_data.event = IPA_SSR_NOTICE; - evt_data.evt_data = NULL; - break; + /* Starting from Hastings, WLAN is not restarted as part of Modem SSR. + * No need to reset NAT Iface. + */ +#ifdef IPA_HW_v4_9 + if (IPACM_Iface::ipacmcfg->GetIPAVer() != IPA_HW_v4_9) +#endif + { + /* WA to clean up wlan instances during SSR */ + evt_data.event = IPA_SSR_NOTICE; + evt_data.evt_data = NULL; + break; + } + continue; case IPA_SSR_AFTER_POWERUP: IPACMDBG_H("Received IPA_SSR_AFTER_POWERUP\n"); OffloadMng = IPACM_OffloadManager::GetInstance(); -- cgit v1.2.3 From efc33e81f90e6d444cfb09e79ba486031e2e86e8 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Thu, 21 May 2020 19:13:21 -0700 Subject: ipacm: provide mechanism to provide upstream interface name Make changes to provide upstream interface name to netmgr whenever tethering is enabled. Change-Id: Id0cb3d0e34c1b324785da12f49c4f8502adabc6b --- ipacm/src/IPACM_Wan.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp index a475894..7383aed 100644 --- a/ipacm/src/IPACM_Wan.cpp +++ b/ipacm/src/IPACM_Wan.cpp @@ -2236,6 +2236,9 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) } IPACMDBG_H("send WAN_IOC_NOTIFY_WAN_STATE up to IPA_PM\n"); wan_state.up = true; +#ifdef WAN_IOCTL_NOTIFY_WAN_INTF_NAME + strlcpy(wan_state.upstreamIface, dev_name, IFNAMSIZ); +#endif if(ioctl(fd_wwan_ioctl, WAN_IOC_NOTIFY_WAN_STATE, &wan_state)) { IPACMERR("Failed to send WAN_IOC_NOTIFY_WAN_STATE as up %d\n ", wan_state.up); @@ -4814,6 +4817,9 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype) return false; } IPACMDBG_H("send WAN_IOC_NOTIFY_WAN_STATE down to IPA_PM\n"); +#ifdef WAN_IOCTL_NOTIFY_WAN_INTF_NAME + strlcpy(wan_state.upstreamIface, dev_name, IFNAMSIZ); +#endif if(ioctl(fd_wwan_ioctl, WAN_IOC_NOTIFY_WAN_STATE, &wan_state)) { IPACMERR("Failed to send WAN_IOC_NOTIFY_WAN_STATE as up %d\n ", wan_state.up); @@ -4995,6 +5001,9 @@ int IPACM_Wan::handle_route_del_evt_ex(ipa_ip_type iptype) return false; } IPACMDBG_H("send WAN_IOC_NOTIFY_WAN_STATE down to IPA_PM\n"); +#ifdef WAN_IOCTL_NOTIFY_WAN_INTF_NAME + strlcpy(wan_state.upstreamIface, dev_name, IFNAMSIZ); +#endif if(ioctl(fd_wwan_ioctl, WAN_IOC_NOTIFY_WAN_STATE, &wan_state)) { IPACMERR("Failed to send WAN_IOC_NOTIFY_WAN_STATE as up %d\n ", wan_state.up); -- cgit v1.2.3 From 2e4f6ddd0b47c151f7c1d814b4302d706f83e238 Mon Sep 17 00:00:00 2001 From: Armaan Siddiqui Date: Wed, 1 Apr 2020 02:17:40 +0530 Subject: ipacm : Add change to update NAT entries for embedded/tethered connections Add change to read and process conntrack entries only when WAN is up and add NAT entries accordingly when switch to tethered connections. Change-Id: Iaa31a44684082802c03402cdd1faa393a7bc85f8 --- ipacm/inc/IPACM_ConntrackListener.h | 5 ++ ipacm/inc/IPACM_Defs.h | 5 ++ ipacm/src/IPACM_ConntrackClient.cpp | 11 +++ ipacm/src/IPACM_ConntrackListener.cpp | 162 ++++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+) diff --git a/ipacm/inc/IPACM_ConntrackListener.h b/ipacm/inc/IPACM_ConntrackListener.h index 24a2c72..6cc4188 100644 --- a/ipacm/inc/IPACM_ConntrackListener.h +++ b/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/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h index a3cbba1..e60516e 100644 --- a/ipacm/inc/IPACM_Defs.h +++ b/ipacm/inc/IPACM_Defs.h @@ -105,6 +105,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/ipacm/src/IPACM_ConntrackClient.cpp b/ipacm/src/IPACM_ConntrackClient.cpp index 8a2499c..24f95a3 100644 --- a/ipacm/src/IPACM_ConntrackClient.cpp +++ b/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/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp index e006393..fff6bfc 100644 --- a/ipacm/src/IPACM_ConntrackListener.cpp +++ b/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; +} -- cgit v1.2.3 From 4298975b49e7b82d1ab3a0dfae90aa6515760a65 Mon Sep 17 00:00:00 2001 From: Sivakanth vaka Date: Mon, 15 Jun 2020 15:23:13 +0530 Subject: ipacm : Add change to avoid null ptr dereference issues Add null ptr check to avoid dereferencing issues. Change-Id: I0ead7ae6f3ecb684383f26580afc9e96f2b4b131 --- ipacm/src/IPACM_ConntrackListener.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp index fff6bfc..baddb4d 100644 --- a/ipacm/src/IPACM_ConntrackListener.cpp +++ b/ipacm/src/IPACM_ConntrackListener.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. +Copyright (c) 2013-2020, 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 @@ -1233,14 +1233,26 @@ void IPACM_ConntrackListener::readConntrack() { unsigned int addr_len = sizeof(nlAddr); pClient = IPACM_ConntrackClient::GetInstance(); + if(pClient == NULL) + { + IPACMERR("unable to get conntrack client instance\n"); + return; + } + len = MAX_CONNTRACK_ENTRIES * sizeof(struct nf_conntrack **); ct_entries = (struct nf_conntrack **) malloc(len); + if(ct_entries == NULL) + { + IPACMERR("unable to allocate ct_entries memory \n"); + return; + } memset(ct_entries, 0, len); if( pClient->fd_tcp < 0) { IPACMDBG_H("Invalid fd %d \n",pClient->fd_tcp); + free(ct_entries); return; } -- cgit v1.2.3 From d60383f64e3205246497397293069cf2140aec18 Mon Sep 17 00:00:00 2001 From: Armaan Siddiqui Date: Fri, 7 Feb 2020 17:18:04 +0530 Subject: ipacm: Remove IPV6 TCP SYN/FIN/RST rules Remove IPV6 TCP SYN/FIN/RST default filter rule to free the memory as we already add default rt-rule Change-Id: Ief0d0eedffce2b60162e6f2b63ba44c3c7e4817c --- ipacm/inc/IPACM_Iface.h | 4 +- ipacm/inc/IPACM_Wan.h | 2 - ipacm/src/IPACM_Iface.cpp | 53 +----------------------- ipacm/src/IPACM_Wan.cpp | 102 +--------------------------------------------- 4 files changed, 4 insertions(+), 157 deletions(-) diff --git a/ipacm/inc/IPACM_Iface.h b/ipacm/inc/IPACM_Iface.h index 55d9e99..35d12db 100644 --- a/ipacm/inc/IPACM_Iface.h +++ b/ipacm/inc/IPACM_Iface.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. +Copyright (c) 2013-2020, 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 @@ -59,7 +59,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define IPV4_DEFAULT_FILTERTING_RULES 3 #ifdef FEATURE_IPA_ANDROID -#define IPV6_DEFAULT_FILTERTING_RULES 8 +#define IPV6_DEFAULT_FILTERTING_RULES 5 #else #define IPV6_DEFAULT_FILTERTING_RULES 4 #endif diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h index 31949c5..4eb5547 100644 --- a/ipacm/inc/IPACM_Wan.h +++ b/ipacm/inc/IPACM_Wan.h @@ -645,8 +645,6 @@ private: int add_dft_filtering_rule(struct ipa_flt_rule_add* rules, int rule_offset, ipa_ip_type iptype); - int add_tcpv6_filtering_rule(struct ipa_flt_rule_add* rules, int rule_offset); - int install_wan_filtering_rule(bool is_sw_routing); void handle_wlan_SCC_MCC_switch(bool, ipa_ip_type); diff --git a/ipacm/src/IPACM_Iface.cpp b/ipacm/src/IPACM_Iface.cpp index 0d4f54f..8282915 100644 --- a/ipacm/src/IPACM_Iface.cpp +++ b/ipacm/src/IPACM_Iface.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. +Copyright (c) 2013-2020, 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 @@ -955,57 +955,6 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype) memcpy(&(m_pFilteringTable->rules[4]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); - IPACMDBG_H("Add TCP ctrl rules: total num %d\n", IPV6_DEFAULT_FILTERTING_RULES); - memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); - - flt_rule_entry.at_rear = true; - flt_rule_entry.flt_rule_hdl = -1; - flt_rule_entry.status = -1; - - flt_rule_entry.rule.retain_hdr = 1; - flt_rule_entry.rule.to_uc = 0; - flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; - flt_rule_entry.rule.eq_attrib_type = 1; - flt_rule_entry.rule.eq_attrib.rule_eq_bitmap = 0; - - if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA) - { - if (IPACM_Iface::ipacmcfg->isIPAv3Supported()) - flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<9); - else - flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<14); - flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1; - flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0; - flt_rule_entry.rule.eq_attrib.metadata_meq32.value = rx_prop->rx[0].attrib.meta_data; - flt_rule_entry.rule.eq_attrib.metadata_meq32.mask = rx_prop->rx[0].attrib.meta_data_mask; - } - - flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<1); - flt_rule_entry.rule.eq_attrib.protocol_eq_present = 1; - flt_rule_entry.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP; - - if (IPACM_Iface::ipacmcfg->isIPAv3Supported()) - flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<7); - else - flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<8); - flt_rule_entry.rule.eq_attrib.num_ihl_offset_meq_32 = 1; - flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12; - - /* add TCP FIN rule*/ - flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[5]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); - - /* add TCP SYN rule*/ - flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[6]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); - - /* add TCP RST rule*/ - flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<rules[7]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); - #endif #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO /* use index hw-counter */ diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp index 7383aed..397c820 100644 --- a/ipacm/src/IPACM_Wan.cpp +++ b/ipacm/src/IPACM_Wan.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. +Copyright (c) 2013-2020 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 @@ -4260,9 +4260,6 @@ int IPACM_Wan::config_wan_firewall_rule(ipa_ip_type iptype) } else if(iptype == IPA_IP_v6) { -#ifdef FEATURE_IPA_ANDROID - add_tcpv6_filtering_rule(flt_rule_v6, IPACM_Wan::num_v6_flt_rule); -#endif IPACM_Wan::num_v6_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6; if(IPACM_FAILURE == add_icmp_alg_rules(flt_rule_v6, IPACM_Wan::num_v6_flt_rule, IPA_IP_v6)) { @@ -4547,103 +4544,6 @@ fail: return res; } -int IPACM_Wan::add_tcpv6_filtering_rule(struct ipa_flt_rule_add *rules, int rule_offset) -{ - struct ipa_ioc_get_rt_tbl_indx rt_tbl_idx; - struct ipa_flt_rule_add flt_rule_entry; - struct ipa_ioc_generate_flt_eq flt_eq; - int res = IPACM_SUCCESS; - - if(rules == NULL) - { - IPACMERR("No filtering table available.\n"); - return IPACM_FAILURE; - } - if(rx_prop == NULL) - { - IPACMERR("No tx property.\n"); - return IPACM_FAILURE; - } - - memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); - strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); - rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; - rt_tbl_idx.ip = IPA_IP_v6; - if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) - { - IPACMERR("Failed to get routing table index from name\n"); - res = IPACM_FAILURE; - goto fail; - } - - IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); - memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); - - flt_rule_entry.at_rear = true; - flt_rule_entry.flt_rule_hdl = -1; - flt_rule_entry.status = -1; - - flt_rule_entry.rule.retain_hdr = 1; - flt_rule_entry.rule.to_uc = 0; - flt_rule_entry.rule.eq_attrib_type = 1; - flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; - flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; - -#ifdef FEATURE_IPA_ANDROID - IPACMDBG_H("Add TCP ctrl rules: total num %d\n", IPA_V2_NUM_TCP_WAN_FILTER_RULE_IPV6); -#endif - memcpy(&flt_rule_entry.rule.attrib, - &rx_prop->rx[0].attrib, - sizeof(flt_rule_entry.rule.attrib)); - memset(&flt_eq, 0, sizeof(flt_eq)); - memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); - flt_eq.ip = IPA_IP_v6; - if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) - { - IPACMERR("Failed to get eq_attrib\n"); - res = IPACM_FAILURE; - goto fail; - } - - memcpy(&flt_rule_entry.rule.eq_attrib, - &flt_eq.eq_attrib, - sizeof(flt_rule_entry.rule.eq_attrib)); - - flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<1); - flt_rule_entry.rule.eq_attrib.protocol_eq_present = 1; - flt_rule_entry.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP; - - if (IPACM_Iface::ipacmcfg->isIPAv3Supported()) - flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<7); - else - flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<8); - flt_rule_entry.rule.eq_attrib.num_ihl_offset_meq_32 = 1; - flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12; - - /* add TCP FIN rule*/ - flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)< Date: Thu, 12 Mar 2020 17:49:50 +0530 Subject: ipacm: V6 filter count mismatch causing udp failures Invalid filter count being passed to modem to install DL filter rules which is creating dummy rules in filter table and udp packets are not matching to any filters Change-Id: I0f2a0dab4b1afea62eda63b4518e6592ff8be53b --- ipacm/inc/IPACM_Wan.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h index 31949c5..5133ffe 100644 --- a/ipacm/inc/IPACM_Wan.h +++ b/ipacm/inc/IPACM_Wan.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. +Copyright (c) 2013-2020, 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 @@ -53,7 +53,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4 2 #ifdef FEATURE_IPA_ANDROID -#define IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6 7 +#define IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6 4 #define IPA_V2_NUM_TCP_WAN_FILTER_RULE_IPV6 3 #define IPA_V2_NUM_MULTICAST_WAN_FILTER_RULE_IPV6 3 #define IPA_V2_NUM_FRAG_WAN_FILTER_RULE_IPV6 1 -- cgit v1.2.3 From 6facc43568f6de2ca4142bb497077639c83db7cd Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Tue, 21 Apr 2020 19:13:58 -0700 Subject: ipacm: keep track of flt rule handles that are in use Initialize an array to keep track which filtering handles are in use to prevent a wraparound issue where we have 2 rules with the same ID leading to a problem with rule deletion. Change-Id: I940c043f486860a1a694ad3b3a183cae44d1057e Signed-off-by: Michael Adisumarta --- ipacm/inc/IPACM_Filtering.h | 2 ++ ipacm/src/IPACM_Filtering.cpp | 27 +++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/ipacm/inc/IPACM_Filtering.h b/ipacm/inc/IPACM_Filtering.h index 428c21a..6667235 100644 --- a/ipacm/inc/IPACM_Filtering.h +++ b/ipacm/inc/IPACM_Filtering.h @@ -48,6 +48,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #define IPA_PCIE_MODEM_RULE_ID_START 69 +#define IPA_PCIE_MODEM_RULE_ID_MAX 1000 class IPACM_Filtering { @@ -80,6 +81,7 @@ private: int fd; /* File descriptor of the IPA device node /dev/ipa */ int total_num_offload_rules; int pcie_modem_rule_id; + bool pcie_modem_rule_id_in_use[IPA_PCIE_MODEM_RULE_ID_MAX]; }; #endif //IPACM_FILTERING_H diff --git a/ipacm/src/IPACM_Filtering.cpp b/ipacm/src/IPACM_Filtering.cpp index 8aa25a6..b230c36 100644 --- a/ipacm/src/IPACM_Filtering.cpp +++ b/ipacm/src/IPACM_Filtering.cpp @@ -60,6 +60,7 @@ IPACM_Filtering::IPACM_Filtering() } total_num_offload_rules = 0; pcie_modem_rule_id = 0; + memset(pcie_modem_rule_id_in_use, 0, sizeof(pcie_modem_rule_id_in_use)); } IPACM_Filtering::~IPACM_Filtering() @@ -710,7 +711,7 @@ bool IPACM_Filtering::AddWanDLFilteringRule(struct ipa_ioc_add_flt_rule const *r bool IPACM_Filtering::AddOffloadFilteringRule(struct ipa_ioc_add_flt_rule *flt_rule_tbl, uint8_t mux_id, uint8_t default_path) { #ifdef WAN_IOCTL_ADD_OFFLOAD_CONNECTION - int ret = 0, cnt, pos = 0; + int ret = 0, cnt, pos = 0, i; ipa_add_offload_connection_req_msg_v01 qmi_add_msg; int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR); if(fd_wwan_ioctl < 0) @@ -807,7 +808,23 @@ bool IPACM_Filtering::AddOffloadFilteringRule(struct ipa_ioc_add_flt_rule *flt_r sizeof(struct ipa_filter_rule_type_v01)); IPACMDBG_H("mux-id %d, hashable %d\n", qmi_add_msg.filter_spec_ex2_list[pos].mux_id, qmi_add_msg.filter_spec_ex2_list[pos].is_rule_hashable); pos++; - pcie_modem_rule_id = (pcie_modem_rule_id + 1)%100; + pcie_modem_rule_id_in_use[pcie_modem_rule_id] = true; + for(i = 0; i < IPA_PCIE_MODEM_RULE_ID_MAX; i++) + { + pcie_modem_rule_id = (pcie_modem_rule_id + 1)%IPA_PCIE_MODEM_RULE_ID_MAX; + if(!pcie_modem_rule_id_in_use[pcie_modem_rule_id]) + break; + } + + if(i == IPA_PCIE_MODEM_RULE_ID_MAX) + { + IPACMERR("all handles are in use, max = %d\n", i); + return false; + } + else + { + IPACMDBG("next free pcie_modem_rule_id: %d\n", pcie_modem_rule_id); + } } else { @@ -892,6 +909,12 @@ bool IPACM_Filtering::DelOffloadFilteringRule(struct ipa_ioc_del_flt_rule const /* passing rule-id to wan-driver */ qmi_del_msg.filter_handle_list[pos].filter_spec_identifier = flt_rule_tbl->hdl[cnt].hdl; pos++; + + /* set in use to false for future rule additions (need to subtract offset and mod max index) */ + pcie_modem_rule_id_in_use[(IPA_PCIE_MODEM_RULE_ID_MAX + flt_rule_tbl->hdl[cnt].hdl - IPA_PCIE_MODEM_RULE_ID_START) + % IPA_PCIE_MODEM_RULE_ID_MAX] = false; + IPACMDBG("freeing pcie_modem_rule_id: %d\n", (IPA_PCIE_MODEM_RULE_ID_MAX + flt_rule_tbl->hdl[cnt].hdl -IPA_PCIE_MODEM_RULE_ID_START) + % IPA_PCIE_MODEM_RULE_ID_MAX); } else { -- cgit v1.2.3 From 330317a31a848a32dd52668907acf6055bd02794 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Thu, 6 Aug 2020 12:14:25 -0700 Subject: ipacm: Fix to ignore ENOMSG error from nfct_catch ENOMSG is returned when the conntrack message received has a non zero pid value. Idea is to handle only messages coming from Kernel which has 0 pid value. Change-Id: Ib1934c82595b980016e98646f34797f9001c51ab --- ipacm/src/IPACM_ConntrackClient.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ipacm/src/IPACM_ConntrackClient.cpp b/ipacm/src/IPACM_ConntrackClient.cpp index 24f95a3..dabd8e6 100644 --- a/ipacm/src/IPACM_ConntrackClient.cpp +++ b/ipacm/src/IPACM_ConntrackClient.cpp @@ -493,12 +493,18 @@ void* IPACM_ConntrackClient::TCPRegisterWithConnTrack(void *) blocks waiting for events. */ IPACMDBG("Waiting for events\n"); +ctcatch: ret = nfct_catch(pClient->tcp_hdl); - if(ret == -1) + if((ret == -1) && (errno != ENOMSG)) { - IPACMERR("(%d)(%s)\n", ret, strerror(errno)); + IPACMERR("(%d)(%d)(%s)\n", ret, errno, strerror(errno)); return NULL; } + else + { + IPACMDBG("ctcatch ret:%d, errno:%d\n", ret, errno); + goto ctcatch; + } IPACMDBG("Exit from tcp thread\n"); @@ -579,14 +585,14 @@ void* IPACM_ConntrackClient::UDPRegisterWithConnTrack(void *) /* Block to catch events from net filter connection track */ ctcatch: ret = nfct_catch(pClient->udp_hdl); - if(ret == -1) + if((ret == -1) && (errno != ENOMSG)) { - IPACMDBG("(%d)(%s)\n", ret, strerror(errno)); + IPACMDBG("(%d)(%d)(%s)\n", ret, errno, strerror(errno)); return NULL; } else { - IPACMDBG("ctcatch ret:%d\n", ret); + IPACMDBG("ctcatch ret:%d, errno:%d\n", ret, errno); goto ctcatch; } -- cgit v1.2.3 From 5c5bd6395fe0b7375f1c8869e7f570e1dc2e5ead Mon Sep 17 00:00:00 2001 From: Pooja Kumari Date: Mon, 17 Aug 2020 16:10:46 +0530 Subject: ipacm: using same-process HAL Create same process HAL to avoid double registrations Change-Id: I47fb46b727d0c66006f65a06586c11e4c42c3ea9 --- hal/inc/HAL.h | 2 +- hal/src/HAL.cpp | 4 ++-- ipacm/src/IPACM_Main.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hal/inc/HAL.h b/hal/inc/HAL.h index 894438f..92ec135 100644 --- a/hal/inc/HAL.h +++ b/hal/inc/HAL.h @@ -123,7 +123,7 @@ public: * Yet, a major version update, would not be backwards compatible. This means that a 2.x HAL * could not linked into the same IPACM code base as a 1.x HAL. */ - static HAL* makeIPAHAL(int /* version */, IOffloadManager* /* mgr */); + static Return<::android::sp> makeIPAHAL(int /* version */, IOffloadManager* /* mgr */); /* IOffloadConfig */ Return setHandles( diff --git a/hal/src/HAL.cpp b/hal/src/HAL.cpp index 3f1a41f..f18767a 100644 --- a/hal/src/HAL.cpp +++ b/hal/src/HAL.cpp @@ -62,7 +62,7 @@ using ::std::vector; /* ------------------------------ PUBLIC ------------------------------------ */ -HAL* HAL::makeIPAHAL(int version, IOffloadManager* mgr) { +Return<::android::sp> HAL::makeIPAHAL(int version, IOffloadManager* mgr) { android::hardware::ProcessState::initWithMmapSize((size_t)(2 * KERNEL_PAGE)); if (DBG) @@ -70,7 +70,7 @@ HAL* HAL::makeIPAHAL(int version, IOffloadManager* mgr) { (mgr != nullptr) ? "provided" : "null"); if (nullptr == mgr) return NULL; else if (version != 1) return NULL; - HAL* ret = new HAL(mgr); + ::android::sp ret = new HAL(mgr); if (nullptr == ret) return NULL; configureRpcThreadpool(1, false); ret->registerAsSystemService("ipacm"); diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp index ec5de34..ca75a4a 100644 --- a/ipacm/src/IPACM_Main.cpp +++ b/ipacm/src/IPACM_Main.cpp @@ -121,7 +121,7 @@ int ipa_reset_hw_index_counter(); #ifdef FEATURE_IPACM_HAL IPACM_OffloadManager* OffloadMng; - HAL *hal; + ::android::sp hal; #endif /* start netlink socket monitor*/ -- cgit v1.2.3 From bcdbbcfa0bb1fed621ad997e8e6cfaa2e5f1b50a Mon Sep 17 00:00:00 2001 From: Pooja Kumari Date: Wed, 19 Aug 2020 13:29:26 +0530 Subject: ipacm: delete WAN iface if rx tx property is NULL Delete Wan iface instance if rx tx property of the interface is NULL. Change-Id: Ib0ab2619fd5ae3596558007ab2d44a601fa73093 --- ipacm/src/IPACM_IfaceManager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp index 2857f39..7ba5a80 100644 --- a/ipacm/src/IPACM_IfaceManager.cpp +++ b/ipacm/src/IPACM_IfaceManager.cpp @@ -450,6 +450,12 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param) else { w = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL); + if (w->rx_prop == NULL && w->tx_prop == NULL) + { + /* close the netdev instance if IPA not support*/ + w->delete_iface(); + return IPACM_FAILURE; + } } IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, w); #ifdef FEATURE_IPA_ANDROID -- cgit v1.2.3 From bedd69bf958a927b9ba39739c857ce6c669f4533 Mon Sep 17 00:00:00 2001 From: Armaan Siddiqui Date: Mon, 29 Jun 2020 16:54:27 +0530 Subject: ipacm: Enable ipacm for bengal go LOW Level RAM target Changes done to enable ipacm for bengal go Low Level RAM target. Change-Id: I987b94791eeb1ff94d08221a0ceeec26c55e69e4 --- ipacm_vendor_product.mk | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ipacm_vendor_product.mk b/ipacm_vendor_product.mk index 9fe88b1..5c0fc23 100644 --- a/ipacm_vendor_product.mk +++ b/ipacm_vendor_product.mk @@ -11,8 +11,15 @@ ifneq ($(TARGET_USES_QMAA_OVERRIDE_DATA),true) endif #TARGET_USES_QMAA_OVERRIDE_DATA endif #TARGET_USES_QMAA +BOARD_IPA_LOW_RAM_EXCP_LIST := bengal + +ifeq ($(TARGET_HAS_LOW_RAM),true) +ifneq ($(call is-board-platform-in-list,$(BOARD_IPA_LOW_RAM_EXCP_LIST)),true) + TARGET_DISABLE_IPACM := true +endif +endif + ifneq ($(TARGET_DISABLE_IPACM),true) -ifneq ($(TARGET_HAS_LOW_RAM),true) BOARD_PLATFORM_LIST := msm8909 BOARD_PLATFORM_LIST += msm8916 BOARD_PLATFORM_LIST += msm8917 @@ -40,4 +47,3 @@ endif # $(TARGET_ARCH) endif endif endif -endif \ No newline at end of file -- cgit v1.2.3 From 72332e735e791817d73252b9464a88bfb45a6af8 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Tue, 8 Sep 2020 23:20:38 -0700 Subject: ipacm: Fix reading the conntrack dump Framework uses UDP fd to query for the conntrack dump. Make changes to use UDP fd to read the conntrack dump. Also read using the fd provided from framework and not using dup fd. Change-Id: Iaeecfc0c4763325314d8f763797bd1fc7124e4db --- ipacm/inc/IPACM_ConntrackListener.h | 2 +- ipacm/src/IPACM_ConntrackClient.cpp | 11 ---- ipacm/src/IPACM_ConntrackListener.cpp | 99 ++++++++++++++++++----------------- ipacm/src/IPACM_OffloadManager.cpp | 24 ++++++++- 4 files changed, 75 insertions(+), 61 deletions(-) diff --git a/ipacm/inc/IPACM_ConntrackListener.h b/ipacm/inc/IPACM_ConntrackListener.h index 6cc4188..7831498 100644 --- a/ipacm/inc/IPACM_ConntrackListener.h +++ b/ipacm/inc/IPACM_ConntrackListener.h @@ -119,7 +119,7 @@ public: void HandleSTAClientAddEvt(uint32_t); void HandleSTAClientDelEvt(uint32_t); int CreateConnTrackThreads(void); - void readConntrack(void); + void readConntrack(int fd); void processConntrack(void); }; diff --git a/ipacm/src/IPACM_ConntrackClient.cpp b/ipacm/src/IPACM_ConntrackClient.cpp index dabd8e6..f6bc9a6 100644 --- a/ipacm/src/IPACM_ConntrackClient.cpp +++ b/ipacm/src/IPACM_ConntrackClient.cpp @@ -421,17 +421,6 @@ 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/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp index baddb4d..9d06442 100644 --- a/ipacm/src/IPACM_ConntrackListener.cpp +++ b/ipacm/src/IPACM_ConntrackListener.cpp @@ -1219,25 +1219,26 @@ bool isLocalHostAddr(uint32_t src_ip_addr, uint32_t dst_ip_addr) { return false; } -void IPACM_ConntrackListener::readConntrack() { +void IPACM_ConntrackListener::readConntrack(int fd) { - IPACM_ConntrackClient *pClient; - int len_fil = 0, recv_bytes = -1, index = 0, len =0; + int 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 + struct iovec iov = { + .iov_base = buffer, + .iov_len = CT_ENTRIES_BUFFER_SIZE, + }; + struct sockaddr_nl addr; + struct msghdr msg = { + .msg_name = &addr, + .msg_namelen = sizeof(struct sockaddr_nl), + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = NULL, + .msg_controllen = 0, + .msg_flags = 0, }; - unsigned int addr_len = sizeof(nlAddr); - - pClient = IPACM_ConntrackClient::GetInstance(); - if(pClient == NULL) - { - IPACMERR("unable to get conntrack client instance\n"); - return; - } len = MAX_CONNTRACK_ENTRIES * sizeof(struct nf_conntrack **); @@ -1249,17 +1250,18 @@ void IPACM_ConntrackListener::readConntrack() { } memset(ct_entries, 0, len); - if( pClient->fd_tcp < 0) + if( fd < 0) { - IPACMDBG_H("Invalid fd %d \n",pClient->fd_tcp); + IPACMDBG_H("Invalid fd %d \n",fd); free(ct_entries); return; } - IPACMDBG_H("receiving conntrack entries started.\n"); - while(len_fil < sizeof(buffer) && index < MAX_CONNTRACK_ENTRIES) + len = CT_ENTRIES_BUFFER_SIZE; + while (len > 0) { - recv_bytes = recvfrom( pClient->fd_tcp, buf, sizeof(buffer)-len_fil, 0, (struct sockaddr *)&nlAddr, (socklen_t *)&addr_len); + memset(buffer, 0, CT_ENTRIES_BUFFER_SIZE); + recv_bytes = recvmsg(fd, &msg, 0); if(recv_bytes < 0) { IPACMDBG_H("error in receiving conntrack entries %d%s",errno, strerror(errno)); @@ -1267,42 +1269,45 @@ void IPACM_ConntrackListener::readConntrack() { } else { - nl_header = (struct nlmsghdr *)buf; - - if (NLMSG_OK(nl_header, recv_bytes) == 0 || nl_header->nlmsg_type == NLMSG_ERROR) + len -= recv_bytes; + nl_header = (struct nlmsghdr *)buffer; + IPACMDBG_H("Number of bytes:%d to parse\n", recv_bytes); + while(NLMSG_OK(nl_header, recv_bytes) && (index < MAX_CONNTRACK_ENTRIES)) { - 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) + if (nl_header->nlmsg_type == NLMSG_ERROR) + { + IPACMDBG_H("Error, recv_bytes is %d\n",recv_bytes); + break; + } + ct = nfct_new(); + if (ct != NULL) { - ct_entries[index++] = ct; + 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("error in parsing %d%s \n", errno, strerror(errno)); + IPACMDBG_H("ct allocation failed"); } + if (nl_header->nlmsg_type == NLMSG_DONE) + { + IPACMDBG_H("Message is done.\n"); + break; + } + nl_header = NLMSG_NEXT(nl_header, recv_bytes); } - 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"); + IPACMDBG_H("receiving conntrack entries ended. No of entries: %d\n", index); if(isWanUp() && !isProcessCTDone) { IPACMDBG_H("wan is up, process ct entries \n"); @@ -1324,7 +1329,7 @@ void IPACM_ConntrackListener::processConntrack() { 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), + if((AF_INET == 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"); @@ -1372,6 +1377,6 @@ IGNORE: } isProcessCTDone = true; free(ct_entries); - IPACMDBG_H("process conntrack ended \n"); + IPACMDBG_H("process conntrack ended. Number of entries:%d \n", index); return; } diff --git a/ipacm/src/IPACM_OffloadManager.cpp b/ipacm/src/IPACM_OffloadManager.cpp index 7919413..b5afda7 100644 --- a/ipacm/src/IPACM_OffloadManager.cpp +++ b/ipacm/src/IPACM_OffloadManager.cpp @@ -120,6 +120,7 @@ RET IPACM_OffloadManager::unregisterCtTimeoutUpdater(ConntrackTimeoutUpdater* ) RET IPACM_OffloadManager::provideFd(int fd, unsigned int groups) { + struct timeval tv; IPACM_ConntrackClient *cc; int on = 1, rel; struct sockaddr_nl local; @@ -158,11 +159,30 @@ RET IPACM_OffloadManager::provideFd(int fd, unsigned int groups) cc->fd_udp = dup(fd); IPACMDBG_H("Received fd %d with groups %d.\n", fd, groups); /* set netlink buf */ - rel = setsockopt(cc->fd_tcp, SOL_NETLINK, NETLINK_NO_ENOBUFS, &on, sizeof(int) ); + rel = setsockopt(cc->fd_udp, SOL_NETLINK, NETLINK_NO_ENOBUFS, &on, sizeof(int) ); if (rel == -1) { - IPACMERR( "setsockopt returned error code %d ( %s )", errno, strerror( errno ) ); + IPACMERR("setsockopt returned error code %d ( %s )\n", errno, strerror(errno)); } + + /* Set receive timeout to 1s on the FD which is used to read conntrack dump. */ + memset(&tv,0, sizeof(struct timeval)); + tv.tv_sec = 1; /* 1s timeout */ + rel = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval)); + if (rel == -1) + { + IPACMERR("setsockopt returned error code %d ( %s )\n", errno, strerror(errno)); + } + + /* 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. + */ + CtList->readConntrack(fd); } else { IPACMERR("Received unexpected fd with groups %d.\n", groups); } -- cgit v1.2.3 From bc042aca9d3b816e34a825fdc8b3281be0610146 Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Thu, 17 Sep 2020 13:41:55 -0700 Subject: ipacm: Fix MTU rule modify and add Reset the rt table handle every time we modify a new rule. Add brackets to if else conditions that were always getting hit. Change-Id: Iebca2ee3cdf4713285e6bedc151e428fd99d2f5c Signed-off-by: Michael Adisumarta --- ipacm/src/IPACM_Lan.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp index 0a532fd..65bd3ca 100644 --- a/ipacm/src/IPACM_Lan.cpp +++ b/ipacm/src/IPACM_Lan.cpp @@ -4205,9 +4205,14 @@ int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype) mtu[i] = IPACM_Wan::queryMTU(ipa_if_num, IPA_IP_v4); if (mtu[i] > 0) + { mtu_rule_cnt++; + IPACMDBG_H("MTU[%d] is %d\n", i, mtu[i]); + } else - IPACMERR("MTU is zero\n"); + { + IPACMERR("MTU is 0"); + } } IPACMDBG_H("total %d MTU rules are needed\n", mtu_rule_cnt); @@ -4237,16 +4242,16 @@ int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype) flt_rule.rule.retain_hdr = 1; flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_ROUTING; - flt_rule.rule.eq_attrib_type = 0; - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl; IPACMDBG_H("Private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name); for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++) { /* add private subnet rule for ipv4 */ + /* these 3 properties below will be reset during construct_mtu_rule */ flt_rule.rule.action = IPA_PASS_TO_ROUTING; flt_rule.rule.eq_attrib_type = 0; + flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl; + flt_rule.rule_hdl = private_fl_rule_hdl[i]; memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; @@ -4264,7 +4269,9 @@ int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype) flt_rule.rule.attrib.u.v4.src_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr; flt_rule.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR; if (construct_mtu_rule(&flt_rule.rule, IPA_IP_v4, mtu[i])) + { IPACMERR("Failed to modify MTU filtering rule.\n"); + } memcpy(&(pFilteringTable->rules[mtu_rule_idx + i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); IPACMDBG_H("Adding MTU rule for private subnet 0x%x.\n", flt_rule.rule.attrib.u.v4.src_addr); } @@ -4302,7 +4309,14 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) uint16_t mtu = IPACM_Wan::queryMTU(ipa_if_num, IPA_IP_v6); if (mtu > 0) + { + IPACMDBG_H("MTU is %d\n", mtu); rule_cnt ++; + } + else + { + IPACMERR("MTU is 0"); + } if(rx_prop != NULL) { -- cgit v1.2.3 From c307e93baf3021307a331f436dc8517542d204ae Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Fri, 24 Apr 2020 17:51:07 -0700 Subject: ipacm: Print flt rules that fail mdfy_flt_rule Move the individual flt rule status check outside the IOCTl fail check to seperate the rules that failed when IPACM sends more than one rule. Change-Id: I4a2c51374bbedced687e23041104a1bc33627c55 Signed-off-by: Michael Adisumarta --- ipacm/src/IPACM_Filtering.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ipacm/src/IPACM_Filtering.cpp b/ipacm/src/IPACM_Filtering.cpp index b230c36..875a794 100644 --- a/ipacm/src/IPACM_Filtering.cpp +++ b/ipacm/src/IPACM_Filtering.cpp @@ -1006,17 +1006,18 @@ bool IPACM_Filtering::ModifyFilteringRule(struct ipa_ioc_mdfy_flt_rule* ruleTabl } ret = ioctl(fd, IPA_IOC_MDFY_FLT_RULE, ruleTable); - if (ret != 0) - { - IPACMERR("Failed modifying filtering rule %pK\n", ruleTable); - for (i = 0; i < ruleTable->num_rules; i++) + for (i = 0; i < ruleTable->num_rules; i++) + { + if (ruleTable->rules[i].status != 0) { - if (ruleTable->rules[i].status != 0) - { - IPACMERR("Modifying filter rule %d failed\n", i); - } + IPACMERR("Modifying filter rule %d failed\n", i); } + } + + if (ret != 0) + { + IPACMERR("Failed modifying filtering rule IOCTL for %pK\n", ruleTable); return false; } -- cgit v1.2.3 From e0ad041f1575b9ff77ebc2ac85e21a8a9084e868 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Sun, 20 Sep 2020 11:26:23 -0700 Subject: ipacm: add mechanism to cache ct events 1) Current logic is to get the conntrack dump first time when tethering is enabled. 2) Once we have the conntrack handles, add mechanism to cache CT events when upstream is not set. 3) Also make changes to reset the socket receive timeout to 0 so that nfct_catch doesn't return EAGAIN. And add check to retry when we receive EILSEQ. Change-Id: I37877c19f11abd3fdb9f7f6c96933a592e6a1490 --- ipacm/inc/IPACM_ConntrackListener.h | 15 ++- ipacm/src/IPACM_ConntrackClient.cpp | 3 +- ipacm/src/IPACM_ConntrackListener.cpp | 171 +++++++++++++++++++++++++++++----- ipacm/src/IPACM_OffloadManager.cpp | 27 ++++-- 4 files changed, 178 insertions(+), 38 deletions(-) diff --git a/ipacm/inc/IPACM_ConntrackListener.h b/ipacm/inc/IPACM_ConntrackListener.h index 7831498..2977af7 100644 --- a/ipacm/inc/IPACM_ConntrackListener.h +++ b/ipacm/inc/IPACM_ConntrackListener.h @@ -61,6 +61,13 @@ typedef struct _nat_entry_bundle }nat_entry_bundle; +typedef struct _ct_entry +{ + struct nf_conntrack *ct; + u_int8_t protocol; + enum nf_conntrack_msg_type type; +}ct_entry; + class IPACM_ConntrackListener : public IPACM_Listener { @@ -78,13 +85,14 @@ 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; + ct_entry *ct_entries; + ct_entry ct_cache[MAX_CONNTRACK_ENTRIES]; #ifdef CT_OPT IPACM_LanToLan *p_lan2lan; #endif void ProcessCTMessage(void *); - void ProcessTCPorUDPMsg(struct nf_conntrack *, + bool ProcessTCPorUDPMsg(struct nf_conntrack *, enum nf_conntrack_msg_type, u_int8_t); void TriggerWANUp(void *); void TriggerWANDown(uint32_t); @@ -121,6 +129,9 @@ public: int CreateConnTrackThreads(void); void readConntrack(int fd); void processConntrack(void); + void CacheORDeleteConntrack(struct nf_conntrack *ct, + enum nf_conntrack_msg_type type, u_int8_t protocol); + void processCacheConntrack(void); }; extern IPACM_ConntrackListener *CtList; diff --git a/ipacm/src/IPACM_ConntrackClient.cpp b/ipacm/src/IPACM_ConntrackClient.cpp index f6bc9a6..29afd50 100644 --- a/ipacm/src/IPACM_ConntrackClient.cpp +++ b/ipacm/src/IPACM_ConntrackClient.cpp @@ -574,7 +574,8 @@ void* IPACM_ConntrackClient::UDPRegisterWithConnTrack(void *) /* Block to catch events from net filter connection track */ ctcatch: ret = nfct_catch(pClient->udp_hdl); - if((ret == -1) && (errno != ENOMSG)) + /* Due to conntrack dump, sequence number might mismatch for initial events. */ + if((ret == -1) && (errno != ENOMSG) && (errno != EILSEQ)) { IPACMDBG("(%d)(%d)(%s)\n", ret, errno, strerror(errno)); return NULL; diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp index 9d06442..b991324 100644 --- a/ipacm/src/IPACM_ConntrackListener.cpp +++ b/ipacm/src/IPACM_ConntrackListener.cpp @@ -40,7 +40,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. IPACM_ConntrackListener::IPACM_ConntrackListener() { IPACMDBG("\n"); - isNatThreadStart = false; isCTReg = false; WanUp = false; @@ -70,6 +69,9 @@ IPACM_ConntrackListener::IPACM_ConntrackListener() #ifdef CT_OPT p_lan2lan = IPACM_LanToLan::getLan2LanInstance(); #endif + + /* Initialize the CT cache. */ + memset(ct_cache, 0, sizeof(ct_cache)); } void IPACM_ConntrackListener::event_callback(ipa_cm_event_id evt, @@ -105,6 +107,8 @@ void IPACM_ConntrackListener::event_callback(ipa_cm_event_id evt, { processConntrack(); } + /* Process the cached entries. */ + processCacheConntrack(); break; case IPA_HANDLE_WAN_DOWN: @@ -675,6 +679,7 @@ void IPACM_ConntrackListener::ProcessCTMessage(void *param) { ipacm_ct_evt_data *evt_data = (ipacm_ct_evt_data *)param; u_int8_t l4proto = 0; + bool cache_ct = false; #ifdef IPACM_DEBUG char buf[1024]; @@ -696,11 +701,14 @@ void IPACM_ConntrackListener::ProcessCTMessage(void *param) } else { - ProcessTCPorUDPMsg(evt_data->ct, evt_data->type, l4proto); + cache_ct = ProcessTCPorUDPMsg(evt_data->ct, evt_data->type, l4proto); } /* Cleanup item that was allocated during the original CT callback */ - nfct_destroy(evt_data->ct); + if (!cache_ct) + nfct_destroy(evt_data->ct); + else + CacheORDeleteConntrack(evt_data->ct, evt_data->type, l4proto); return; } @@ -847,7 +855,7 @@ void IPACM_ConntrackListener::AddORDeleteNatEntry(const nat_entry_bundle *input) } else if (IPPROTO_UDP == input->rule->protocol) { - if (NFCT_T_NEW == input->type) + if (NFCT_T_NEW == input->type || NFCT_T_UPDATE == input->type) { IPACMDBG("New UDP connection at time %ld\n", time(NULL)); if (!CtList->isWanUp()) @@ -1037,7 +1045,7 @@ void IPACM_ConntrackListener::CheckSTAClient( } /* conntrack send in host order and ipa expects in host order */ -void IPACM_ConntrackListener::ProcessTCPorUDPMsg( +bool IPACM_ConntrackListener::ProcessTCPorUDPMsg( struct nf_conntrack *ct, enum nf_conntrack_msg_type type, u_int8_t l4proto) @@ -1046,6 +1054,7 @@ void IPACM_ConntrackListener::ProcessTCPorUDPMsg( uint32_t status = 0; uint32_t orig_src_ip, orig_dst_ip; bool isAdd = false; + bool cache_ct = false; nat_entry_bundle nat_entry; nat_entry.isTempEntry = false; @@ -1075,7 +1084,7 @@ void IPACM_ConntrackListener::ProcessTCPorUDPMsg( if(orig_src_ip == 0) { IPACMERR("unable to retrieve orig src ip address\n"); - return; + return cache_ct; } orig_dst_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST); @@ -1083,7 +1092,7 @@ void IPACM_ConntrackListener::ProcessTCPorUDPMsg( if(orig_dst_ip == 0) { IPACMERR("unable to retrieve orig dst ip address\n"); - return; + return cache_ct; } if(orig_src_ip == wan_ipaddr) @@ -1104,8 +1113,11 @@ void IPACM_ConntrackListener::ProcessTCPorUDPMsg( #ifdef CT_OPT HandleLan2Lan(ct, type, &rule); #endif - IPACMDBG("Neither source Nor destination nat\n"); - goto IGNORE; + IPACMDBG("Neither source Nor destination nat.\n"); + /* If WAN is not up, cache the event. */ + if(!CtList->isWanUp()) + cache_ct = true; + goto IGNORE; } } @@ -1137,7 +1149,7 @@ void IPACM_ConntrackListener::ProcessTCPorUDPMsg( CheckSTAClient(&rule, &nat_entry.isTempEntry); nat_entry.rule = &rule; AddORDeleteNatEntry(&nat_entry); - return; + return cache_ct; IGNORE: IPACMDBG_H("ignoring below Nat Entry\n"); @@ -1147,7 +1159,7 @@ IGNORE: 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; + return cache_ct; } void IPACM_ConntrackListener::HandleSTAClientAddEvt(uint32_t clnt_ip_addr) @@ -1240,9 +1252,9 @@ void IPACM_ConntrackListener::readConntrack(int fd) { .msg_flags = 0, }; - len = MAX_CONNTRACK_ENTRIES * sizeof(struct nf_conntrack **); + len = MAX_CONNTRACK_ENTRIES * sizeof(ct_entry); - ct_entries = (struct nf_conntrack **) malloc(len); + ct_entries = (ct_entry *) malloc(len); if(ct_entries == NULL) { IPACMERR("unable to allocate ct_entries memory \n"); @@ -1264,7 +1276,7 @@ void IPACM_ConntrackListener::readConntrack(int fd) { recv_bytes = recvmsg(fd, &msg, 0); if(recv_bytes < 0) { - IPACMDBG_H("error in receiving conntrack entries %d%s",errno, strerror(errno)); + IPACMDBG_H("error in receiving conntrack entries %d%s\n",errno, strerror(errno)); break; } else @@ -1283,18 +1295,20 @@ void IPACM_ConntrackListener::readConntrack(int fd) { if (ct != NULL) { int parseResult = nfct_parse_conntrack((nf_conntrack_msg_type) NFCT_T_ALL,nl_header, ct); - if(parseResult != NFCT_T_ERROR) + if(parseResult != NFCT_T_ERROR && parseResult != 0) { - ct_entries[index++] = ct; + ct_entries[index].ct = ct; + ct_entries[index++].type = (nf_conntrack_msg_type)parseResult; } else { IPACMDBG_H("error in parsing %d%s \n", errno, strerror(errno)); + nfct_destroy(ct); } } else { - IPACMDBG_H("ct allocation failed"); + IPACMDBG_H("ct allocation failed\n"); } if (nl_header->nlmsg_type == NLMSG_DONE) { @@ -1322,15 +1336,14 @@ 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) + while(ct_entries[index].ct != NULL) { - ip_type = nfct_get_attr_u8(ct_entries[index], ATTR_REPL_L3PROTO); - if((AF_INET == 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))) + ip_type = nfct_get_attr_u8(ct_entries[index].ct, ATTR_REPL_L3PROTO); + if((AF_INET == ip_type) && isLocalHostAddr(nfct_get_attr_u32(ct_entries[index].ct, ATTR_ORIG_IPV4_SRC), + nfct_get_attr_u32(ct_entries[index].ct, ATTR_ORIG_IPV4_DST))) { IPACMDBG_H(" loopback entry \n"); goto IGNORE; @@ -1351,8 +1364,8 @@ void IPACM_ConntrackListener::processConntrack() { goto IGNORE; } - ct_data->ct = ct_entries[index]; - ct_data->type = type; + ct_data->ct = ct_entries[index].ct; + ct_data->type = ct_entries[index].type; #ifdef CT_OPT if(AF_INET6 == ip_type) @@ -1366,7 +1379,7 @@ void IPACM_ConntrackListener::processConntrack() { free(ct_data); continue; IGNORE: - nfct_destroy(ct_entries[index]); + nfct_destroy(ct_entries[index].ct); index++; } } @@ -1377,6 +1390,114 @@ IGNORE: } isProcessCTDone = true; free(ct_entries); + ct_entries = NULL; IPACMDBG_H("process conntrack ended. Number of entries:%d \n", index); return; } + +void IPACM_ConntrackListener::CacheORDeleteConntrack +( + struct nf_conntrack *ct, + enum nf_conntrack_msg_type type, + u_int8_t protocol +) +{ + u_int8_t tcp_state; + int i = 0, free_idx = -1; + + IPACMDBG("CT entry, type (%d), protocol(%d)\n", type, protocol); + /* Check for duplicate entry and in parallel find first free index. */ + for(; i < MAX_CONNTRACK_ENTRIES; i++) + { + if (ct_cache[i].ct != NULL) + { + if (nfct_cmp(ct_cache[i].ct, ct, NFCT_CMP_ORIG | NFCT_CMP_REPL)) + { + /* Duplicate entry. */ + IPACMDBG("Duplicate CT entry, type (%d), protocol(%d)\n", + type, protocol); + break; + } + } + else if ((ct_cache[i].ct == NULL) && (free_idx == -1)) + { + /* Cache the first free index. */ + free_idx = i; + } + } + + /* Duplicate entry handling. */ + if (i < MAX_CONNTRACK_ENTRIES) + { + if (IPPROTO_TCP == protocol) + { + tcp_state = nfct_get_attr_u8(ct, ATTR_TCP_STATE); + if (TCP_CONNTRACK_FIN_WAIT == tcp_state || type == NFCT_T_DESTROY) + { + IPACMDBG("TCP state TCP_CONNTRACK_FIN_WAIT(%d) " + "or type NFCT_T_DESTROY\n", tcp_state); + nfct_destroy(ct_cache[i].ct); + nfct_destroy(ct); + memset(&ct_cache[i], 0, sizeof(ct_cache[i])); + return ; + } + } + if ((IPPROTO_UDP == protocol) && (type == NFCT_T_DESTROY)) + { + IPACMDBG("UDP type NFCT_T_DESTROY\n"); + nfct_destroy(ct_cache[i].ct); + nfct_destroy(ct); + memset(&ct_cache[i], 0, sizeof(ct_cache[i])); + return; + } + } + else if ((i == MAX_CONNTRACK_ENTRIES) && + (type != NFCT_T_DESTROY) && (free_idx != -1)) + { + if (IPPROTO_TCP == protocol) + { + tcp_state = nfct_get_attr_u8(ct, ATTR_TCP_STATE); + if (TCP_CONNTRACK_ESTABLISHED == tcp_state) + { + IPACMDBG("TCP state TCP_CONNTRACK_ESTABLISHED\n"); + /* Cache the entry. */ + ct_cache[free_idx].ct = ct; + ct_cache[free_idx].protocol = protocol; + ct_cache[free_idx].type = type; + return; + } + } + if (IPPROTO_UDP == protocol) + { + if (NFCT_T_NEW == type) + { + IPACMDBG("New UDP connection\n"); + /* Cache the entry. */ + ct_cache[free_idx].ct = ct; + ct_cache[free_idx].protocol = protocol; + ct_cache[free_idx].type = type; + return; + } + } + } + /* In all other cases, free the conntracy entry. */ + nfct_destroy(ct); + return ; +} +void IPACM_ConntrackListener::processCacheConntrack(void) +{ + int i = 0; + + IPACMDBG("Entry:\n"); + for(; i < MAX_CONNTRACK_ENTRIES; i++) + { + if (ct_cache[i].ct != NULL) + { + ProcessTCPorUDPMsg(ct_cache[i].ct, ct_cache[i].type, ct_cache[i].protocol); + nfct_destroy(ct_cache[i].ct); + memset(&ct_cache[i], 0, sizeof(ct_cache[i])); + } + } + IPACMDBG("Exit:\n"); +} + diff --git a/ipacm/src/IPACM_OffloadManager.cpp b/ipacm/src/IPACM_OffloadManager.cpp index b5afda7..708725b 100644 --- a/ipacm/src/IPACM_OffloadManager.cpp +++ b/ipacm/src/IPACM_OffloadManager.cpp @@ -122,7 +122,7 @@ RET IPACM_OffloadManager::provideFd(int fd, unsigned int groups) { struct timeval tv; IPACM_ConntrackClient *cc; - int on = 1, rel; + int on = 1, rel = 0; struct sockaddr_nl local; unsigned int addr_len; @@ -156,15 +156,6 @@ RET IPACM_OffloadManager::provideFd(int fd, unsigned int groups) IPACMERR( "setsockopt returned error code %d ( %s )", errno, strerror( errno ) ); } } else if (groups == cc->subscrips_udp) { - cc->fd_udp = dup(fd); - IPACMDBG_H("Received fd %d with groups %d.\n", fd, groups); - /* set netlink buf */ - rel = setsockopt(cc->fd_udp, SOL_NETLINK, NETLINK_NO_ENOBUFS, &on, sizeof(int) ); - if (rel == -1) - { - IPACMERR("setsockopt returned error code %d ( %s )\n", errno, strerror(errno)); - } - /* Set receive timeout to 1s on the FD which is used to read conntrack dump. */ memset(&tv,0, sizeof(struct timeval)); tv.tv_sec = 1; /* 1s timeout */ @@ -183,6 +174,22 @@ RET IPACM_OffloadManager::provideFd(int fd, unsigned int groups) for both TCP/UDP embedded traffic. */ CtList->readConntrack(fd); + /* Reset receive timeout on the FD which is used to read conntrack dump. */ + memset(&tv,0, sizeof(struct timeval)); + rel = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&tv,sizeof(struct timeval)); + if (rel == -1) + { + IPACMERR("setsockopt returned error code %d ( %s )\n", errno, strerror(errno)); + } + + cc->fd_udp = dup(fd); + IPACMDBG_H("Received fd %d with groups %d.\n", fd, groups); + /* set netlink buf */ + rel = setsockopt(cc->fd_udp, SOL_NETLINK, NETLINK_NO_ENOBUFS, &on, sizeof(int) ); + if (rel == -1) + { + IPACMERR("setsockopt returned error code %d ( %s )\n", errno, strerror(errno)); + } } else { IPACMERR("Received unexpected fd with groups %d.\n", groups); } -- cgit v1.2.3 From c40430c299f4694692553132086854b03eba3e52 Mon Sep 17 00:00:00 2001 From: Pooja Kumari Date: Thu, 24 Sep 2020 20:05:32 +0530 Subject: ipacm: increment num_tethered_client properly in case of XLAT Currently in case of XLAT if ADD_DOWNSTREAM event comes before XLAT_CONNECT event then num_offload_v4_tethered_iface is not incremented and it will have incorrect value. Increment num_offload_v4_tethered_iface var if XLAT comes after downstream is up. Change-Id: I79814a526b1112d7004fa1959a519475c02fe834 --- ipacm/src/IPACM_Lan.cpp | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp index 65bd3ca..7e7e875 100644 --- a/ipacm/src/IPACM_Lan.cpp +++ b/ipacm/src/IPACM_Lan.cpp @@ -751,25 +751,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n"); -#ifdef FEATURE_IPA_ANDROID - if (IPACM_Wan::isXlat() && (data->prefix.iptype == IPA_IP_v4)) - { - /* indicate v4-offload */ - IPACM_OffloadManager::num_offload_v4_tethered_iface++; - IPACMDBG_H("in xlat: update num_offload_v4_tethered_iface %d\n", IPACM_OffloadManager::num_offload_v4_tethered_iface); - - /* xlat not support for 2st tethered iface */ - if (IPACM_OffloadManager::num_offload_v4_tethered_iface > 1) - { - IPACMDBG_H("Not support 2st downstream iface %s for xlat, cur: %d\n", dev_name, - IPACM_OffloadManager::num_offload_v4_tethered_iface); - return; - } - } - IPACMDBG_H(" support downstream iface %s, cur %d\n", dev_name, - IPACM_OffloadManager::num_offload_v4_tethered_iface); -#endif if (data->prefix.iptype < IPA_IP_MAX && is_downstream_set[data->prefix.iptype] == false) { IPACMDBG_H("Add downstream for IP iptype %d\n", data->prefix.iptype); @@ -1905,6 +1887,25 @@ int IPACM_Lan::handle_wan_up_ex(ipacm_ext_prop *ext_prop, ipa_ip_type iptype, ui ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id); modem_ul_v6_set = true; } else if (iptype ==IPA_IP_v4 && modem_ul_v4_set == false) { +#ifdef FEATURE_IPA_ANDROID + if (IPACM_Wan::isXlat()) + { + /* indicate v4-offload */ + IPACM_OffloadManager::num_offload_v4_tethered_iface++; + IPACMDBG_H("in xlat: update num_offload_v4_tethered_iface %d\n", IPACM_OffloadManager::num_offload_v4_tethered_iface); + + /* xlat not support for 2st tethered iface */ + if (IPACM_OffloadManager::num_offload_v4_tethered_iface > 1) + { + IPACMDBG_H("Not support 2st downstream iface %s for xlat, cur: %d\n", dev_name, + IPACM_OffloadManager::num_offload_v4_tethered_iface); + return IPACM_FAILURE; + } + } + + IPACMDBG_H(" support downstream iface %s, cur %d\n", dev_name, + IPACM_OffloadManager::num_offload_v4_tethered_iface); +#endif /* add MTU rules for ipv4 */ handle_private_subnet_android(IPA_IP_v4); -- cgit v1.2.3 From 50b9701ad29f45ae0f49a189f58972e41cdbd1af Mon Sep 17 00:00:00 2001 From: Pooja Kumari Date: Wed, 30 Sep 2020 16:17:26 +0530 Subject: ipacm: disable IPACM on msm8937 target Disable ipacm on msm8937 target as IPA hw is not present. Change-Id: I2477f9b976798a9c91e37e14e122f0e411546b8a --- ipacm_vendor_product.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/ipacm_vendor_product.mk b/ipacm_vendor_product.mk index 5c0fc23..f225a30 100644 --- a/ipacm_vendor_product.mk +++ b/ipacm_vendor_product.mk @@ -24,6 +24,7 @@ BOARD_PLATFORM_LIST := msm8909 BOARD_PLATFORM_LIST += msm8916 BOARD_PLATFORM_LIST += msm8917 BOARD_PLATFORM_LIST += qm215 +BOARD_PLATFORM_LIST += msm8937 BOARD_IPAv3_LIST := msm8998 BOARD_IPAv3_LIST += sdm845 BOARD_IPAv3_LIST += sdm710 -- cgit v1.2.3 From 1f373aa0fe7e0313d6d41726f85f820d1a72849e Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Thu, 6 Aug 2020 08:12:53 -0700 Subject: ipacm: Fix to add dummy NAT entries for tunneled connections When tunneling is enabled from the device, same NAT entry will be translate from Public to tunneled IP and then to Private IP. In case we try to add the entry to HW, HW ends up translating it to Private IP and connection fails. Make change to add dummy NAT entries for tunneled connections. Change-Id: I340189e2a0db71dd04316a704116e045d6622063 --- ipacm/src/IPACM_ConntrackListener.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp index b991324..fd1566d 100644 --- a/ipacm/src/IPACM_ConntrackListener.cpp +++ b/ipacm/src/IPACM_ConntrackListener.cpp @@ -888,6 +888,8 @@ void IPACM_ConntrackListener::PopulateTCPorUDPEntry( uint32_t status, nat_table_entry *rule) { + uint32_t repl_dst_ip; + if (IPS_DST_NAT == status) { IPACMDBG("Destination NAT\n"); @@ -972,6 +974,15 @@ void IPACM_ConntrackListener::PopulateTCPorUDPEntry( { IPACMDBG("unable to retrieve private port\n"); } + + /* If Reply destination IP is not Public IP, install dummy NAT rule. */ + repl_dst_ip = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST); + repl_dst_ip = ntohl(repl_dst_ip); + if(repl_dst_ip != rule->public_ip) + { + IPACMDBG_H("Reply dst IP:0x%x not equal to wan ip:0x%x\n",repl_dst_ip, rule->public_ip); + rule->private_ip = rule->public_ip; + } } return; @@ -1121,8 +1132,8 @@ bool IPACM_ConntrackListener::ProcessTCPorUDPMsg( } } - PopulateTCPorUDPEntry(ct, status, &rule); rule.public_ip = wan_ipaddr; + PopulateTCPorUDPEntry(ct, status, &rule); if (rule.private_ip != wan_ipaddr) { -- cgit v1.2.3 From a9392c9662a8aa140770b95f2c343c2bb791e8d2 Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Fri, 30 Oct 2020 17:05:37 -0700 Subject: ipacm: add dynamic support for IPA new MTU events Handle new MTU events to replace modem PDN MTU for WANv4/v6 and replace the MTU rules if they are already installed. Change-Id: I06c16db2300ccd572a99ab316d413fcbf9197986 Signed-off-by: Michael Adisumarta --- ipacm/inc/IPACM_Defs.h | 11 ++ ipacm/inc/IPACM_Lan.h | 2 + ipacm/inc/IPACM_Wan.h | 21 +++- ipacm/src/IPACM_Iface.cpp | 2 +- ipacm/src/IPACM_IfaceManager.cpp | 9 ++ ipacm/src/IPACM_Lan.cpp | 162 ++++++++++++++++++++++++--- ipacm/src/IPACM_Main.cpp | 30 +++++ ipacm/src/IPACM_Wan.cpp | 231 ++++++++++++++++++++++++++++++--------- ipacm/src/IPACM_Wlan.cpp | 29 +++++ 9 files changed, 422 insertions(+), 75 deletions(-) diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h index e60516e..82e9c6b 100644 --- a/ipacm/inc/IPACM_Defs.h +++ b/ipacm/inc/IPACM_Defs.h @@ -193,6 +193,10 @@ typedef enum IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, /* ipacm_event_eth_bridge*/ IPA_SSR_NOTICE, /* NULL*/ IPA_COALESCE_NOTICE, /* NULL*/ +#ifdef IPA_MTU_EVENT_MAX + IPA_MTU_SET, /* ipa_mtu_info */ + IPA_MTU_UPDATE, /* ipacm_event_mtu_info */ +#endif #ifdef FEATURE_L2TP IPA_ADD_VLAN_IFACE, /* ipa_ioc_vlan_iface_info */ IPA_DEL_VLAN_IFACE, /* ipa_ioc_vlan_iface_info */ @@ -407,4 +411,11 @@ typedef struct { _ipacm_offload_prefix prefix; } ipacm_event_ipahal_stream; +#ifdef IPA_MTU_EVENT_MAX +typedef struct _ipacm_event_mtu_info +{ + int if_index; + ipa_mtu_info mtu_info; +} ipacm_event_mtu_info; +#endif #endif /* IPA_CM_DEFS_H */ diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h index 605edb5..de64be1 100644 --- a/ipacm/inc/IPACM_Lan.h +++ b/ipacm/inc/IPACM_Lan.h @@ -230,6 +230,8 @@ protected: int reset_to_dummy_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl); + virtual int modify_ipv6_prefix_flt_rule(uint32_t* prefix); + virtual int install_ipv6_prefix_flt_rule(uint32_t* prefix); virtual void delete_ipv6_prefix_flt_rule(); diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h index ad62783..eecf039 100644 --- a/ipacm/inc/IPACM_Wan.h +++ b/ipacm/inc/IPACM_Wan.h @@ -105,8 +105,10 @@ public: static bool wan_up; static bool wan_up_v6; static uint8_t xlat_mux_id; - static uint16_t mtu_default_wan; - uint16_t mtu_size; + + static uint16_t mtu_default_wan_v4; + static uint16_t mtu_default_wan_v6; + /* IPACM interface name */ static char wan_up_dev_name[IF_NAME_LEN]; static uint32_t curr_wan_ip; @@ -145,15 +147,14 @@ public: { if (isWanUP(ipa_if_num_tether)) { - return mtu_default_wan; + return mtu_default_wan_v4; } } else if (iptype == IPA_IP_v6) { if (isWanUP_V6(ipa_if_num_tether)) { - return mtu_default_wan; - + return mtu_default_wan_v6; } } return DEFAULT_MTU_SIZE; @@ -405,6 +406,14 @@ private: /* handle for TCP RST rule */ uint32_t tcp_rst_hdl; + /* V4 MTU value. */ + uint16_t mtu_v4; + bool mtu_v4_set; + + /* V6 MTU value. */ + uint16_t mtu_v6; + bool mtu_v6_set; + inline ipa_wan_client* get_client_memptr(ipa_wan_client *param, int cnt) { char *ret = ((char *)param) + (wan_client_len * cnt); @@ -674,7 +683,7 @@ private: int delete_tcp_fin_rst_exception_rule(); - /* Query mtu size */ + /* MTU helper functions */ int query_mtu_size(); }; diff --git a/ipacm/src/IPACM_Iface.cpp b/ipacm/src/IPACM_Iface.cpp index 8282915..55cf71d 100644 --- a/ipacm/src/IPACM_Iface.cpp +++ b/ipacm/src/IPACM_Iface.cpp @@ -1009,7 +1009,7 @@ fail: return res; } -/* get ipa interface name */ +/* get ipa interface index from name */ int IPACM_Iface::ipa_get_if_index ( char * if_name, diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp index 7ba5a80..1392a1a 100644 --- a/ipacm/src/IPACM_IfaceManager.cpp +++ b/ipacm/src/IPACM_IfaceManager.cpp @@ -291,6 +291,9 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param) IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, lan); #endif IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, lan); +#ifdef IPA_MTU_EVENT_MAX + IPACM_EvtDispatcher::registr(IPA_MTU_UPDATE, lan); +#endif IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, lan); /* IPA_LAN_DELETE_SELF should be always last */ IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, lan); @@ -420,6 +423,9 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param) IPACM_EvtDispatcher::registr(IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE, wl); #endif IPACM_EvtDispatcher::registr(IPA_WIGIG_CLIENT_ADD_EVENT, wl); +#ifdef IPA_MTU_EVENT_MAX + IPACM_EvtDispatcher::registr(IPA_MTU_UPDATE, wl); +#endif /* IPA_LAN_DELETE_SELF should be always last */ IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, wl); IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance open/registr ok\n", wl->dev_name, wl->ipa_if_num); @@ -464,6 +470,9 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param) if(is_sta_mode == Q6_WAN) { IPACM_EvtDispatcher::registr(IPA_NETWORK_STATS_UPDATE_EVENT, w); +#ifdef IPA_MTU_EVENT_MAX + IPACM_EvtDispatcher::registr(IPA_MTU_SET, w); +#endif }; #else/* defined(FEATURE_IPA_ANDROID) */ IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, w); diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp index 7e7e875..a6b2b90 100644 --- a/ipacm/src/IPACM_Lan.cpp +++ b/ipacm/src/IPACM_Lan.cpp @@ -1110,6 +1110,36 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) } break; +#ifdef IPA_MTU_EVENT_MAX + case IPA_MTU_UPDATE: + { + IPACMDBG_H("Received IPA_MTU_UPDATE"); + ipacm_event_mtu_info *evt_data = (ipacm_event_mtu_info *)param; + ipa_mtu_info *data = &(evt_data->mtu_info); + + /* IPA_IP_MAX means both ipv4 and ipv6 */ + if ((data->ip_type == IPA_IP_v4 || data->ip_type == IPA_IP_MAX) && IPACM_Wan::isWanUP(ipa_if_num)) + { + handle_private_subnet_android(IPA_IP_v4); + } + + /* IPA_IP_MAX means both ipv4 and ipv6 */ + if ((data->ip_type == IPA_IP_v6 || data->ip_type == IPA_IP_MAX) && IPACM_Wan::isWanUP_V6(ipa_if_num)) + { + /* check if the prefix + MTU rules are installed */ + if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1]) + { + modify_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); + } + else + { + IPACMERR("Failed to update prefix MTU rules, no prefix rules set"); + } + } + } + break; +#endif + default: break; } @@ -1641,9 +1671,9 @@ int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type) /* Update ipv6 MTU here if WAN_v6 is up and filter rules were installed */ if (IPACM_Wan::isWanUP_V6(ipa_if_num)) { - if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1] ) { - delete_ipv6_prefix_flt_rule(); - install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); + if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1]) + { + modify_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); } } @@ -1912,9 +1942,9 @@ int IPACM_Lan::handle_wan_up_ex(ipacm_ext_prop *ext_prop, ipa_ip_type iptype, ui /* Update ipv6 MTU here if WAN_v6 is up and filter rules were installed */ if (IPACM_Wan::isWanUP_V6(ipa_if_num)) { - if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1] ) { - delete_ipv6_prefix_flt_rule(); - install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); + if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1]) + { + modify_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); } } @@ -4293,8 +4323,13 @@ fail: return res; } -int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) +int IPACM_Lan::modify_ipv6_prefix_flt_rule(uint32_t* prefix) { + int len, res = IPACM_SUCCESS; + struct ipa_flt_rule_mdfy flt_rule_entry; + struct ipa_ioc_mdfy_flt_rule* flt_rule; + int rule_cnt = 1; + if(prefix == NULL) { IPACMERR("IPv6 prefix is empty.\n"); @@ -4302,12 +4337,114 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) } IPACMDBG_H("Receive IPv6 prefix: 0x%08x%08x.\n", prefix[0], prefix[1]); + uint16_t mtu = IPACM_Wan::queryMTU(ipa_if_num, IPA_IP_v6); + if (mtu > 0) + { + IPACMDBG_H("MTU is %d\n", mtu); + rule_cnt ++; + } + else + { + IPACMERR("MTU is 0"); + } + + + if(rx_prop == NULL) + { + IPACMERR("no rx props\n"); + return IPACM_FAILURE; + } + + len = sizeof(struct ipa_ioc_mdfy_flt_rule) + rule_cnt * sizeof(struct ipa_flt_rule_mdfy); + flt_rule = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); + if(!flt_rule) + { + IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); + return IPACM_FAILURE; + } + memset(flt_rule, 0, len); + + flt_rule->commit = 1; + flt_rule->ip = IPA_IP_v6; + flt_rule->num_rules = rule_cnt; + + memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_mdfy)); + flt_rule_entry.status = -1; + flt_rule_entry.rule.retain_hdr = 1; + flt_rule_entry.rule.to_uc = 0; + flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; + flt_rule_entry.rule.eq_attrib_type = 0; + flt_rule_entry.rule_hdl = ipv6_prefix_flt_rule_hdl[0]; + + memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); + flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; + flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = prefix[0]; + flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = prefix[1]; + flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x0; + flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x0; + flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; + flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; + flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x0; + flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x0; + memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_mdfy)); + + + flt_rule_entry.rule_hdl = ipv6_prefix_flt_rule_hdl[1]; + memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); // this will remove the IPA_FLT_DST_ADDR + flt_rule_entry.rule.attrib.u.v6.src_addr[3] = prefix[0]; + flt_rule_entry.rule.attrib.u.v6.src_addr[2] = prefix[1]; + flt_rule_entry.rule.attrib.u.v6.src_addr[1] = 0x0; + flt_rule_entry.rule.attrib.u.v6.src_addr[0] = 0x0; + flt_rule_entry.rule.attrib.u.v6.src_addr_mask[3] = 0xFFFFFFFF; + flt_rule_entry.rule.attrib.u.v6.src_addr_mask[2] = 0xFFFFFFFF; + flt_rule_entry.rule.attrib.u.v6.src_addr_mask[1] = 0x0; + flt_rule_entry.rule.attrib.u.v6.src_addr_mask[0] = 0x0; + flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR; + + /* Add an MTU rule with every new private prefix */ + if (mtu > 0) + { + if (construct_mtu_rule(&flt_rule_entry.rule, IPA_IP_v6, mtu)) + { + IPACMERR("Failed to add MTU filtering rule.\n") + } + else + { + memcpy(&(flt_rule->rules[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_mdfy)); + } + } + + + if(false == m_filtering.ModifyFilteringRule(flt_rule)) + { + IPACMERR("Failed to modify prefix filtering rules.\n"); + res = IPACM_FAILURE; + goto fail; + } + +fail: + if(flt_rule != NULL) + { + free(flt_rule); + } + return res; +} + +int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) +{ int len; struct ipa_ioc_add_flt_rule* flt_rule; struct ipa_flt_rule_add flt_rule_entry; bool result; int rule_cnt = 1; + if(prefix == NULL) + { + IPACMERR("IPv6 prefix is empty.\n"); + return IPACM_FAILURE; + } + IPACMDBG_H("Receive IPv6 prefix: 0x%08x%08x.\n", prefix[0], prefix[1]); + uint16_t mtu = IPACM_Wan::queryMTU(ipa_if_num, IPA_IP_v6); if (mtu > 0) { @@ -4383,18 +4520,7 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) } } -#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO - /* use index hw-counter */ - if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support) - { - IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL); - result = m_filtering.AddFilteringRule_hw_index(flt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL); - } else { - result = m_filtering.AddFilteringRule(flt_rule); - } -#else result = m_filtering.AddFilteringRule(flt_rule); -#endif if (result == false) { diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp index ca75a4a..6bd117e 100644 --- a/ipacm/src/IPACM_Main.cpp +++ b/ipacm/src/IPACM_Main.cpp @@ -270,6 +270,10 @@ void* ipa_driver_msg_notifier(void *param) #endif ipacm_cmd_q_data new_neigh_evt; ipacm_event_data_all* new_neigh_data; +#ifdef IPA_MTU_EVENT_MAX + ipacm_event_mtu_info *mtu_event = NULL; + ipa_mtu_info *mtu_info; +#endif param = NULL; fd = open(IPA_DRIVER, O_RDWR); @@ -874,6 +878,32 @@ void* ipa_driver_msg_notifier(void *param) break; #endif +#ifdef IPA_MTU_EVENT_MAX + case IPA_SET_MTU: + mtu_event = (ipacm_event_mtu_info *)malloc(sizeof(*mtu_event)); + if(mtu_event == NULL) + { + IPACMERR("Failed to allocate memory.\n"); + return NULL; + } + mtu_info = &(mtu_event->mtu_info); + memcpy(mtu_info, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_mtu_info)); + IPACMDBG_H("Received IPA_SET_MTU if_name %s ip_type %d mtu_v4 %d mtu_v6 %d\n", + mtu_info->if_name, mtu_info->ip_type, mtu_info->mtu_v4, mtu_info->mtu_v6); + if (mtu_info->ip_type > IPA_IP_MAX) + { + IPACMERR("ip_type (%d) beyond the Max range (%d), abort\n", + mtu_info->ip_type, IPA_IP_MAX); + return NULL; + } + + ipa_get_if_index(mtu_info->if_name, &(mtu_event->if_index)); + + evt_data.event = IPA_MTU_SET; + evt_data.evt_data = mtu_event; + break; +#endif + default: IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type); continue; diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp index 397c820..ad174c4 100644 --- a/ipacm/src/IPACM_Wan.cpp +++ b/ipacm/src/IPACM_Wan.cpp @@ -92,7 +92,8 @@ int IPACM_Wan::ipa_if_num_tether_v4[IPA_MAX_IFACE_ENTRIES]; int IPACM_Wan::ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES]; #endif -uint16_t IPACM_Wan::mtu_default_wan = DEFAULT_MTU_SIZE; +uint16_t IPACM_Wan::mtu_default_wan_v4 = DEFAULT_MTU_SIZE; +uint16_t IPACM_Wan::mtu_default_wan_v6 = DEFAULT_MTU_SIZE; IPACM_Wan::IPACM_Wan(int iface_index, ipacm_wan_iface_type is_sta_mode, @@ -132,7 +133,11 @@ IPACM_Wan::IPACM_Wan(int iface_index, ext_prop = NULL; is_ipv6_frag_firewall_flt_rule_installed = false; ipv6_frag_firewall_flt_rule_hdl = 0; - mtu_size = DEFAULT_MTU_SIZE; + + mtu_v4 = DEFAULT_MTU_SIZE; + mtu_v4_set = false; + mtu_v6 = DEFAULT_MTU_SIZE; + mtu_v6_set = false; num_wan_client = 0; header_name_count = 0; @@ -146,6 +151,53 @@ IPACM_Wan::IPACM_Wan(int iface_index, wan_client_len = 0; m_is_sta_mode = is_sta_mode; +#ifdef IPA_MTU_EVENT_MAX + /* Query WAN MTU to handle IPACM restart scenarios. */ + if(is_sta_mode == Q6_WAN) + { + int fd_wwan_ioctl; + ipa_mtu_info *mtu_info = (ipa_mtu_info *)malloc(sizeof(ipa_mtu_info)); + if (mtu_info) + { + memset(mtu_info, 0, sizeof(ipa_mtu_info)); + memcpy(mtu_info->if_name, dev_name, IPA_IFACE_NAME_LEN); + fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR); + if(fd_wwan_ioctl < 0) + { + IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME); + } + else + { + IPACMDBG_H("send WAN_IOC_GET_WAN_MTU for %s\n", mtu_info->if_name); + if(ioctl(fd_wwan_ioctl, WAN_IOC_GET_WAN_MTU, mtu_info)) + { + IPACMERR("Failed to send WAN_IOC_GET_WAN_MTU\n "); + } + else + { + /* Updated MTU values.*/ + if (mtu_info->mtu_v4) + { + mtu_v4 = mtu_info->mtu_v4; + mtu_v4_set = true; + IPACMDBG_H("Updated v4 mtu=[%d] for (%s)\n", + mtu_v4, mtu_info->if_name); + } + if (mtu_info->mtu_v6) + { + mtu_v6 = mtu_info->mtu_v6; + mtu_v6_set = true; + IPACMDBG_H("Updated v6 mtu=[%d] for (%s)\n", + mtu_v6, mtu_info->if_name); + } + } + close(fd_wwan_ioctl); + } + free(mtu_info); + } + } +#endif + if(iface_query != NULL) { IPACMDBG_H("index:%d constructor: Tx properties:%d\n", iface_index, iface_query->num_tx_props); @@ -1112,6 +1164,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) } } break; + case IPA_LINK_DOWN_EVENT: { ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; @@ -1721,54 +1774,117 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) } break; - case IPA_WLAN_SWITCH_TO_SCC: - if(IPACM_Wan::backhaul_mode == WLAN_WAN) + case IPA_WLAN_SWITCH_TO_SCC: + if(IPACM_Wan::backhaul_mode == WLAN_WAN) + { + IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_SCC\n"); + if(ip_type == IPA_IP_MAX) { - IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_SCC\n"); - if(ip_type == IPA_IP_MAX) - { - handle_wlan_SCC_MCC_switch(true, IPA_IP_v4); - handle_wlan_SCC_MCC_switch(true, IPA_IP_v6); - handle_wan_client_SCC_MCC_switch(true, IPA_IP_v4); - handle_wan_client_SCC_MCC_switch(true, IPA_IP_v6); - } - else - { - handle_wlan_SCC_MCC_switch(true, ip_type); - handle_wan_client_SCC_MCC_switch(true, ip_type); - } + handle_wlan_SCC_MCC_switch(true, IPA_IP_v4); + handle_wlan_SCC_MCC_switch(true, IPA_IP_v6); + handle_wan_client_SCC_MCC_switch(true, IPA_IP_v4); + handle_wan_client_SCC_MCC_switch(true, IPA_IP_v6); } - break; + else + { + handle_wlan_SCC_MCC_switch(true, ip_type); + handle_wan_client_SCC_MCC_switch(true, ip_type); + } + } + break; + + case IPA_WLAN_SWITCH_TO_MCC: + if(IPACM_Wan::backhaul_mode == WLAN_WAN) + { + IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_MCC\n"); + if(ip_type == IPA_IP_MAX) + { + handle_wlan_SCC_MCC_switch(false, IPA_IP_v4); + handle_wlan_SCC_MCC_switch(false, IPA_IP_v6); + handle_wan_client_SCC_MCC_switch(false, IPA_IP_v4); + handle_wan_client_SCC_MCC_switch(false, IPA_IP_v6); + } + else + { + handle_wlan_SCC_MCC_switch(false, ip_type); + handle_wan_client_SCC_MCC_switch(false, ip_type); + } + } + break; +#ifdef FEATURE_IPACM_HAL + /* WA for WLAN to clean up NAT instance during SSR */ + case IPA_SSR_NOTICE: + case IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE: + { + IPACMDBG_H("Received IPA_SSR_NOTICE event.\n"); + if(m_is_sta_mode == WLAN_WAN) + { + IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface + } + } + break; +#endif +#ifdef IPA_MTU_EVENT_MAX + case IPA_MTU_SET: + { + ipacm_event_mtu_info *data = (ipacm_event_mtu_info *)param; + ipa_mtu_info *mtu_info = &(data->mtu_info); + ipa_interface_index = iface_ipa_index_query(data->if_index); - case IPA_WLAN_SWITCH_TO_MCC: - if(IPACM_Wan::backhaul_mode == WLAN_WAN) + if (ipa_interface_index == ipa_if_num) + { + IPACMDBG_H("Received IPA_MTU_SET (Android) for interface (%d)\n", + ipa_interface_index); + if (mtu_info->ip_type == IPA_IP_v4 || mtu_info->ip_type == IPA_IP_MAX) { - IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_MCC\n"); - if(ip_type == IPA_IP_MAX) + /* Update v4_mtu. */ + mtu_v4 = mtu_info->mtu_v4; + mtu_v4_set = true; + + if (active_v4) { - handle_wlan_SCC_MCC_switch(false, IPA_IP_v4); - handle_wlan_SCC_MCC_switch(false, IPA_IP_v6); - handle_wan_client_SCC_MCC_switch(false, IPA_IP_v4); - handle_wan_client_SCC_MCC_switch(false, IPA_IP_v6); + /* upstream interface. update default MTU. */ + mtu_default_wan_v4 = mtu_v4; } - else + IPACMDBG_H("Updated v4 mtu=[%d] for (%s), upstream_mtu=[%d]\n", + mtu_v4, mtu_info->if_name, mtu_default_wan_v4); + } + if (mtu_info->ip_type == IPA_IP_v6 || mtu_info->ip_type == IPA_IP_MAX) + { + /* Update v4_mtu. */ + mtu_v6 = mtu_info->mtu_v6; + mtu_v6_set = true; + if (active_v6) { - handle_wlan_SCC_MCC_switch(false, ip_type); - handle_wan_client_SCC_MCC_switch(false, ip_type); + /* upstream interface. update default MTU. */ + mtu_default_wan_v6 = mtu_v6; } + IPACMDBG_H("Updated v6 mtu=[%d] for (%s), upstream_mtu=[%d]\n", + mtu_v6, mtu_info->if_name, mtu_default_wan_v6); } - break; -#ifdef FEATURE_IPACM_HAL - /* WA for WLAN to clean up NAT instance during SSR */ - case IPA_SSR_NOTICE: - case IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE: - IPACMDBG_H("Received IPA_SSR_NOTICE event.\n"); - if(m_is_sta_mode == WLAN_WAN) + + if (active_v4 || active_v6) { - IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface + ipacm_event_mtu_info *mtu_event; + ipacm_cmd_q_data evt_data; + mtu_event = (ipacm_event_mtu_info *)malloc(sizeof(*mtu_event)); + if(mtu_event == NULL) + { + IPACMERR("Failed to allocate memory.\n"); + return; + } + memcpy(&mtu_event->mtu_info, mtu_info, sizeof(ipa_mtu_info)); + evt_data.event = IPA_MTU_UPDATE; + evt_data.evt_data = mtu_event; + /* finish command queue */ + IPACMDBG_H("Posting IPA_MTU_UPDATE event\n"); + IPACM_EvtDispatcher::PostEvt(&evt_data); } - break; + } + } + break; #endif + default: break; } @@ -1779,7 +1895,6 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) /* wan default route/filter rule configuration */ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) { - /* add default WAN route */ struct ipa_ioc_add_rt_rule *rt_rule = NULL; struct ipa_rt_rule_add *rt_rule_entry; @@ -1817,8 +1932,14 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) } IPACMDBG_H("backhaul_is_wan_bridge ?: %d \n", IPACM_Wan::backhaul_is_wan_bridge); - /* query MTU size of the interface */ - query_mtu_size(); + /* query MTU size of the interface if MTU is not set via ioctl. */ + if (!mtu_v4_set && !mtu_v6_set) + { + if(query_mtu_size()) + { + IPACMERR("Failed to query mtu"); + } + } if (m_is_sta_mode ==Q6_WAN) { @@ -2104,11 +2225,6 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) wan_route_rule_v6_hdl_a5[0], 0, iptype); } - /* set mtu_default_wan to current default wan instance */ - mtu_default_wan = mtu_size; - - IPACMDBG_H("replace the mtu_default_wan to %d\n", mtu_default_wan); - ipacm_event_iface_up *wanup_data; wanup_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up)); if (wanup_data == NULL) @@ -2122,6 +2238,10 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) /* handling filter rule construction */ if (iptype == IPA_IP_v4) { + /* set mtu_default_wan to current default wan instance */ + mtu_default_wan_v4 = mtu_v4; + IPACMDBG_H("replace the mtu_wan to %d\n", mtu_default_wan_v4); + IPACM_Wan::wan_up = true; active_v4 = true; memcpy(IPACM_Wan::wan_up_dev_name, @@ -2181,6 +2301,10 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) } else { + /* set mtu_default_wan to current default wan instance */ + mtu_default_wan_v6 = mtu_v6; + IPACMDBG_H("replace the mtu_wan to %d\n", mtu_default_wan_v6); + memcpy(backhaul_ipv6_prefix, ipv6_prefix, sizeof(backhaul_ipv6_prefix)); IPACMDBG_H("Setup backhaul ipv6 prefix to be 0x%08x%08x.\n", backhaul_ipv6_prefix[0], backhaul_ipv6_prefix[1]); @@ -5453,8 +5577,13 @@ int IPACM_Wan::handle_down_evt_ex() goto fail; } +#ifndef IPA_MTU_EVENT_MAX /* reset the mtu size */ - mtu_size = DEFAULT_MTU_SIZE; + mtu_v4 = DEFAULT_MTU_SIZE; + mtu_v4_set = false; + mtu_v6 = DEFAULT_MTU_SIZE; + mtu_v6_set = false; +#endif if(ip_type == IPA_IP_v4) { @@ -7828,10 +7957,12 @@ int IPACM_Wan::query_mtu_size() return IPACM_FAILURE; } IPACMDBG_H("mtu=[%d]\n", if_mtu.ifr_mtu); - if (if_mtu.ifr_mtu < DEFAULT_MTU_SIZE) { - mtu_size = if_mtu.ifr_mtu; - IPACMDBG_H("replaced mtu=[%d] for (%s)\n", mtu_size, dev_name); + if (if_mtu.ifr_mtu <= DEFAULT_MTU_SIZE) { + mtu_v4 = mtu_v6 = if_mtu.ifr_mtu; + }else { + mtu_v4 = mtu_v6 = DEFAULT_MTU_SIZE; } + IPACMDBG_H("Updated mtu=[%d] for (%s)\n", mtu_v4, dev_name); close(fd); return IPACM_SUCCESS; diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp index 689cc78..460b6c0 100644 --- a/ipacm/src/IPACM_Wlan.cpp +++ b/ipacm/src/IPACM_Wlan.cpp @@ -651,6 +651,35 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) } break; } +#ifdef IPA_MTU_EVENT_MAX + case IPA_MTU_UPDATE: + { + IPACMDBG_H("Received IPA_MTU_UPDATE"); + ipacm_event_mtu_info *evt_data = (ipacm_event_mtu_info *)param; + ipa_mtu_info *data = &(evt_data->mtu_info); + + /* IPA_IP_MAX means both ipv4 and ipv6 */ + if ((data->ip_type == IPA_IP_v4 || data->ip_type == IPA_IP_MAX) && IPACM_Wan::isWanUP(ipa_if_num)) + { + handle_private_subnet_android(IPA_IP_v4); + } + + /* IPA_IP_MAX means both ipv4 and ipv6 */ + if ((data->ip_type == IPA_IP_v6 || data->ip_type == IPA_IP_MAX) && IPACM_Wan::isWanUP_V6(ipa_if_num)) + { + //check if the prefix + MTU rules are installed + if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1]) { + modify_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); + } + else + { + IPACMERR("failed to update prefix MTU rules, no prefix rules set"); + } + } + } + break; +#endif + #else case IPA_HANDLE_WAN_UP: IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n"); -- cgit v1.2.3 From e523e357563fd8bb369e264d8422eadebf614af5 Mon Sep 17 00:00:00 2001 From: Skylar Chang Date: Tue, 17 Mar 2020 16:31:58 -0700 Subject: ipacm: fix the rt rule blowup issue For backhaul keeping down and up, seeing v4/v6 routing rules are not cleam up and resulted in routing tbl blow-up in ipa-hw. Made the fix to clean up routing rules accordingly. Change-Id: Iadbb0841d7f1d0eb9944e029b79a04cb4503a496 --- ipacm/src/IPACM_Wan.cpp | 89 +++++++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 55 deletions(-) diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp index ad174c4..8ad4836 100644 --- a/ipacm/src/IPACM_Wan.cpp +++ b/ipacm/src/IPACM_Wan.cpp @@ -5276,17 +5276,6 @@ int IPACM_Wan::handle_down_evt() handle_route_del_evt(IPA_IP_v4); IPACMDBG_H("Delete default v4 routing rules\n"); - if(m_is_sta_mode == Q6_MHI_WAN) - { - /* Delete default v4 RT rule */ - IPACMDBG_H("Delete default v4 routing rules\n"); - if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false) - { - IPACMERR("Routing v6-lan-RT rule deletion failed!\n"); - res = IPACM_FAILURE; - goto fail; - } - } #ifdef FEATURE_IPA_ANDROID /* posting wan_down_tether for lan clients */ @@ -5318,18 +5307,6 @@ int IPACM_Wan::handle_down_evt() handle_route_del_evt(IPA_IP_v6); IPACMDBG_H("Delete default v6 routing rules\n"); - if(m_is_sta_mode == Q6_MHI_WAN) - { - /* Delete default v6 RT rule */ - IPACMDBG_H("Delete default v6 routing rules\n"); - if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[1], IPA_IP_v6) == false) - { - IPACMERR("Routing v6-wan-RT rule deletion failed!\n"); - res = IPACM_FAILURE; - goto fail; - } - } - #ifdef FEATURE_IPA_ANDROID /* posting wan_down_tether for lan clients */ #ifdef FEATURE_IPACM_HAL @@ -5351,37 +5328,51 @@ int IPACM_Wan::handle_down_evt() #endif } - if(m_is_sta_mode != Q6_MHI_WAN) + /* Delete default v4 RT rule */ + if (ip_type != IPA_IP_v6 && wan_v4_addr_set) { - /* Delete default v4 RT rule */ - if (ip_type != IPA_IP_v6) + /* no need delete v4 RSC routing rules */ + IPACMDBG_H("Delete default v4 routing rules\n"); + if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false) + { + IPACMERR("Routing rule deletion failed!\n"); + res = IPACM_FAILURE; + goto fail; + } + } + + /* delete default v6 RT rule */ + if (ip_type != IPA_IP_v4) + { + IPACMDBG_H("Delete default v6 routing rules\n"); + /* May have multiple ipv6 iface-routing rules*/ + for (i = 0; i < 2*num_dft_rt_v6; i++) { - /* no need delete v4 RSC routing rules */ - IPACMDBG_H("Delete default v4 routing rules\n"); - if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false) + if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false) { IPACMERR("Routing rule deletion failed!\n"); res = IPACM_FAILURE; goto fail; } } + IPACMDBG_H("finished delete default v6 RT rules\n "); + } - /* delete default v6 RT rule */ - if (ip_type != IPA_IP_v4) + /* check software routing fl rule hdl */ + if (softwarerouting_act == true) + { + if(m_is_sta_mode == Q6_MHI_WAN) { - IPACMDBG_H("Delete default v6 routing rules\n"); - /* May have multiple ipv6 iface-routing rules*/ - for (i = 0; i < 2*num_dft_rt_v6; i++) - { - if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false) - { - IPACMERR("Routing rule deletion failed!\n"); - res = IPACM_FAILURE; - goto fail; - } - } - IPACMDBG_H("finished delete default v6 RT rules\n "); + handle_software_routing_disable(true); + } + else + { + handle_software_routing_disable(false); } + } + + if(m_is_sta_mode != Q6_MHI_WAN) + { /* clean wan-client header, routing rules */ IPACMDBG_H("left %d wan clients need to be deleted \n ", num_wan_client); for (i = 0; i < num_wan_client; i++) @@ -5430,18 +5421,6 @@ int IPACM_Wan::handle_down_evt() /* free the edm clients cache */ IPACMDBG_H("Free wan clients cache\n"); - /* check software routing fl rule hdl */ - if (softwarerouting_act == true) - { - if(m_is_sta_mode == Q6_MHI_WAN) - { - handle_software_routing_disable(true); - } - else - { - handle_software_routing_disable(false); - } - } /* free dft ipv4 filter rule handlers if any */ if (ip_type != IPA_IP_v6 && rx_prop != NULL) { -- cgit v1.2.3 From b00e17bb739d04a9f0792da5d4c6c1e154703ab3 Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Wed, 4 Nov 2020 23:34:05 -0800 Subject: ipacm: support the mac renew with same IPv4 Add the support on IPACM to clean up old header routing rules associated with old mac after new_neighbor comign from kernel and re-construct header/routing rules for WIFI STA scenario. Change-Id: I8fa08dedbeb3127d8974529ecb82dc7c0ea0d54a --- ipacm/inc/IPACM_Wan.h | 11 +- ipacm/src/IPACM_Wan.cpp | 324 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 261 insertions(+), 74 deletions(-) diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h index eecf039..a73ec98 100644 --- a/ipacm/inc/IPACM_Wan.h +++ b/ipacm/inc/IPACM_Wan.h @@ -592,10 +592,13 @@ private: return IPACM_SUCCESS; } - int handle_wan_hdr_init(uint8_t *mac_addr); + int handle_wan_hdr_init(uint8_t *mac_addr, bool replaced = false, int entry = 0); int handle_wan_client_ipaddr(ipacm_event_data_all *data); int handle_wan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype); + /* handle_gw_mac_renew, index_client valiud is success */ + int handle_gw_mac_renew(ipacm_event_data_all *data, int index_client); + /* handle new_address event */ int handle_addr_evt(ipacm_event_data_addr *data); @@ -603,10 +606,10 @@ private: int handle_addr_evt_mhi_q6(ipacm_event_data_addr *data); /* wan default route/filter rule configuration */ - int handle_route_add_evt(ipa_ip_type iptype); + int handle_route_add_evt(ipa_ip_type iptype, bool add_only = false); /* construct complete STA ethernet header */ - int handle_sta_header_add_evt(); + int handle_sta_header_add_evt(bool renew = false); bool check_dft_firewall_rules_attr_mask(IPACM_firewall_conf_t *firewall_config); @@ -621,7 +624,7 @@ private: /* configure the initial firewall filter rules */ int config_dft_embms_rules(ipa_ioc_add_flt_rule *pFilteringTable_v4, ipa_ioc_add_flt_rule *pFilteringTable_v6); - int handle_route_del_evt(ipa_ip_type iptype); + int handle_route_del_evt(ipa_ip_type iptype, bool delete_only = false); int del_dft_firewall_rules(ipa_ip_type iptype); diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp index ad174c4..de2854f 100644 --- a/ipacm/src/IPACM_Wan.cpp +++ b/ipacm/src/IPACM_Wan.cpp @@ -862,7 +862,7 @@ int IPACM_Wan::handle_addr_evt_mhi_q6(ipacm_event_data_addr *data) IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING for ip-family %d \n", dev_name, IPA_IP_v6); IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_v6); } - /* skylar setup v6-wan-tbl */ + /* setup v6-wan-tbl */ rt_rule = (struct ipa_ioc_add_rt_rule *) calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + NUM_RULES * sizeof(struct ipa_rt_rule_add)); @@ -1628,6 +1628,8 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) { ipacm_event_data_all *data = (ipacm_event_data_all *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); + int index = 0; + bool renew = false; if (ipa_interface_index == ipa_if_num) { @@ -1659,6 +1661,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) } IPACMDBG_H("wan-iface got client \n"); + /* first construc WAN-client full header */ if(memcmp(data->mac_addr, invalid_mac, @@ -1670,7 +1673,20 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) return; } - handle_wan_hdr_init(data->mac_addr); + /* check if same as GW_ip need replacing */ + if( handle_gw_mac_renew(data, index) == IPACM_SUCCESS) + { + renew = true; + IPACMDBG_H("Renew is happening with client-index (%d)\n", index); + /* clinet renew procedure */ + handle_wan_hdr_init(data->mac_addr, true, index); + } + else + { + IPACMDBG_H("Renew is no need!\n"); + handle_wan_hdr_init(data->mac_addr); + } + IPACMDBG_H("construct wan-client header and route rules \n"); /* Associate with IP and construct RT-rule */ if (handle_wan_client_ipaddr(data) == IPACM_FAILURE) @@ -1679,7 +1695,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) } handle_wan_client_route_rule(data->mac_addr, data->iptype); /* Check & construct STA header */ - handle_sta_header_add_evt(); + handle_sta_header_add_evt(renew); return; } } @@ -1893,7 +1909,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) } /* wan default route/filter rule configuration */ -int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) +int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype, bool add_only) { /* add default WAN route */ struct ipa_ioc_add_rt_rule *rt_rule = NULL; @@ -2225,6 +2241,17 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) wan_route_rule_v6_hdl_a5[0], 0, iptype); } + /* support delete only, not post wan_down event */ + if (add_only) + { + IPACMDBG_H(" Only add default WAN routing rules (%d)\n", add_only); + if(rt_rule != NULL) + { + free(rt_rule); + } + return IPACM_SUCCESS; + } + ipacm_event_iface_up *wanup_data; wanup_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up)); if (wanup_data == NULL) @@ -2495,7 +2522,7 @@ int IPACM_Wan::post_wan_down_tether_evt(ipa_ip_type iptype, int ipa_if_num_tethe #endif /* construct complete ethernet header */ -int IPACM_Wan::handle_sta_header_add_evt() +int IPACM_Wan::handle_sta_header_add_evt(bool renew) { int res = IPACM_SUCCESS, index = IPACM_INVALID_INDEX; if((header_set_v4 == true) || (header_set_v6 == true)) @@ -2552,7 +2579,13 @@ int IPACM_Wan::handle_sta_header_add_evt() } } - /* checking if the ipv4 same as default route */ + /* see if v4 default routes are setup before constructing full header */ + if(header_partial_default_wan_v4 == true) + { + handle_route_add_evt(IPA_IP_v4, renew); + } + + /* checking if the ipv6 same as default route */ if(wan_v6_addr_gw_set) { index = get_wan_client_index_ipv6(wan_v6_addr_gw); @@ -2600,15 +2633,11 @@ int IPACM_Wan::handle_sta_header_add_evt() } } - /* see if default routes are setup before constructing full header */ - if(header_partial_default_wan_v4 == true) - { - handle_route_add_evt(IPA_IP_v4); - } + /* see if v6 default routes are setup before constructing full header */ if(header_partial_default_wan_v6 == true) { - handle_route_add_evt(IPA_IP_v6); + handle_route_add_evt(IPA_IP_v6, renew); } return res; } @@ -4796,7 +4825,7 @@ int IPACM_Wan::del_dft_firewall_rules(ipa_ip_type iptype) } /* for STA mode: wan default route/filter rule delete */ -int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype) +int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype, bool delete_only) { uint32_t tx_index; ipacm_cmd_q_data evt_data; @@ -4820,42 +4849,42 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype) if (((iptype == IPA_IP_v4) && (active_v4 == true)) || ((iptype == IPA_IP_v6) && (active_v6 == true))) { - if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0) - { - /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */ - IPACMDBG_H("dev %s delete producer dependency\n", dev_name); - IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); - IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); - } - else + if (!delete_only) { - /* change wan_state for Q6_MHI */ -#ifdef WAN_IOC_NOTIFY_WAN_STATE - IPACMDBG_H("ipa_pm_q6_check to %d\n", ipa_pm_q6_check); - if(ipa_pm_q6_check == 1 && m_is_sta_mode == Q6_MHI_WAN) + if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0) { - fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR); - if(fd_wwan_ioctl < 0) + /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */ + IPACMDBG_H("dev %s delete producer dependency\n", dev_name); + IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); + IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); + } + else + { + /* change wan_state for Q6_MHI */ +#ifdef WAN_IOC_NOTIFY_WAN_STATE + IPACMDBG_H("ipa_pm_q6_check to %d\n", ipa_pm_q6_check); + if(ipa_pm_q6_check == 1 && m_is_sta_mode == Q6_MHI_WAN) { - IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME); - return false; + fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR); + if(fd_wwan_ioctl < 0) + { + IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME); + return false; + } + IPACMDBG_H("send WAN_IOC_NOTIFY_WAN_STATE down to IPA_PM\n"); + if(ioctl(fd_wwan_ioctl, WAN_IOC_NOTIFY_WAN_STATE, &wan_state)) + { + IPACMERR("Failed to send WAN_IOC_NOTIFY_WAN_STATE as up %d\n ", wan_state.up); + } + close(fd_wwan_ioctl); } - IPACMDBG_H("send WAN_IOC_NOTIFY_WAN_STATE down to IPA_PM\n"); -#ifdef WAN_IOCTL_NOTIFY_WAN_INTF_NAME - strlcpy(wan_state.upstreamIface, dev_name, IFNAMSIZ); + if (ipa_pm_q6_check > 0) + ipa_pm_q6_check--; + else + IPACMERR(" ipa_pm_q6_check becomes negative !!!\n"); #endif - if(ioctl(fd_wwan_ioctl, WAN_IOC_NOTIFY_WAN_STATE, &wan_state)) - { - IPACMERR("Failed to send WAN_IOC_NOTIFY_WAN_STATE as up %d\n ", wan_state.up); - } - close(fd_wwan_ioctl); } - if (ipa_pm_q6_check > 0) - ipa_pm_q6_check--; - else - IPACMERR(" ipa_pm_q6_check becomes negative !!!\n"); -#endif - } + } // end of delete_only for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) { @@ -4898,6 +4927,14 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype) return IPACM_FAILURE; } } + + /* support delete only, not post wan_down event */ + if(delete_only) + { + IPACMDBG_H(" Only delete default WAN routing rules (%d)\n", delete_only); + return IPACM_SUCCESS; + } + ipacm_event_iface_up *wandown_data; wandown_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up)); if (wandown_data == NULL) @@ -6148,7 +6185,7 @@ fail: /* handle STA WAN-client */ /* handle WAN client initial, construct full headers (tx property) */ -int IPACM_Wan::handle_wan_hdr_init(uint8_t *mac_addr) +int IPACM_Wan::handle_wan_hdr_init(uint8_t *mac_addr, bool replaced, int entry) { #define WAN_IFACE_INDEX_LEN 2 @@ -6160,38 +6197,41 @@ int IPACM_Wan::handle_wan_hdr_init(uint8_t *mac_addr) uint32_t cnt; int clnt_indx; - clnt_indx = get_wan_client_index(mac_addr); + IPACMDBG_H("WAN client number: %d\n", num_wan_client); - if (clnt_indx != IPACM_INVALID_INDEX) + if(!replaced) { - IPACMERR("eth client is found/attached already with index %d \n", clnt_indx); - return IPACM_FAILURE; - } + clnt_indx = get_wan_client_index(mac_addr); - /* add header to IPA */ - if (num_wan_client >= IPA_MAX_NUM_WAN_CLIENTS) - { - IPACMERR("Reached maximum number(%d) of eth clients\n", IPA_MAX_NUM_WAN_CLIENTS); - return IPACM_FAILURE; - } + if (clnt_indx != IPACM_INVALID_INDEX) + { + IPACMERR("eth client is found/attached already with index %d \n", clnt_indx); + return IPACM_FAILURE; + } - IPACMDBG_H("WAN client number: %d\n", num_wan_client); + /* add header to IPA */ + if (num_wan_client >= IPA_MAX_NUM_WAN_CLIENTS) + { + IPACMERR("Reached maximum number(%d) of eth clients\n", IPA_MAX_NUM_WAN_CLIENTS); + return IPACM_FAILURE; + } - memcpy(get_client_memptr(wan_client, num_wan_client)->mac, + memcpy(get_client_memptr(wan_client, num_wan_client)->mac, mac_addr, sizeof(get_client_memptr(wan_client, num_wan_client)->mac)); - IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", + IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); - IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n", + IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n", get_client_memptr(wan_client, num_wan_client)->mac[0], get_client_memptr(wan_client, num_wan_client)->mac[1], get_client_memptr(wan_client, num_wan_client)->mac[2], get_client_memptr(wan_client, num_wan_client)->mac[3], get_client_memptr(wan_client, num_wan_client)->mac[4], get_client_memptr(wan_client, num_wan_client)->mac[5]); + } /* add header to IPA */ if(tx_prop != NULL) @@ -6292,13 +6332,23 @@ int IPACM_Wan::handle_wan_hdr_init(uint8_t *mac_addr) goto fail; } - get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl; - IPACMDBG_H("eth-client(%d) v4 full header name:%s header handle:(0x%x)\n", + if (!replaced) + { + get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl; + IPACMDBG_H("eth-client(%d) v4 full header name:%s header handle:(0x%x)\n", num_wan_client, pHeaderDescriptor->hdr[0].name, get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v4); get_client_memptr(wan_client, num_wan_client)->ipv4_header_set=true; - + } else + { + get_client_memptr(wan_client, entry)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl; + IPACMDBG_H("replaced eth-client(%d) v4 full header name:%s header handle:(0x%x)\n", + entry, + pHeaderDescriptor->hdr[0].name, + get_client_memptr(wan_client, entry)->hdr_hdl_v4); + get_client_memptr(wan_client, entry)->ipv4_header_set=true; + } break; } } @@ -6388,24 +6438,45 @@ int IPACM_Wan::handle_wan_hdr_init(uint8_t *mac_addr) goto fail; } - get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl; - IPACMDBG_H("eth-client(%d) v6 full header name:%s header handle:(0x%x)\n", + if (!replaced) + { + get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl; + IPACMDBG_H("eth-client(%d) v6 full header name:%s header handle:(0x%x)\n", num_wan_client, pHeaderDescriptor->hdr[0].name, get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v6); - get_client_memptr(wan_client, num_wan_client)->ipv6_header_set=true; + } + else + { + get_client_memptr(wan_client, entry)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl; + IPACMDBG_H("replaced eth-client(%d) v6 full header name:%s header handle:(0x%x)\n", + entry, + pHeaderDescriptor->hdr[0].name, + get_client_memptr(wan_client, entry)->hdr_hdl_v6); + get_client_memptr(wan_client, entry)->ipv6_header_set=true; + } break; } } /* initialize wifi client*/ - get_client_memptr(wan_client, num_wan_client)->route_rule_set_v4 = false; - get_client_memptr(wan_client, num_wan_client)->route_rule_set_v6 = 0; - get_client_memptr(wan_client, num_wan_client)->ipv4_set = false; - get_client_memptr(wan_client, num_wan_client)->ipv6_set = 0; - num_wan_client++; + if (!replaced) + { + get_client_memptr(wan_client, num_wan_client)->route_rule_set_v4 = false; + get_client_memptr(wan_client, num_wan_client)->route_rule_set_v6 = 0; + get_client_memptr(wan_client, num_wan_client)->ipv4_set = false; + get_client_memptr(wan_client, num_wan_client)->ipv6_set = 0; + num_wan_client++; + } + else + { + get_client_memptr(wan_client, entry)->route_rule_set_v4 = false; + get_client_memptr(wan_client, entry)->route_rule_set_v6 = 0; + get_client_memptr(wan_client, entry)->ipv4_set = false; + get_client_memptr(wan_client, entry)->ipv6_set = 0; + } header_name_count++; //keep increasing header_name_count res = IPACM_SUCCESS; IPACMDBG_H("eth client number: %d\n", num_wan_client); @@ -7967,3 +8038,116 @@ int IPACM_Wan::query_mtu_size() close(fd); return IPACM_SUCCESS; } + +/* construct complete ethernet header */ +int IPACM_Wan::handle_gw_mac_renew(ipacm_event_data_all *data, int index_client) +{ + int index = IPACM_INVALID_INDEX; + + /* checking if client has same ipv4, v6 will put future work */ + if (data->iptype == IPA_IP_v4) + { + index = get_wan_client_index_ipv4(data->ipv4_addr); + if (index != IPACM_INVALID_INDEX) + { + IPACMDBG_H("Matched client index: %d\n", index); + IPACMDBG_H("Client MAC in cache %02x:%02x:%02x:%02x:%02x:%02x\n", + get_client_memptr(wan_client, index)->mac[0], + get_client_memptr(wan_client, index)->mac[1], + get_client_memptr(wan_client, index)->mac[2], + get_client_memptr(wan_client, index)->mac[3], + get_client_memptr(wan_client, index)->mac[4], + get_client_memptr(wan_client, index)->mac[5]); + + /* check mac same or not */ + if ((data->mac_addr[0] == get_client_memptr(wan_client, index)->mac[0]) && + (data->mac_addr[1] == get_client_memptr(wan_client, index)->mac[1]) && + (data->mac_addr[2] == get_client_memptr(wan_client, index)->mac[2]) && + (data->mac_addr[3] == get_client_memptr(wan_client, index)->mac[3]) && + (data->mac_addr[4] == get_client_memptr(wan_client, index)->mac[4]) && + (data->mac_addr[5] == get_client_memptr(wan_client, index)->mac[5])) + { + IPACMDBG_H(" No need client (%d) mac renew with IPv4 (0x%x)\n", index, data->ipv4_addr); + return IPACM_FAILURE; + } + else + { + IPACMDBG_H(" client %d need mac renew with IPv4 (0x%x)\n", index, data->ipv4_addr); + + /* Del NAT rules before ipv4 RT rules are delete */ + if(get_client_memptr(wan_client, index)->ipv4_set == true) + { + IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wan_client, index)->v4_addr); + CtList->HandleSTAClientDelEvt(get_client_memptr(wan_client, index)->v4_addr); + } + + /* clean up STA header / routing rule */ + if (data->ipv4_addr == wan_v4_addr_gw && active_v4) + { + handle_route_del_evt(IPA_IP_v4, true); + IPACMDBG_H("Delete default v4 routing rules\n"); + hdr_hdl_sta_v4 = 0; + header_set_v4 = false; + header_partial_default_wan_v4 = true; + + if (active_v6) + { + handle_route_del_evt(IPA_IP_v6, true); + IPACMDBG_H("Delete default v6 routing rules\n"); + header_partial_default_wan_v6 = true; + } + hdr_hdl_sta_v6 = 0; + header_set_v6 = false; + } + + /* clean up client header routing rule entry */ + if(delete_wan_rtrules(index, IPA_IP_v4)) + { + IPACMERR("unbale to delete wan-client v4 route rules for index %d\n", index); + return IPACM_FAILURE; + } + + get_client_memptr(wan_client, index)->route_rule_set_v4 = false; + get_client_memptr(wan_client, index)->ipv4_set = false; + + IPACMDBG_H("Delete client %d header\n", index); + if(get_client_memptr(wan_client, index)->ipv4_header_set == true) + { + if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, index)->hdr_hdl_v4) == false) + { + IPACMERR("unable to delete client v4 header for index %d\n", index); + return IPACM_FAILURE; + } + get_client_memptr(wan_client, index)->ipv4_header_set = false; + } + + if(delete_wan_rtrules(index, IPA_IP_v6)) + { + IPACMERR("unbale to delete wan-client v6 route rules for index %d\n", index); + return IPACM_FAILURE; + } + get_client_memptr(wan_client, index)->route_rule_set_v6 = 0; + get_client_memptr(wan_client, index)->ipv6_set = 0; + if(get_client_memptr(wan_client, index)->ipv6_header_set == true) + { + if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, index)->hdr_hdl_v6) == false) + { + IPACMERR("unable to delete client v6 header for index %d\n", index); + return IPACM_FAILURE; + } + get_client_memptr(wan_client, index)->ipv6_header_set = false; + } + /* replacing the old mac to new_mac on same entry */ + get_client_memptr(wan_client, index)->mac[0] = data->mac_addr[0]; + get_client_memptr(wan_client, index)->mac[1] = data->mac_addr[1]; + get_client_memptr(wan_client, index)->mac[2] = data->mac_addr[2]; + get_client_memptr(wan_client, index)->mac[3] = data->mac_addr[3]; + get_client_memptr(wan_client, index)->mac[4] = data->mac_addr[4]; + get_client_memptr(wan_client, index)->mac[5] = data->mac_addr[5]; + index_client = index; + return IPACM_SUCCESS; + } + } + } + return IPACM_FAILURE; +} -- cgit v1.2.3 From b2ee9443129e677851feb483dc7e1bc19a3fb3a3 Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Tue, 8 Dec 2020 02:17:05 -0800 Subject: IPACM: fix the MHI icmpv6 exception rule Clean the icmp v6 rule when backhaul type is ipv6. Change-Id: I5b158f5cbfb6846fc21a9556462c23a0d0f7b2d2 --- ipacm/src/IPACM_Lan.cpp | 2 +- ipacm/src/IPACM_Wan.cpp | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp index a6b2b90..c97168d 100644 --- a/ipacm/src/IPACM_Lan.cpp +++ b/ipacm/src/IPACM_Lan.cpp @@ -4242,7 +4242,7 @@ int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype) } else { - IPACMERR("MTU is 0"); + IPACMDBG_H("MTU is zero\n"); } } IPACMDBG_H("total %d MTU rules are needed\n", mtu_rule_cnt); diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp index 763e16a..2ee9f2c 100644 --- a/ipacm/src/IPACM_Wan.cpp +++ b/ipacm/src/IPACM_Wan.cpp @@ -4834,6 +4834,7 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype, bool delete_only) int fd_wwan_ioctl; memset(&wan_state, 0, sizeof(wan_state)); #endif + int ret = IPACM_SUCCESS; IPACMDBG_H("got handle_route_del_evt for STA-mode with ip-family:%d \n", iptype); @@ -4974,24 +4975,19 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype, bool delete_only) if(delete_offload_frag_rule()) { IPACMERR("Failed to delete DL frag rule \n"); - return IPACM_FAILURE; - } - /* Delete MHI icmpv6 exception rule */ - if(delete_icmpv6_exception_rule()) - { - IPACMERR("Failed to delete icmpv6 rule \n"); - return IPACM_FAILURE; + ret = IPACM_FAILURE; } + /* Delete tcp_fin_rst rule */ if(delete_tcp_fin_rst_exception_rule()) { IPACMERR("Failed to delete tcp_fin_rst rule \n"); - return IPACM_FAILURE; + ret = IPACM_FAILURE; } + return ret; } else { - wandown_data->backhaul_type = m_is_sta_mode; memcpy(wandown_data->ipv6_prefix, ipv6_prefix, sizeof(wandown_data->ipv6_prefix)); evt_data.event = IPA_HANDLE_WAN_DOWN_V6; @@ -5010,6 +5006,13 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype, bool delete_only) { memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); } + /* Delete MHI icmpv6 exception rule */ + if(delete_icmpv6_exception_rule()) + { + IPACMERR("Failed to delete icmpv6 rule \n"); + return IPACM_FAILURE; + } + } } else -- cgit v1.2.3 From 0f47323e936c00fa11729ca7884a34704935aba4 Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Tue, 8 Dec 2020 05:31:43 -0800 Subject: ipacm: add stringify for coalesce and mtu events Add stringify for these new events so CMD_queue will print the right events for ipacm logs. Change-Id: I5061b328bbf5f0af47b96450b501102f92701c46 Signed-off-by: Michael Adisumarta --- ipacm/src/IPACM_Config.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp index c396c6c..d0c33e9 100644 --- a/ipacm/src/IPACM_Config.cpp +++ b/ipacm/src/IPACM_Config.cpp @@ -106,7 +106,12 @@ const char *ipacm_event_name[] = { __stringify(IPA_ETH_BRIDGE_CLIENT_ADD), /* ipacm_event_eth_bridge*/ __stringify(IPA_ETH_BRIDGE_CLIENT_DEL), /* ipacm_event_eth_bridge*/ __stringify(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH), /* ipacm_event_eth_bridge*/ - __stringify(IPA_SSR_NOTICE) /* NULL*/ + __stringify(IPA_SSR_NOTICE), /* NULL*/ + __stringify(IPA_COALESCE_NOTICE), /* NULL*/ +#ifdef IPA_MTU_EVENT_MAX + __stringify(IPA_MTU_SET), /* ipa_mtu_info */ + __stringify(IPA_MTU_UPDATE), /* ipacm_event_mtu_info */ +#endif #ifdef FEATURE_L2TP __stringify(IPA_ADD_VLAN_IFACE), /* ipa_ioc_vlan_iface_info */ __stringify(IPA_DEL_VLAN_IFACE), /* ipa_ioc_vlan_iface_info */ -- cgit v1.2.3 From 286830306063751378d274cb85d405cc8f5d53d1 Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Thu, 10 Dec 2020 18:44:26 -0800 Subject: ipacm: add null pointer checks in LanToLan instance Make changes to add null pointer checks in LanToLan instance to avoid any potential ipacm issues. Change-Id: I7331bf3e9b2d777872b6dfc03fa811d2a2925d8d --- ipacm/src/IPACM_LanToLan.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ipacm/src/IPACM_LanToLan.cpp b/ipacm/src/IPACM_LanToLan.cpp index ea016ef..0075418 100644 --- a/ipacm/src/IPACM_LanToLan.cpp +++ b/ipacm/src/IPACM_LanToLan.cpp @@ -1308,8 +1308,12 @@ void IPACM_LanToLan_Iface::handle_down_event() it_own_peer_info++) { /* decrement reference count of peer l2 header type on both interfaces*/ - decrement_ref_cnt_peer_l2_hdr_type(it_own_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type); - it_own_peer_info->peer->decrement_ref_cnt_peer_l2_hdr_type(m_p_iface->tx_prop->tx[0].hdr_l2_type); + if (it_own_peer_info->peer && + it_own_peer_info->peer->get_iface_pointer() && + it_own_peer_info->peer->get_iface_pointer()->tx_prop) + decrement_ref_cnt_peer_l2_hdr_type(it_own_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type); + if (it_own_peer_info->peer && m_p_iface && m_p_iface->tx_prop) + it_own_peer_info->peer->decrement_ref_cnt_peer_l2_hdr_type(m_p_iface->tx_prop->tx[0].hdr_l2_type); /* first clear all flt rule on target interface */ IPACMDBG_H("Clear all flt rule on target interface.\n"); @@ -1330,7 +1334,8 @@ void IPACM_LanToLan_Iface::handle_down_event() other_iface->clear_all_rt_rule_for_one_peer_iface(&(*it_other_iface_peer_info)); /* remove the peer info from the list */ other_iface->m_peer_iface_info.erase(it_other_iface_peer_info); - other_iface->del_hdr_proc_ctx(m_p_iface->tx_prop->tx[0].hdr_l2_type); + if (m_p_iface && m_p_iface->tx_prop) + other_iface->del_hdr_proc_ctx(m_p_iface->tx_prop->tx[0].hdr_l2_type); break; } } @@ -1338,6 +1343,9 @@ void IPACM_LanToLan_Iface::handle_down_event() /* then clear rt rule and hdr proc ctx and release rt table on target interface */ IPACMDBG_H("Clear rt rules and hdr proc ctx and release rt table on target interface.\n"); clear_all_rt_rule_for_one_peer_iface(&(*it_own_peer_info)); + if (it_own_peer_info->peer && + it_own_peer_info->peer->get_iface_pointer() && + it_own_peer_info->peer->get_iface_pointer()->tx_prop) del_hdr_proc_ctx(it_own_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type); } m_peer_iface_info.clear(); -- cgit v1.2.3 From 58d2ae06a3b4c2c1cd86ed36a1ea35e5ccffb0de Mon Sep 17 00:00:00 2001 From: Chaitanya Pratapa Date: Tue, 15 Dec 2020 23:36:05 -0800 Subject: ipacm: make changes to store offload state Make changes to store offload state in a file. Change-Id: I5cbeacd2849bcdac043941d9bd491eaa62364fbc --- ipacm/inc/IPACM_Wan.h | 1 + ipacm/src/IPACM_Wan.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h index a73ec98..9460938 100644 --- a/ipacm/inc/IPACM_Wan.h +++ b/ipacm/inc/IPACM_Wan.h @@ -63,6 +63,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define NETWORK_STATS "%s %llu %llu %llu %llu" #define IPA_NETWORK_STATS_FILE_NAME "/data/misc/ipa/network_stats" +#define IPA_OFFLOAD_TETHER_STATE_FILE_NAME "/data/vendor/ipa/offload_state" typedef struct _wan_client_rt_hdl { diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp index 2ee9f2c..f17eb03 100644 --- a/ipacm/src/IPACM_Wan.cpp +++ b/ipacm/src/IPACM_Wan.cpp @@ -2395,6 +2395,20 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype, bool add_only) IPACMERR("Failed to send WAN_IOC_NOTIFY_WAN_STATE as up %d\n ", wan_state.up); } close(fd_wwan_ioctl); + + /* Store the Offload state. */ + FILE *fp = NULL; + fp = fopen(IPA_OFFLOAD_TETHER_STATE_FILE_NAME, "w"); + if (fp == NULL) + { + IPACMERR("Failed to write offload state to %s, error is %d - %s\n", + IPA_OFFLOAD_TETHER_STATE_FILE_NAME, errno, strerror(errno)); + } + else + { + fprintf(fp, "UPSTREAM=%s,STATE=UP", dev_name); + fclose(fp); + } } ipa_pm_q6_check++; IPACMDBG_H("update ipa_pm_q6_check to %d\n", ipa_pm_q6_check); @@ -5073,6 +5087,20 @@ int IPACM_Wan::handle_route_del_evt_ex(ipa_ip_type iptype) IPACMERR("Failed to send WAN_IOC_NOTIFY_WAN_STATE as up %d\n ", wan_state.up); } close(fd_wwan_ioctl); + + /* Store the Offload state. */ + FILE *fp = NULL; + fp = fopen(IPA_OFFLOAD_TETHER_STATE_FILE_NAME, "w"); + if (fp == NULL) + { + IPACMERR("Failed to write offload state to %s, error is %d - %s\n", + IPA_OFFLOAD_TETHER_STATE_FILE_NAME, errno, strerror(errno)); + } + else + { + fprintf(fp, "UPSTREAM=%s,STATE=DOWN", dev_name); + fclose(fp); + } } if (ipa_pm_q6_check > 0) ipa_pm_q6_check--; -- cgit v1.2.3 From 8f861291645e60a4245341849724c7c67d0853b2 Mon Sep 17 00:00:00 2001 From: Akshay Pandit Date: Thu, 25 Mar 2021 15:04:46 +0530 Subject: data-ipa-cfg-mgr: ipacm: Avoid multiple updates to tether client count Avoid incrementing number of tethered clients twice when xlat is enabled. For WLAN if wan is up prior to DOWNSTREAM_ADD, number of tethered clients is incremented twice. Due to current andorid limitation, andorid won't support 2nd tethered interface. Hence, handle_uplink_filter_rule is not processed due to incorrect counter. Change-Id: I5419434158248139cd936e3873506f7ae706f231 --- ipacm/src/IPACM_Wlan.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp index 460b6c0..eeb4b01 100644 --- a/ipacm/src/IPACM_Wlan.cpp +++ b/ipacm/src/IPACM_Wlan.cpp @@ -562,25 +562,6 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) if(ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n"); -#ifdef FEATURE_IPA_ANDROID - if (IPACM_Wan::isXlat() && (data->prefix.iptype == IPA_IP_v4)) - { - /* indicate v4-offload */ - IPACM_OffloadManager::num_offload_v4_tethered_iface++; - IPACMDBG_H("in xlat: update num_offload_v4_tethered_iface %d\n", IPACM_OffloadManager::num_offload_v4_tethered_iface); - - /* xlat not support for 2st tethered iface */ - if (IPACM_OffloadManager::num_offload_v4_tethered_iface > 1) - { - IPACMDBG_H("Not support 2st downstream iface %s for xlat, cur: %d\n", dev_name, - IPACM_OffloadManager::num_offload_v4_tethered_iface); - return; - } - } - - IPACMDBG_H(" support downstream iface %s, cur %d\n", dev_name, - IPACM_OffloadManager::num_offload_v4_tethered_iface); -#endif if(data->prefix.iptype < IPA_IP_MAX && is_downstream_set[data->prefix.iptype] == false) { IPACMDBG_H("Add downstream for IP iptype %d.\n", data->prefix.iptype); -- cgit v1.2.3 From 20d7b5a2d03d9d50869b88f4a643178fc11870b7 Mon Sep 17 00:00:00 2001 From: Michael Adisumarta Date: Fri, 31 Jan 2020 14:34:08 -0800 Subject: ipacm: Add correct ihl_offset eq bitmap on MTU rules HW < IPA3.0 Change the MTU rule to use the correct equation bitmap to specify ihl_offset_range16 on IPA version older than 3.0 Change-Id: I615534cf76d673ef929ca415b2b905d5119100f8 --- ipacm/src/IPACM_Lan.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp index c97168d..c83a729 100644 --- a/ipacm/src/IPACM_Lan.cpp +++ b/ipacm/src/IPACM_Lan.cpp @@ -6608,6 +6608,7 @@ int IPACM_Lan::construct_mtu_rule(struct ipa_flt_rule *rule, ipa_ip_type iptype, rule->eq_attrib_type = 1; rule->eq_attrib.rule_eq_bitmap = 0; rule->action = IPA_PASS_TO_EXCEPTION; + rule->rt_tbl_hdl = -1; /* generate eq */ memset(&flt_eq, 0, sizeof(flt_eq)); @@ -6631,7 +6632,11 @@ int IPACM_Lan::construct_mtu_rule(struct ipa_flt_rule *rule, ipa_ip_type iptype, &flt_eq.eq_attrib, sizeof(rule->eq_attrib)); //add IHL offsets - rule->eq_attrib.rule_eq_bitmap |= (1<<10); +#ifdef FEATURE_IPA_V3 + rule->eq_attrib.rule_eq_bitmap |= (1<<10); +#else + rule->eq_attrib.rule_eq_bitmap |= (1<<4); +#endif rule->eq_attrib.num_ihl_offset_range_16 = 1; if (iptype == IPA_IP_v4) rule->eq_attrib.ihl_offset_range_16[0].offset = 0x82; -- cgit v1.2.3 From e853a35eb7f17871c7f7b047d38692d96b7bfb97 Mon Sep 17 00:00:00 2001 From: Sauvik Saha Date: Thu, 1 Apr 2021 12:22:00 +0530 Subject: hal: FR59823: Remove references to libhwbinder & libhidltransport Remove libhwbinder & libhidltransport references Change-Id: Ife1f1d572f1386e63ca1b9559f218e2689017ca3 --- hal/Android.bp | 2 -- 1 file changed, 2 deletions(-) diff --git a/hal/Android.bp b/hal/Android.bp index f7559b2..14d3745 100644 --- a/hal/Android.bp +++ b/hal/Android.bp @@ -10,9 +10,7 @@ cc_library_shared { ], shared_libs: [ - "libhwbinder", "libhidlbase", - "libhidltransport", "liblog", "libcutils", "libdl", -- cgit v1.2.3