"LA.UM.9.2.1.r1-07200-sdm660.0"

Signed-off-by: OdSazib <odsazib@gmail.com>
This commit is contained in:
OdSazib 2021-06-28 02:53:45 +06:00
parent e222125fc6
commit 439eba9d44
No known key found for this signature in database
GPG key ID: D4CC9F3E8190970A
34 changed files with 2214 additions and 1477 deletions

View file

@ -0,0 +1,26 @@
cc_library_shared {
name: "liboffloadhal",
srcs: [
"src/CtUpdateAmbassador.cpp",
"src/HAL.cpp",
"src/IpaEventRelay.cpp",
"src/LocalLogBuffer.cpp",
"src/OffloadStatistics.cpp",
"src/PrefixParser.cpp",
],
shared_libs: [
"libhidlbase",
"liblog",
"libcutils",
"libdl",
"libbase",
"libutils",
"libhardware_legacy",
"libhardware",
"android.hardware.tetheroffload.config@1.0",
"android.hardware.tetheroffload.control@1.0",
],
export_include_dirs: ["inc"],
vendor: true,
}

View file

@ -1,31 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_SRC_FILES := src/CtUpdateAmbassador.cpp \
src/HAL.cpp \
src/IpaEventRelay.cpp \
src/LocalLogBuffer.cpp \
src/OffloadStatistics.cpp \
src/PrefixParser.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/inc
LOCAL_MODULE := liboffloadhal
#LOCAL_CPP_FLAGS := -Wall -Werror
LOCAL_SHARED_LIBRARIES := libhwbinder \
libhidlbase \
libhidltransport \
liblog \
libcutils \
libdl \
libbase \
libutils \
libhardware_legacy \
libhardware \
android.hardware.tetheroffload.config@1.0 \
android.hardware.tetheroffload.control@1.0
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/inc
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
include $(BUILD_SHARED_LIBRARY)

View file

@ -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<HAL>> makeIPAHAL(int /* version */, IOffloadManager* /* mgr */);
/* IOffloadConfig */
Return<void> setHandles(

View file

@ -33,7 +33,7 @@
/* External Includes */
#include <arpa/inet.h>
#include <log/log.h>
#include <cutils/log.h>
/* HIDL Includes */
#include <android/hardware/tetheroffload/control/1.0/ITetheringOffloadCallback.h>

View file

@ -39,7 +39,7 @@
#include <linux/netfilter/nfnetlink_compat.h>
/* External Includes */
#include <log/log.h>
#include <cutils/log.h>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
@ -62,7 +62,7 @@ using ::std::vector;
/* ------------------------------ PUBLIC ------------------------------------ */
HAL* HAL::makeIPAHAL(int version, IOffloadManager* mgr) {
Return<::android::sp<HAL>> 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<HAL> ret = new HAL(mgr);
if (nullptr == ret) return NULL;
configureRpcThreadpool(1, false);
ret->registerAsSystemService("ipacm");
@ -86,7 +86,7 @@ HAL::HAL(IOffloadManager* mgr) : mLogs("HAL Function Calls", 50) {
mCbCt = nullptr;
} /* HAL */
void HAL::registerAsSystemService(const char* name __unused) {
void HAL::registerAsSystemService(const char* name) {
status_t ret = 0;
ret = IOffloadControl::registerAsService();

View file

@ -28,7 +28,7 @@
*/
#define LOG_TAG "IPAHALService/IpaEventRelay"
/* External Includes */
#include <log/log.h>
#include <cutils/log.h>
/* HIDL Includes */
#include <android/hardware/tetheroffload/control/1.0/ITetheringOffloadCallback.h>

View file

@ -29,7 +29,7 @@
#define LOG_TAG "IPAHALService/dump"
/* External Includes */
#include <log/log.h>
#include <cutils/log.h>
#include <deque>
#include <string>
#include <sys/types.h>

View file

@ -0,0 +1,72 @@
cc_binary {
name: "ipacm",
local_include_dirs: ["src"] + ["inc"],
header_libs: ["qti_kernel_headers"],
cflags: ["-v"] + ["-DFEATURE_IPA_ANDROID"] + ["-DFEATURE_IPACM_RESTART"] + [
"-DFEATURE_IPACM_HAL",
"-DDEBUG",
"-Wall",
"-Werror",
"-Wno-error=macro-redefined",
],
srcs: [
"src/IPACM_Main.cpp",
"src/IPACM_EvtDispatcher.cpp",
"src/IPACM_Config.cpp",
"src/IPACM_CmdQueue.cpp",
"src/IPACM_Filtering.cpp",
"src/IPACM_Routing.cpp",
"src/IPACM_Header.cpp",
"src/IPACM_Lan.cpp",
"src/IPACM_Iface.cpp",
"src/IPACM_Wlan.cpp",
"src/IPACM_Wan.cpp",
"src/IPACM_IfaceManager.cpp",
"src/IPACM_Neighbor.cpp",
"src/IPACM_Netlink.cpp",
"src/IPACM_Xml.cpp",
"src/IPACM_Conntrack_NATApp.cpp",
"src/IPACM_ConntrackClient.cpp",
"src/IPACM_ConntrackListener.cpp",
"src/IPACM_Log.cpp",
"src/IPACM_OffloadManager.cpp",
"src/IPACM_LanToLan.cpp",
],
init_rc: ["src/ipacm.rc"],
clang: true,
vendor: true,
shared_libs: [
"liboffloadhal",
"libipanat",
"libxml2",
"libnfnetlink",
"libnetfilter_conntrack",
"libhidlbase",
"liblog",
"libcutils",
"libdl",
"libbase",
"libutils",
"libhardware_legacy",
"libhardware",
"android.hardware.tetheroffload.config@1.0",
"android.hardware.tetheroffload.control@1.0",
],
}
//###############################################################################
prebuilt_etc {
name: "IPACM_cfg.xml",
vendor: true,
owner: "ipacm",
src: "src/IPACM_cfg.xml",
}

View file

@ -261,6 +261,14 @@ public:
enum ipa_hw_type GetIPAVer(bool get = false);
#ifdef IPA_IOCTL_GET_HW_FEATURE_SUPPORT
int GetIPAFeatureSupport(bool get = false);
#endif
bool isEthBridgingSupported();
bool isIPAv3Supported();
int Init(void);
inline bool isPrivateSubnet(uint32_t ip_addr)
@ -357,6 +365,9 @@ public:
private:
enum ipa_hw_type ver;
#ifdef IPA_IOCTL_GET_HW_FEATURE_SUPPORT
uint32_t hw_feature;
#endif
static IPACM_Config *pInstance;
static const char *DEVICE_NAME;
IPACM_Config(void);

View file

@ -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);
@ -119,8 +127,11 @@ public:
void HandleSTAClientAddEvt(uint32_t);
void HandleSTAClientDelEvt(uint32_t);
int CreateConnTrackThreads(void);
void readConntrack(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;

View file

@ -97,11 +97,7 @@ extern "C"
#define IPA_DEVICE_NAME "/dev/ipa"
#define MAX_NUM_PROP 2
#ifndef FEATURE_IPA_V3
#define IPA_MAX_FLT_RULE 50
#else
#define IPA_MAX_FLT_RULE 100
#endif
#define TCP_FIN_SHIFT 16
#define TCP_SYN_SHIFT 17
@ -197,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 */
@ -411,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 */

View file

@ -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();

View file

@ -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
{
@ -105,8 +106,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 +148,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 +407,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);
@ -583,10 +593,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);
@ -594,10 +607,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);
@ -612,7 +625,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);
@ -674,7 +687,7 @@ private:
int delete_tcp_fin_rst_exception_rule();
/* Query mtu size */
/* MTU helper functions */
int query_mtu_size();
};

View file

@ -1,162 +0,0 @@
TARGET_DISABLE_IPACM := false
ifeq ($(TARGET_USES_QMAA),true)
ifneq ($(TARGET_USES_QMAA_OVERRIDE_DATA),true)
TARGET_DISABLE_IPACM := 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)
BOARD_PLATFORM_LIST := msm8909
BOARD_PLATFORM_LIST += msm8916
BOARD_PLATFORM_LIST += msm8917
BOARD_PLATFORM_LIST += qm215
ifeq ($(TARGET_BOARD_SUFFIX),_gvmq)
BOARD_PLATFORM_LIST += msmnile
endif
BOARD_IPAv3_LIST := msm8998
BOARD_IPAv3_LIST += sdm845
BOARD_IPAv3_LIST += sdm710
BOARD_IPAv3_LIST += msmnile
BOARD_IPAv3_LIST += kona
BOARD_IPAv3_LIST += $(MSMSTEPPE)
BOARD_IPAv3_LIST += $(TRINKET)
BOARD_IPAv3_LIST += lito
BOARD_IPAv3_LIST += atoll
BOARD_IPAv3_LIST += bengal
BOARD_ETH_BRIDGE_LIST := msmnile
BOARD_ETH_BRIDGE_LIST += kona
ifneq ($(call is-board-platform-in-list,$(BOARD_PLATFORM_LIST)),true)
ifneq (,$(filter $(QCOM_BOARD_PLATFORMS),$(TARGET_BOARD_PLATFORM)))
ifneq (, $(filter aarch64 arm arm64, $(TARGET_ARCH)))
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../inc
LOCAL_HEADER_LIBRARIES := generated_kernel_headers
LOCAL_CFLAGS := -DFEATURE_IPA_ANDROID
LOCAL_CFLAGS += -DFEATURE_IPACM_RESTART
ifeq ($(call is-board-platform-in-list,$(BOARD_ETH_BRIDGE_LIST)),true)
LOCAL_CFLAGS += -DFEATURE_ETH_BRIDGE_LE
endif
LOCAL_CFLAGS += -DFEATURE_IPACM_HAL
LOCAL_CFLAGS += \
-Wall \
-Werror \
-Wno-constant-logical-operand \
-Wno-format \
-Wno-missing-field-initializers \
-Wno-sign-compare \
-Wno-sometimes-uninitialized \
-Wno-unused-parameter \
-Wno-unused-value \
-Wno-unused-variable \
-Wno-writable-strings \
-Wno-error=implicit-fallthrough
ifneq (,$(filter eng, $(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DDEBUG
endif
ifeq ($(call is-board-platform-in-list,$(BOARD_IPAv3_LIST)),true)
LOCAL_CFLAGS += -DFEATURE_IPA_V3
endif
filetoadd = bionic/libc/kernel/arch-arm/asm/posix_types.h
LOCAL_CFLAGS += $(shell if [ -a $(filetoadd) ] ; then echo -include $(filetoadd) ; fi ;)
filetoadd = bionic/libc/kernel/arch-arm/asm/byteorder.h
LOCAL_CFLAGS += $(shell if [ -a $(filetoadd) ] ; then echo -include $(filetoadd) ; fi ;)
LOCAL_SRC_FILES := IPACM_Main.cpp \
IPACM_EvtDispatcher.cpp \
IPACM_Config.cpp \
IPACM_CmdQueue.cpp \
IPACM_Filtering.cpp \
IPACM_Routing.cpp \
IPACM_Header.cpp \
IPACM_Lan.cpp \
IPACM_Iface.cpp \
IPACM_Wlan.cpp \
IPACM_Wan.cpp \
IPACM_IfaceManager.cpp \
IPACM_Neighbor.cpp \
IPACM_Netlink.cpp \
IPACM_Xml.cpp \
IPACM_Conntrack_NATApp.cpp\
IPACM_ConntrackClient.cpp \
IPACM_ConntrackListener.cpp \
IPACM_Log.cpp \
IPACM_OffloadManager.cpp \
IPACM_LanToLan.cpp
LOCAL_MODULE := ipacm
LOCAL_INIT_RC := ipacm.rc
LOCAL_CLANG := false
LOCAL_MODULE_TAGS := optional
LOCAL_SHARED_LIBRARIES := liboffloadhal
LOCAL_SHARED_LIBRARIES += libipanat
LOCAL_SHARED_LIBRARIES += libxml2
LOCAL_SHARED_LIBRARIES += libnfnetlink
LOCAL_SHARED_LIBRARIES += libnetfilter_conntrack
LOCAL_SHARED_LIBRARIES += libhwbinder \
libhidlbase \
libhidltransport \
liblog \
libcutils \
libdl \
libbase \
libutils \
libhardware_legacy \
libhardware \
android.hardware.tetheroffload.config@1.0 \
android.hardware.tetheroffload.control@1.0
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_EXECUTABLES)
LOCAL_CLANG := true
include $(BUILD_EXECUTABLE)
################################################################################
define ADD_TEST
include $(CLEAR_VARS)
LOCAL_MODULE := $1
LOCAL_SRC_FILES := $1
LOCAL_MODULE_CLASS := ipacm
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
include $(BUILD_PREBUILT)
endef
include $(CLEAR_VARS)
LOCAL_MODULE := IPACM_cfg.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_OWNER := ipacm
include $(BUILD_PREBUILT)
endif # $(TARGET_ARCH)
endif
endif
endif

View file

@ -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 */
@ -192,6 +197,9 @@ int IPACM_Config::Init(void)
IPACMERR("Failed opening %s.\n", DEVICE_NAME);
}
ver = GetIPAVer(true);
#ifdef IPA_IOCTL_GET_HW_FEATURE_SUPPORT
hw_feature = GetIPAFeatureSupport(true);
#endif
#ifdef FEATURE_IPACM_HAL
strlcpy(IPACM_config_file, "/vendor/etc/IPACM_cfg.xml", sizeof(IPACM_config_file));
#else
@ -905,3 +913,51 @@ enum ipa_hw_type IPACM_Config::GetIPAVer(bool get)
IPACMDBG_H("IPA version is %d.\n", ver);
return ver;
}
#ifdef IPA_IOCTL_GET_HW_FEATURE_SUPPORT
int IPACM_Config::GetIPAFeatureSupport(bool get)
{
int ret;
if(!get)
return hw_feature;
ret = ioctl(m_fd, IPA_IOC_GET_HW_FEATURE_SUPPORT, &hw_feature);
if(ret != 0)
{
IPACMERR("Failed to get IPA HW feature support %d.\n", ret);
hw_feature = 0;
return hw_feature;
}
IPACMDBG_H("IPA HW supported feature %d.\n", hw_feature);
return hw_feature;
}
#endif
bool IPACM_Config::isEthBridgingSupported()
{
enum ipa_hw_type hw_type;
hw_type = GetIPAVer();
#ifdef IPA_IOCTL_GET_HW_FEATURE_SUPPORT
if (hw_type >= IPA_HW_v4_11) {
return ((hw_feature & IPA_HW_ETH_BRIDGING_SUPPORT_BMSK) != 0);
}
#endif
#ifdef IPA_HW_v4_7
return ((hw_type >= IPA_HW_v4_5) &&
(hw_type != IPA_HW_v4_7));
#else
return (hw_type >= IPA_HW_v4_5);
#endif
}
bool IPACM_Config::isIPAv3Supported()
{
enum ipa_hw_type hw_type;
hw_type = GetIPAVer();
return (hw_type >= IPA_HW_v3_0);
}

View file

@ -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)
@ -493,12 +482,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 +574,15 @@ void* IPACM_ConntrackClient::UDPRegisterWithConnTrack(void *)
/* Block to catch events from net filter connection track */
ctcatch:
ret = nfct_catch(pClient->udp_hdl);
if(ret == -1)
/* Due to conntrack dump, sequence number might mismatch for initial events. */
if((ret == -1) && (errno != ENOMSG) && (errno != EILSEQ))
{
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;
}

View file

@ -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
@ -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())
@ -880,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");
@ -964,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;
@ -1037,7 +1056,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 +1065,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 +1095,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 +1103,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,13 +1124,16 @@ 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;
}
}
PopulateTCPorUDPEntry(ct, status, &rule);
rule.public_ip = wan_ipaddr;
PopulateTCPorUDPEntry(ct, status, &rule);
if (rule.private_ip != wan_ipaddr)
{
@ -1137,7 +1160,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 +1170,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)
@ -1219,78 +1242,97 @@ 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();
len = MAX_CONNTRACK_ENTRIES * sizeof(struct nf_conntrack **);
len = MAX_CONNTRACK_ENTRIES * sizeof(ct_entry);
ct_entries = (struct nf_conntrack **) malloc(len);
memset(ct_entries, 0, len);
if( pClient->fd_tcp < 0)
ct_entries = (ct_entry *) malloc(len);
if(ct_entries == NULL)
{
IPACMDBG_H("Invalid fd %d \n",pClient->fd_tcp);
IPACMERR("unable to allocate ct_entries memory \n");
return;
}
memset(ct_entries, 0, len);
IPACMDBG_H("receiving conntrack entries started.\n");
while(len_fil < sizeof(buffer) && index < MAX_CONNTRACK_ENTRIES)
if( fd < 0)
{
recv_bytes = recvfrom( pClient->fd_tcp, buf, sizeof(buffer)-len_fil, 0, (struct sockaddr *)&nlAddr, (socklen_t *)&addr_len);
IPACMDBG_H("Invalid fd %d \n",fd);
free(ct_entries);
return;
}
IPACMDBG_H("receiving conntrack entries started.\n");
len = CT_ENTRIES_BUFFER_SIZE;
while (len > 0)
{
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));
IPACMDBG_H("error in receiving conntrack entries %d%s\n",errno, strerror(errno));
break;
}
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)
{
ct_entries[index++] = ct;
IPACMDBG_H("Error, 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 && parseResult != 0)
{
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("error in parsing %d%s \n", errno, strerror(errno));
IPACMDBG_H("ct allocation failed\n");
}
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");
@ -1305,15 +1347,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_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)))
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;
@ -1334,8 +1375,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)
@ -1349,7 +1390,7 @@ void IPACM_ConntrackListener::processConntrack() {
free(ct_data);
continue;
IGNORE:
nfct_destroy(ct_entries[index]);
nfct_destroy(ct_entries[index].ct);
index++;
}
}
@ -1360,6 +1401,114 @@ IGNORE:
}
isProcessCTDone = true;
free(ct_entries);
IPACMDBG_H("process conntrack ended \n");
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");
}

View file

@ -195,12 +195,6 @@ int NatApp::AddTable(uint32_t pub_ip, uint8_t mux_id)
}
}
/* configure NAT initialization paramater */
pub_ip_addr = pub_ip;
pub_mux_id = mux_id;
IPACMDBG(" Set pub_mux_id: %d\t", pub_mux_id);
/* Add back the cached NAT-entry */
if (pub_ip == pub_ip_addr_pre)
{
@ -228,8 +222,6 @@ int NatApp::AddTable(uint32_t pub_ip, uint8_t mux_id)
/* send connections info to pcie modem only with DL direction */
if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP))
{
/* propagate pub_ip info */
cache[cnt].public_ip = pub_ip;
ret = AddConnection(&cache[cnt]);
if(ret > 0)
{
@ -254,6 +246,9 @@ int NatApp::AddTable(uint32_t pub_ip, uint8_t mux_id)
}
}
pub_ip_addr = pub_ip;
pub_mux_id = mux_id;
IPACMDBG(" Set pub_mux_id: %d\t", pub_mux_id);
return 0;
}
@ -551,9 +546,8 @@ int NatApp::AddConnection(const nat_table_entry *rule)
flt_rule_entry.rule.to_uc = 0;
flt_rule_entry.rule.eq_attrib_type = 1;
flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
#ifdef FEATURE_IPA_V3
flt_rule_entry.rule.hashable = true;
#endif
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
flt_rule_entry.rule.hashable = true;
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_PORT;
flt_rule_entry.rule.attrib.src_port = rule->target_port;
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_PORT;

View file

@ -46,6 +46,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "IPACM_Filtering.h"
#include <IPACM_Log.h>
#include "IPACM_Defs.h"
#include "IPACM_Iface.h"
const char *IPACM_Filtering::DEVICE_NAME = "/dev/ipa";
@ -235,156 +236,162 @@ fail_tbl:
bool IPACM_Filtering::AddFilteringRuleAfter_hw_index(struct ipa_ioc_add_flt_rule_after *ruleTable, int hw_counter_index)
{
bool ret = true;
#ifdef FEATURE_IPA_V3
int retval=0, cnt = 0, len = 0;
struct ipa_ioc_add_flt_rule_after_v2 *ruleTable_v2;
struct ipa_flt_rule_add_v2 flt_rule_entry;
IPACMDBG("Printing filter add attributes\n");
IPACMDBG("ep: %d\n", ruleTable->ep);
IPACMDBG("ip type: %d\n", ruleTable->ip);
IPACMDBG("Number of rules: %d\n", ruleTable->num_rules);
IPACMDBG("add_after_hdl: %d\n", ruleTable->add_after_hdl);
IPACMDBG("commit value: %d\n", ruleTable->commit);
/* change to v2 format*/
len = sizeof(struct ipa_ioc_add_flt_rule_after_v2);
ruleTable_v2 = (struct ipa_ioc_add_flt_rule_after_v2*)malloc(len);
if (ruleTable_v2 == NULL)
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
{
IPACMERR("Error Locate ipa_ioc_add_flt_rule_after_v2 memory...\n");
return false;
}
memset(ruleTable_v2, 0, len);
ruleTable_v2->rules = (uint64_t)calloc(ruleTable->num_rules, sizeof(struct ipa_flt_rule_add_v2));
if (!ruleTable_v2->rules) {
IPACMERR("Failed to allocate memory for filtering rules\n");
ret = false;
goto fail_tbl;
}
IPACMDBG("Printing filter add attributes\n");
IPACMDBG("ep: %d\n", ruleTable->ep);
IPACMDBG("ip type: %d\n", ruleTable->ip);
IPACMDBG("Number of rules: %d\n", ruleTable->num_rules);
IPACMDBG("add_after_hdl: %d\n", ruleTable->add_after_hdl);
IPACMDBG("commit value: %d\n", ruleTable->commit);
ruleTable_v2->commit = ruleTable->commit;
ruleTable_v2->ep = ruleTable->ep;
ruleTable_v2->ip = ruleTable->ip;
ruleTable_v2->num_rules = ruleTable->num_rules;
ruleTable_v2->add_after_hdl = ruleTable->add_after_hdl;
ruleTable_v2->flt_rule_size = sizeof(struct ipa_flt_rule_add_v2);
for (cnt=0; cnt < ruleTable->num_rules; cnt++)
{
memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add_v2));
flt_rule_entry.at_rear = ruleTable->rules[cnt].at_rear;
flt_rule_entry.rule.retain_hdr = ruleTable->rules[cnt].rule.retain_hdr;
flt_rule_entry.rule.to_uc = ruleTable->rules[cnt].rule.to_uc;
flt_rule_entry.rule.action = ruleTable->rules[cnt].rule.action;
flt_rule_entry.rule.rt_tbl_hdl = ruleTable->rules[cnt].rule.rt_tbl_hdl;
flt_rule_entry.rule.rt_tbl_idx = ruleTable->rules[cnt].rule.rt_tbl_idx;
flt_rule_entry.rule.eq_attrib_type = ruleTable->rules[cnt].rule.eq_attrib_type;
flt_rule_entry.rule.max_prio = ruleTable->rules[cnt].rule.max_prio;
flt_rule_entry.rule.hashable = ruleTable->rules[cnt].rule.hashable;
flt_rule_entry.rule.rule_id = ruleTable->rules[cnt].rule.rule_id;
flt_rule_entry.rule.set_metadata = ruleTable->rules[cnt].rule.set_metadata;
flt_rule_entry.rule.pdn_idx = ruleTable->rules[cnt].rule.pdn_idx;
memcpy(&flt_rule_entry.rule.eq_attrib,
&ruleTable->rules[cnt].rule.eq_attrib,
sizeof(flt_rule_entry.rule.eq_attrib));
memcpy(&flt_rule_entry.rule.attrib,
&ruleTable->rules[cnt].rule.attrib,
sizeof(flt_rule_entry.rule.attrib));
IPACMDBG("Filter rule:%d attrib mask: 0x%x\n", cnt,
ruleTable->rules[cnt].rule.attrib.attrib_mask);
/* 0 means disable hw-counter-sats */
if (hw_counter_index != 0)
/* change to v2 format*/
len = sizeof(struct ipa_ioc_add_flt_rule_after_v2);
ruleTable_v2 = (struct ipa_ioc_add_flt_rule_after_v2*)malloc(len);
if (ruleTable_v2 == NULL)
{
flt_rule_entry.rule.enable_stats = 1;
flt_rule_entry.rule.cnt_idx = hw_counter_index;
IPACMERR("Error Locate ipa_ioc_add_flt_rule_after_v2 memory...\n");
return false;
}
memset(ruleTable_v2, 0, len);
ruleTable_v2->rules = (uint64_t)calloc(ruleTable->num_rules, sizeof(struct ipa_flt_rule_add_v2));
if (!ruleTable_v2->rules) {
IPACMERR("Failed to allocate memory for filtering rules\n");
ret = false;
goto fail_tbl;
}
/* copy to v2 table*/
memcpy((void *)(ruleTable_v2->rules + (cnt * sizeof(struct ipa_flt_rule_add_v2))),
&flt_rule_entry, sizeof(flt_rule_entry));
}
ruleTable_v2->commit = ruleTable->commit;
ruleTable_v2->ep = ruleTable->ep;
ruleTable_v2->ip = ruleTable->ip;
ruleTable_v2->num_rules = ruleTable->num_rules;
ruleTable_v2->add_after_hdl = ruleTable->add_after_hdl;
ruleTable_v2->flt_rule_size = sizeof(struct ipa_flt_rule_add_v2);
retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE_AFTER_V2, ruleTable_v2);
if (retval != 0)
{
IPACMERR("Failed adding Filtering rule %pK\n", ruleTable_v2);
PERROR("unable to add filter rule:");
for (int cnt = 0; cnt < ruleTable_v2->num_rules; cnt++)
for (cnt=0; cnt < ruleTable->num_rules; cnt++)
{
if (((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add_v2));
flt_rule_entry.at_rear = ruleTable->rules[cnt].at_rear;
flt_rule_entry.rule.retain_hdr = ruleTable->rules[cnt].rule.retain_hdr;
flt_rule_entry.rule.to_uc = ruleTable->rules[cnt].rule.to_uc;
flt_rule_entry.rule.action = ruleTable->rules[cnt].rule.action;
flt_rule_entry.rule.rt_tbl_hdl = ruleTable->rules[cnt].rule.rt_tbl_hdl;
flt_rule_entry.rule.rt_tbl_idx = ruleTable->rules[cnt].rule.rt_tbl_idx;
flt_rule_entry.rule.eq_attrib_type = ruleTable->rules[cnt].rule.eq_attrib_type;
flt_rule_entry.rule.max_prio = ruleTable->rules[cnt].rule.max_prio;
flt_rule_entry.rule.hashable = ruleTable->rules[cnt].rule.hashable;
flt_rule_entry.rule.rule_id = ruleTable->rules[cnt].rule.rule_id;
flt_rule_entry.rule.set_metadata = ruleTable->rules[cnt].rule.set_metadata;
flt_rule_entry.rule.pdn_idx = ruleTable->rules[cnt].rule.pdn_idx;
memcpy(&flt_rule_entry.rule.eq_attrib,
&ruleTable->rules[cnt].rule.eq_attrib,
sizeof(flt_rule_entry.rule.eq_attrib));
memcpy(&flt_rule_entry.rule.attrib,
&ruleTable->rules[cnt].rule.attrib,
sizeof(flt_rule_entry.rule.attrib));
IPACMDBG("Filter rule:%d attrib mask: 0x%x\n", cnt,
ruleTable->rules[cnt].rule.attrib.attrib_mask);
/* 0 means disable hw-counter-sats */
if (hw_counter_index != 0)
{
flt_rule_entry.rule.enable_stats = 1;
flt_rule_entry.rule.cnt_idx = hw_counter_index;
}
/* copy to v2 table*/
memcpy((void *)(ruleTable_v2->rules + (cnt * sizeof(struct ipa_flt_rule_add_v2))),
&flt_rule_entry, sizeof(flt_rule_entry));
}
retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE_AFTER_V2, ruleTable_v2);
if (retval != 0)
{
IPACMERR("Failed adding Filtering rule %pK\n", ruleTable_v2);
PERROR("unable to add filter rule:");
for (int cnt = 0; cnt < ruleTable_v2->num_rules; cnt++)
{
if (((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
{
IPACMERR("Adding Filter rule:%d failed with status:%d\n",
cnt, ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status);
}
}
ret = false;
goto fail_rule;
}
/* copy results from v2 to v1 format */
for (int cnt = 0; cnt < ruleTable->num_rules; cnt++)
{
/* copy status to v1 format */
ruleTable->rules[cnt].status = ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status;
ruleTable->rules[cnt].flt_rule_hdl = ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].flt_rule_hdl;
if(((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
{
IPACMERR("Adding Filter rule:%d failed with status:%d\n",
cnt, ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status);
cnt, ((struct ipa_flt_rule_add_v2 *) ruleTable_v2->rules)[cnt].status);
}
}
ret = false;
goto fail_rule;
}
/* copy results from v2 to v1 format */
for (int cnt = 0; cnt < ruleTable->num_rules; cnt++)
IPACMDBG("Added Filtering rule %pK\n", ruleTable_v2);
fail_rule:
if((void *)ruleTable_v2->rules != NULL)
free((void *)ruleTable_v2->rules);
fail_tbl:
if (ruleTable_v2 != NULL)
free(ruleTable_v2);
}
else
{
/* copy status to v1 format */
ruleTable->rules[cnt].status = ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status;
ruleTable->rules[cnt].flt_rule_hdl = ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].flt_rule_hdl;
if(((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
{
IPACMERR("Adding Filter rule:%d failed with status:%d\n",
cnt, ((struct ipa_flt_rule_add_v2 *) ruleTable_v2->rules)[cnt].status);
}
if (ruleTable)
IPACMERR("Not support adding Filtering rule %pK\n", ruleTable);
}
IPACMDBG("Added Filtering rule %pK\n", ruleTable_v2);
fail_rule:
if((void *)ruleTable_v2->rules != NULL)
free((void *)ruleTable_v2->rules);
fail_tbl:
if (ruleTable_v2 != NULL)
free(ruleTable_v2);
#else
if (ruleTable)
IPACMERR("Not support adding Filtering rule %pK\n", ruleTable);
#endif
return ret;
}
#endif //IPA_IOCTL_SET_FNR_COUNTER_INFO
bool IPACM_Filtering::AddFilteringRuleAfter(struct ipa_ioc_add_flt_rule_after const *ruleTable)
{
#ifdef FEATURE_IPA_V3
int retval = 0;
IPACMDBG("Printing filter add attributes\n");
IPACMDBG("ip type: %d\n", ruleTable->ip);
IPACMDBG("Number of rules: %d\n", ruleTable->num_rules);
IPACMDBG("End point: %d\n", ruleTable->ep);
IPACMDBG("commit value: %d\n", ruleTable->commit);
retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE_AFTER, ruleTable);
for (int cnt = 0; cnt<ruleTable->num_rules; cnt++)
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
{
if(ruleTable->rules[cnt].status != 0)
IPACMDBG("Printing filter add attributes\n");
IPACMDBG("ip type: %d\n", ruleTable->ip);
IPACMDBG("Number of rules: %d\n", ruleTable->num_rules);
IPACMDBG("End point: %d\n", ruleTable->ep);
IPACMDBG("commit value: %d\n", ruleTable->commit);
retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE_AFTER, ruleTable);
for (int cnt = 0; cnt<ruleTable->num_rules; cnt++)
{
IPACMERR("Adding Filter rule:%d failed with status:%d\n",
cnt, ruleTable->rules[cnt].status);
if(ruleTable->rules[cnt].status != 0)
{
IPACMERR("Adding Filter rule:%d failed with status:%d\n",
cnt, ruleTable->rules[cnt].status);
}
}
}
if (retval != 0)
{
IPACMERR("Failed adding Filtering rule %pK\n", ruleTable);
return false;
if (retval != 0)
{
IPACMERR("Failed adding Filtering rule %pK\n", ruleTable);
return false;
}
IPACMDBG("Added Filtering rule %pK\n", ruleTable);
}
else
{
if (ruleTable)
IPACMERR("Not support adding Filtering rule %pK\n", ruleTable);
}
IPACMDBG("Added Filtering rule %pK\n", ruleTable);
#else
if (ruleTable)
IPACMERR("Not support adding Filtering rule %pK\n", ruleTable);
#endif
return true;
}
@ -502,9 +509,7 @@ bool IPACM_Filtering::AddWanDLFilteringRule(struct ipa_ioc_add_flt_rule const *r
{
int ret = 0, cnt, num_rules = 0, pos = 0;
ipa_install_fltr_rule_req_msg_v01 qmi_rule_msg;
#ifdef FEATURE_IPA_V3
ipa_install_fltr_rule_req_ex_msg_v01 qmi_rule_ex_msg;
#endif
memset(&qmi_rule_msg, 0, sizeof(qmi_rule_msg));
int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
@ -526,175 +531,178 @@ bool IPACM_Filtering::AddWanDLFilteringRule(struct ipa_ioc_add_flt_rule const *r
}
/* if it is not IPA v3, use old QMI format */
#ifndef FEATURE_IPA_V3
if(num_rules > QMI_IPA_MAX_FILTERS_V01)
if (!IPACM_Iface::ipacmcfg->isIPAv3Supported())
{
IPACMERR("The number of filtering rules exceed limit.\n");
close(fd_wwan_ioctl);
return false;
}
else
{
if (num_rules > 0)
if(num_rules > QMI_IPA_MAX_FILTERS_V01)
{
qmi_rule_msg.filter_spec_list_valid = true;
}
else
{
qmi_rule_msg.filter_spec_list_valid = false;
}
qmi_rule_msg.filter_spec_list_len = num_rules;
qmi_rule_msg.source_pipe_index_valid = 0;
IPACMDBG_H("Get %d WAN DL filtering rules in total.\n", num_rules);
if(rule_table_v4 != NULL)
{
for(cnt = rule_table_v4->num_rules - 1; cnt >= 0; cnt--)
{
if (pos < QMI_IPA_MAX_FILTERS_V01)
{
qmi_rule_msg.filter_spec_list[pos].filter_spec_identifier = pos;
qmi_rule_msg.filter_spec_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
qmi_rule_msg.filter_spec_list[pos].filter_action = GetQmiFilterAction(rule_table_v4->rules[cnt].rule.action);
qmi_rule_msg.filter_spec_list[pos].is_routing_table_index_valid = 1;
qmi_rule_msg.filter_spec_list[pos].route_table_index = rule_table_v4->rules[cnt].rule.rt_tbl_idx;
qmi_rule_msg.filter_spec_list[pos].is_mux_id_valid = 1;
qmi_rule_msg.filter_spec_list[pos].mux_id = mux_id;
memcpy(&qmi_rule_msg.filter_spec_list[pos].filter_rule,
&rule_table_v4->rules[cnt].rule.eq_attrib,
sizeof(struct ipa_filter_rule_type_v01));
pos++;
}
else
{
IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos);
}
}
}
if(rule_table_v6 != NULL)
{
for(cnt = rule_table_v6->num_rules - 1; cnt >= 0; cnt--)
{
if (pos < QMI_IPA_MAX_FILTERS_V01)
{
qmi_rule_msg.filter_spec_list[pos].filter_spec_identifier = pos;
qmi_rule_msg.filter_spec_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
qmi_rule_msg.filter_spec_list[pos].filter_action = GetQmiFilterAction(rule_table_v6->rules[cnt].rule.action);
qmi_rule_msg.filter_spec_list[pos].is_routing_table_index_valid = 1;
qmi_rule_msg.filter_spec_list[pos].route_table_index = rule_table_v6->rules[cnt].rule.rt_tbl_idx;
qmi_rule_msg.filter_spec_list[pos].is_mux_id_valid = 1;
qmi_rule_msg.filter_spec_list[pos].mux_id = mux_id;
memcpy(&qmi_rule_msg.filter_spec_list[pos].filter_rule,
&rule_table_v6->rules[cnt].rule.eq_attrib,
sizeof(struct ipa_filter_rule_type_v01));
pos++;
}
else
{
IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos);
}
}
}
ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE, &qmi_rule_msg);
if (ret != 0)
{
IPACMERR("Failed adding Filtering rule %p with ret %d\n ", &qmi_rule_msg, ret);
IPACMERR("The number of filtering rules exceed limit.\n");
close(fd_wwan_ioctl);
return false;
}
}
else
{
if (num_rules > 0)
{
qmi_rule_msg.filter_spec_list_valid = true;
}
else
{
qmi_rule_msg.filter_spec_list_valid = false;
}
qmi_rule_msg.filter_spec_list_len = num_rules;
qmi_rule_msg.source_pipe_index_valid = 0;
IPACMDBG_H("Get %d WAN DL filtering rules in total.\n", num_rules);
if(rule_table_v4 != NULL)
{
for(cnt = rule_table_v4->num_rules - 1; cnt >= 0; cnt--)
{
if (pos < QMI_IPA_MAX_FILTERS_V01)
{
qmi_rule_msg.filter_spec_list[pos].filter_spec_identifier = pos;
qmi_rule_msg.filter_spec_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
qmi_rule_msg.filter_spec_list[pos].filter_action = GetQmiFilterAction(rule_table_v4->rules[cnt].rule.action);
qmi_rule_msg.filter_spec_list[pos].is_routing_table_index_valid = 1;
qmi_rule_msg.filter_spec_list[pos].route_table_index = rule_table_v4->rules[cnt].rule.rt_tbl_idx;
qmi_rule_msg.filter_spec_list[pos].is_mux_id_valid = 1;
qmi_rule_msg.filter_spec_list[pos].mux_id = mux_id;
memcpy(&qmi_rule_msg.filter_spec_list[pos].filter_rule,
&rule_table_v4->rules[cnt].rule.eq_attrib,
sizeof(struct ipa_filter_rule_type_v01));
pos++;
}
else
{
IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos);
}
}
}
if(rule_table_v6 != NULL)
{
for(cnt = rule_table_v6->num_rules - 1; cnt >= 0; cnt--)
{
if (pos < QMI_IPA_MAX_FILTERS_V01)
{
qmi_rule_msg.filter_spec_list[pos].filter_spec_identifier = pos;
qmi_rule_msg.filter_spec_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
qmi_rule_msg.filter_spec_list[pos].filter_action = GetQmiFilterAction(rule_table_v6->rules[cnt].rule.action);
qmi_rule_msg.filter_spec_list[pos].is_routing_table_index_valid = 1;
qmi_rule_msg.filter_spec_list[pos].route_table_index = rule_table_v6->rules[cnt].rule.rt_tbl_idx;
qmi_rule_msg.filter_spec_list[pos].is_mux_id_valid = 1;
qmi_rule_msg.filter_spec_list[pos].mux_id = mux_id;
memcpy(&qmi_rule_msg.filter_spec_list[pos].filter_rule,
&rule_table_v6->rules[cnt].rule.eq_attrib,
sizeof(struct ipa_filter_rule_type_v01));
pos++;
}
else
{
IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos);
}
}
}
ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE, &qmi_rule_msg);
if (ret != 0)
{
IPACMERR("Failed adding Filtering rule %p with ret %d\n ", &qmi_rule_msg, ret);
close(fd_wwan_ioctl);
return false;
}
}
/* if it is IPA v3, use new QMI format */
#else
if(num_rules > QMI_IPA_MAX_FILTERS_EX_V01)
{
IPACMERR("The number of filtering rules exceed limit.\n");
close(fd_wwan_ioctl);
return false;
}
else
{
memset(&qmi_rule_ex_msg, 0, sizeof(qmi_rule_ex_msg));
if (num_rules > 0)
if(num_rules > QMI_IPA_MAX_FILTERS_EX_V01)
{
qmi_rule_ex_msg.filter_spec_ex_list_valid = true;
}
else
{
qmi_rule_ex_msg.filter_spec_ex_list_valid = false;
}
qmi_rule_ex_msg.filter_spec_ex_list_len = num_rules;
qmi_rule_ex_msg.source_pipe_index_valid = 0;
IPACMDBG_H("Get %d WAN DL filtering rules in total.\n", num_rules);
if(rule_table_v4 != NULL)
{
for(cnt = rule_table_v4->num_rules - 1; cnt >= 0; cnt--)
{
if (pos < QMI_IPA_MAX_FILTERS_EX_V01)
{
qmi_rule_ex_msg.filter_spec_ex_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_action = GetQmiFilterAction(rule_table_v4->rules[cnt].rule.action);
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_routing_table_index_valid = 1;
qmi_rule_ex_msg.filter_spec_ex_list[pos].route_table_index = rule_table_v4->rules[cnt].rule.rt_tbl_idx;
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_mux_id_valid = 1;
qmi_rule_ex_msg.filter_spec_ex_list[pos].mux_id = mux_id;
qmi_rule_ex_msg.filter_spec_ex_list[pos].rule_id = rule_table_v4->rules[cnt].rule.rule_id;
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_rule_hashable = rule_table_v4->rules[cnt].rule.hashable;
memcpy(&qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_rule,
&rule_table_v4->rules[cnt].rule.eq_attrib,
sizeof(struct ipa_filter_rule_type_v01));
pos++;
}
else
{
IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_EX_V01, pos);
}
}
}
if(rule_table_v6 != NULL)
{
for(cnt = rule_table_v6->num_rules - 1; cnt >= 0; cnt--)
{
if (pos < QMI_IPA_MAX_FILTERS_EX_V01)
{
qmi_rule_ex_msg.filter_spec_ex_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_action = GetQmiFilterAction(rule_table_v6->rules[cnt].rule.action);
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_routing_table_index_valid = 1;
qmi_rule_ex_msg.filter_spec_ex_list[pos].route_table_index = rule_table_v6->rules[cnt].rule.rt_tbl_idx;
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_mux_id_valid = 1;
qmi_rule_ex_msg.filter_spec_ex_list[pos].mux_id = mux_id;
qmi_rule_ex_msg.filter_spec_ex_list[pos].rule_id = rule_table_v6->rules[cnt].rule.rule_id;
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_rule_hashable = rule_table_v6->rules[cnt].rule.hashable;
memcpy(&qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_rule,
&rule_table_v6->rules[cnt].rule.eq_attrib,
sizeof(struct ipa_filter_rule_type_v01));
pos++;
}
else
{
IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_EX_V01, pos);
}
}
}
ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE_EX, &qmi_rule_ex_msg);
if (ret != 0)
{
IPACMERR("Failed adding Filtering rule %pK with ret %d\n ", &qmi_rule_ex_msg, ret);
IPACMERR("The number of filtering rules exceed limit.\n");
close(fd_wwan_ioctl);
return false;
}
else
{
memset(&qmi_rule_ex_msg, 0, sizeof(qmi_rule_ex_msg));
if (num_rules > 0)
{
qmi_rule_ex_msg.filter_spec_ex_list_valid = true;
}
else
{
qmi_rule_ex_msg.filter_spec_ex_list_valid = false;
}
qmi_rule_ex_msg.filter_spec_ex_list_len = num_rules;
qmi_rule_ex_msg.source_pipe_index_valid = 0;
IPACMDBG_H("Get %d WAN DL filtering rules in total.\n", num_rules);
if(rule_table_v4 != NULL)
{
for(cnt = rule_table_v4->num_rules - 1; cnt >= 0; cnt--)
{
if (pos < QMI_IPA_MAX_FILTERS_EX_V01)
{
qmi_rule_ex_msg.filter_spec_ex_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_action = GetQmiFilterAction(rule_table_v4->rules[cnt].rule.action);
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_routing_table_index_valid = 1;
qmi_rule_ex_msg.filter_spec_ex_list[pos].route_table_index = rule_table_v4->rules[cnt].rule.rt_tbl_idx;
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_mux_id_valid = 1;
qmi_rule_ex_msg.filter_spec_ex_list[pos].mux_id = mux_id;
qmi_rule_ex_msg.filter_spec_ex_list[pos].rule_id = rule_table_v4->rules[cnt].rule.rule_id;
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_rule_hashable = rule_table_v4->rules[cnt].rule.hashable;
memcpy(&qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_rule,
&rule_table_v4->rules[cnt].rule.eq_attrib,
sizeof(struct ipa_filter_rule_type_v01));
pos++;
}
else
{
IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_EX_V01, pos);
}
}
}
if(rule_table_v6 != NULL)
{
for(cnt = rule_table_v6->num_rules - 1; cnt >= 0; cnt--)
{
if (pos < QMI_IPA_MAX_FILTERS_EX_V01)
{
qmi_rule_ex_msg.filter_spec_ex_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_action = GetQmiFilterAction(rule_table_v6->rules[cnt].rule.action);
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_routing_table_index_valid = 1;
qmi_rule_ex_msg.filter_spec_ex_list[pos].route_table_index = rule_table_v6->rules[cnt].rule.rt_tbl_idx;
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_mux_id_valid = 1;
qmi_rule_ex_msg.filter_spec_ex_list[pos].mux_id = mux_id;
qmi_rule_ex_msg.filter_spec_ex_list[pos].rule_id = rule_table_v6->rules[cnt].rule.rule_id;
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_rule_hashable = rule_table_v6->rules[cnt].rule.hashable;
memcpy(&qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_rule,
&rule_table_v6->rules[cnt].rule.eq_attrib,
sizeof(struct ipa_filter_rule_type_v01));
pos++;
}
else
{
IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_EX_V01, pos);
}
}
}
ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE_EX, &qmi_rule_ex_msg);
if (ret != 0)
{
IPACMERR("Failed adding Filtering rule %pK with ret %d\n ", &qmi_rule_ex_msg, ret);
close(fd_wwan_ioctl);
return false;
}
}
}
#endif
close(fd_wwan_ioctl);
return true;

View file

@ -133,9 +133,8 @@ int IPACM_Iface::handle_software_routing_enable(bool mhip)
flt_rule_entry.flt_rule_hdl = -1;
flt_rule_entry.status = -1;
flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
#ifdef FEATURE_IPA_V3
flt_rule_entry.rule.hashable = true;
#endif
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
flt_rule_entry.rule.hashable = true;
memcpy(&flt_rule_entry.rule.attrib,
&rx_prop->rx[0].attrib,
sizeof(flt_rule_entry.rule.attrib));
@ -772,10 +771,11 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
flt_rule_entry.flt_rule_hdl = -1;
flt_rule_entry.status = -1;
flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
#ifdef FEATURE_IPA_V3
flt_rule_entry.at_rear = false;
flt_rule_entry.rule.hashable = false;
#endif
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
{
flt_rule_entry.at_rear = false;
flt_rule_entry.rule.hashable = false;
}
IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask);
memcpy(&flt_rule_entry.rule.attrib,
&rx_prop->rx[0].attrib,
@ -791,19 +791,21 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xF0000000;
flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xE0000000;
#ifdef FEATURE_IPA_V3
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.hashable = true;
#endif
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
{
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.hashable = true;
}
memcpy(&(m_pFilteringTable->rules[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
/* Configuring Broadcast Filtering Rule */
flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xFFFFFFFF;
#ifdef FEATURE_IPA_V3
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.hashable = true;
#endif
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
{
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.hashable = true;
}
memcpy(&(m_pFilteringTable->rules[2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
@ -886,10 +888,11 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
#ifdef FEATURE_IPA_V3
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.hashable = true;
#endif
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
{
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.hashable = true;
}
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
/* Configuring fe80::/10 Link-Scoped Unicast Filtering Rule */
@ -901,10 +904,11 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
#ifdef FEATURE_IPA_V3
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.hashable = true;
#endif
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
{
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.hashable = true;
}
memcpy(&(m_pFilteringTable->rules[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
/* Configuring fec0::/10 Reserved by IETF Filtering Rule */
@ -916,10 +920,11 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
#ifdef FEATURE_IPA_V3
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.hashable = true;
#endif
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
{
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.hashable = true;
}
memcpy(&(m_pFilteringTable->rules[2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
/* Configuring fd00::/8 Unique Local Ipv6 Address */
@ -931,10 +936,11 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
#ifdef FEATURE_IPA_V3
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.hashable = true;
#endif
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
{
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.hashable = true;
}
memcpy(&(m_pFilteringTable->rules[3]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
#ifdef FEATURE_IPA_ANDROID
@ -1003,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,

View file

@ -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);
@ -406,9 +409,8 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param)
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, wl);
#endif
IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, wl); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
#ifdef FEATURE_ETH_BRIDGE_LE
IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, wl);
#endif
if (IPACM_Iface::ipacmcfg->isEthBridgingSupported())
IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, wl);
IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, wl);
IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, wl);
#ifndef FEATURE_IPA_ANDROID
@ -421,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);
@ -451,6 +456,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
@ -459,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);

File diff suppressed because it is too large Load diff

View file

@ -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();

View file

@ -121,7 +121,7 @@ int ipa_reset_hw_index_counter();
#ifdef FEATURE_IPACM_HAL
IPACM_OffloadManager* OffloadMng;
HAL *hal;
::android::sp<HAL> hal;
#endif
/* start netlink socket monitor*/
@ -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);
@ -450,12 +454,11 @@ void* ipa_driver_msg_notifier(void *param)
}
memcpy(event_ex, buffer + sizeof(struct ipa_msg_meta), length);
data_ex = (ipacm_event_data_wlan_ex *)malloc(sizeof(ipacm_event_data_wlan_ex) + event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val));
if (data_ex == NULL)
{
if (data_ex == NULL)
{
IPACMERR("unable to allocate memory for event data\n");
free(event_ex);
return NULL;
}
return NULL;
}
data_ex->num_of_attribs = event_ex->num_of_attribs;
memcpy(data_ex->attribs,
@ -761,10 +764,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();
@ -866,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;
@ -952,11 +990,11 @@ int main(int argc, char **argv)
IPACMDBG_H(" START IPACM_OffloadManager and link to android framework\n");
#endif
#ifdef FEATURE_ETH_BRIDGE_LE
IPACM_LanToLan* lan2lan = IPACM_LanToLan::get_instance();
IPACMDBG_H("Staring IPACM_LanToLan instance %p\n", lan2lan);
#endif
if (IPACM_Iface::ipacmcfg->isEthBridgingSupported())
{
IPACM_LanToLan* lan2lan = IPACM_LanToLan::get_instance();
IPACMDBG_H("Staring IPACM_LanToLan instance %p\n", lan2lan);
}
CtList = new IPACM_ConntrackListener();
IPACMDBG_H("Staring IPA main\n");

View file

@ -709,7 +709,6 @@ static int ipa_nl_decode_nlmsg
if(ret_val != IPACM_SUCCESS)
{
IPACMERR("Error while getting interface name\n");
free(data_fid);
return IPACM_FAILURE;
}
IPACMDBG_H("Got a usb link_up event (Interface %s, %d) \n", dev_name, msg_ptr->nl_link_info.metainfo.ifi_index);

View file

@ -120,8 +120,9 @@ RET IPACM_OffloadManager::unregisterCtTimeoutUpdater(ConntrackTimeoutUpdater* )
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;
@ -155,13 +156,39 @@ 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) {
/* 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);
/* 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_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));
}
} else {
IPACMERR("Received unexpected fd with groups %d.\n", groups);

File diff suppressed because it is too large Load diff

View file

@ -206,20 +206,21 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("Received IPA_LAN_DELETE_SELF event.\n");
IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
#ifdef FEATURE_ETH_BRIDGE_LE
if(rx_prop != NULL)
if (IPACM_Iface::ipacmcfg->isEthBridgingSupported())
{
free(rx_prop);
if(rx_prop != NULL)
{
free(rx_prop);
}
if(tx_prop != NULL)
{
free(tx_prop);
}
if(iface_query != NULL)
{
free(iface_query);
}
}
if(tx_prop != NULL)
{
free(tx_prop);
}
if(iface_query != NULL)
{
free(iface_query);
}
#endif
delete this;
}
break;
@ -561,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);
@ -650,6 +632,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");
@ -1633,9 +1644,8 @@ int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type ipt
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
#ifdef FEATURE_IPA_V3
rt_rule_entry->rule.hashable = true;
#endif
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
rt_rule_entry->rule.hashable = true;
if (false == m_routing.AddRoutingRule(rt_rule))
{
IPACMERR("Routing rule addition failed!\n");
@ -1685,9 +1695,8 @@ int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type ipt
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
#ifdef FEATURE_IPA_V3
rt_rule_entry->rule.hashable = true;
#endif
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
rt_rule_entry->rule.hashable = true;
#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
/* use index hw-counter */
if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
@ -2137,9 +2146,8 @@ fail:
IPACMDBG_H("depend Got pipe %d rm index : %d \n", rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]);
}
#ifndef FEATURE_ETH_BRIDGE_LE
free(rx_prop);
#endif
if (!(IPACM_Iface::ipacmcfg->isEthBridgingSupported()))
free(rx_prop);
}
for (i = 0; i < num_wifi_client; i++)
@ -2153,17 +2161,18 @@ fail:
{
free(wlan_client);
}
#ifndef FEATURE_ETH_BRIDGE_LE
if (tx_prop != NULL)
if (!(IPACM_Iface::ipacmcfg->isEthBridgingSupported()))
{
free(tx_prop);
}
if (tx_prop != NULL)
{
free(tx_prop);
}
if (iface_query != NULL)
{
free(iface_query);
if (iface_query != NULL)
{
free(iface_query);
}
}
#endif
is_active = false;
post_del_self_evt();
@ -2504,9 +2513,8 @@ int IPACM_Wlan::add_connection(int client_index, int v6_num)
flt_rule_entry.rule.to_uc = 0;
flt_rule_entry.rule.eq_attrib_type = 1;
flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
#ifdef FEATURE_IPA_V3
flt_rule_entry.rule.hashable = true;
#endif
if (IPACM_Iface::ipacmcfg->isIPAv3Supported())
flt_rule_entry.rule.hashable = true;
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][0];
flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][1];

View file

@ -25,13 +25,10 @@
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# msm specific files that need to be created on /data
on post-fs-data
mkdir /data/vendor/ipa 0770 radio radio
chmod 0770 /data/vendor/ipa
service vendor.ipacm /system/vendor/bin/ipacm
class late_start
class main
user radio
group radio inet
writepid /dev/cpuset/system-background/tasks
on post-fs
start vendor.ipacm

View file

@ -0,0 +1,50 @@
TARGET_DISABLE_IPACM := false
#IPACM_DATA
IPACM_DATA += IPACM_cfg.xml
IPACM_DATA += ipacm
IPACM_DATA += ipacm.rc
ifeq ($(TARGET_USES_QMAA),true)
ifneq ($(TARGET_USES_QMAA_OVERRIDE_DATA),true)
TARGET_DISABLE_IPACM := 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)
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
BOARD_IPAv3_LIST += msmnile
BOARD_IPAv3_LIST += kona
BOARD_IPAv3_LIST += $(MSMSTEPPE)
BOARD_IPAv3_LIST += $(TRINKET)
BOARD_IPAv3_LIST += lito
BOARD_IPAv3_LIST += atoll
BOARD_IPAv3_LIST += bengal
BOARD_ETH_BRIDGE_LIST := msmnile
BOARD_ETH_BRIDGE_LIST += kona
ifneq ($(call is-board-platform-in-list,$(BOARD_PLATFORM_LIST)),true)
ifneq (,$(filter $(QCOM_BOARD_PLATFORMS),$(TARGET_BOARD_PLATFORM)))
ifneq (, $(filter aarch64 arm arm64, $(TARGET_ARCH)))
PRODUCT_PACKAGES += $(IPACM_DATA)
endif # $(TARGET_ARCH)
endif
endif
endif

View file

@ -0,0 +1,28 @@
cc_library_shared {
name: "libipanat",
header_libs: ["qti_kernel_headers"],
srcs: [
"src/ipa_nat_drv.c",
"src/ipa_nat_drvi.c",
],
shared_libs:
["libcutils",
"libdl",
"libbase",
"libutils",
],
export_include_dirs: ["inc"],
vendor: true,
cflags: [
"-DDEBUG",
"-Wall",
"-Werror",
] + ["-DFEATURE_IPA_ANDROID"],
clang: true,
}

View file

@ -30,9 +30,9 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef IPA_NAT_DRVI_H
#define IPA_NAT_DRVI_H
#include <unistd.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/msm_ipa.h>
@ -40,12 +40,11 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sys/inotify.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include "ipa_nat_logi.h"
#ifdef DEBUG
#define NAT_DUMP
#endif
/*======= IMPLEMENTATION related data structures and functions ======= */
#ifdef IPA_ON_R3PC

View file

@ -1,49 +0,0 @@
BOARD_PLATFORM_LIST := msm8909
BOARD_PLATFORM_LIST += msm8916
BOARD_PLATFORM_LIST += msm8917
ifeq ($(TARGET_BOARD_SUFFIX),_gvmq)
BOARD_PLATFORM_LIST += msmnile
endif
TARGET_DISABLE_IPANAT := false
ifeq ($(TARGET_USES_QMAA),true)
ifneq ($(TARGET_USES_QMAA_OVERRIDE_DATA),true)
TARGET_DISABLE_IPANAT := true
endif #TARGET_USES_QMAA_OVERRIDE_DATA
endif #TARGET_USES_QMAA
ifneq ($(TARGET_DISABLE_IPANAT),true)
ifneq ($(call is-board-platform-in-list,$(BOARD_PLATFORM_LIST)),true)
ifneq (,$(filter $(QCOM_BOARD_PLATFORMS),$(TARGET_BOARD_PLATFORM)))
ifneq (, $(filter aarch64 arm arm64, $(TARGET_ARCH)))
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../inc
LOCAL_HEADER_LIBRARIES := generated_kernel_headers
LOCAL_SRC_FILES := ipa_nat_drv.c \
ipa_nat_drvi.c
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../inc
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
ifneq (,$(filter eng, $(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS := -DDEBUG
endif
LOCAL_CFLAGS += -Wall -Werror
LOCAL_CFLAGS += -DFEATURE_IPA_ANDROID
LOCAL_MODULE := libipanat
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
LOCAL_CLANG := true
include $(BUILD_SHARED_LIBRARY)
endif # $(TARGET_ARCH)
endif
endif
endif

View file

@ -10,7 +10,8 @@ include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../ipanat/inc
LOCAL_HEADER_LIBRARIES := generated_kernel_headers
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_MODULE := ipa_nat_test
LOCAL_SRC_FILES := ipa_nat_test000.c \
@ -41,7 +42,7 @@ LOCAL_SRC_FILES := ipa_nat_test000.c \
LOCAL_SHARED_LIBRARIES := libipanat
LOCAL_MODULE_TAGS := tests
LOCAL_MODULE_TAGS := debug
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/kernel-tests/ip_accelerator
include $(BUILD_EXECUTABLE)