wayne-common: Synchronize IPACM to P

* QC Tag: LA.UM.7.2.r1-04900-sdm660.0

Signed-off-by: Isaac Chen <isaacchen@isaacchen.cn>
This commit is contained in:
Isaac Chen 2018-12-23 00:18:57 +01:00 committed by Isaac Chen
parent 85cc63e4da
commit ae5a6d2790
33 changed files with 1346 additions and 325 deletions

View file

@ -10,7 +10,8 @@ LOCAL_SRC_FILES := src/CtUpdateAmbassador.cpp \
src/PrefixParser.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/inc
LOCAL_MODULE := liboffloadhal
LOCAL_CPP_FLAGS := -Wall -Werror
#LOCAL_CPP_FLAGS := -Wall -Werror
LOCAL_SHARED_LIBRARIES := libhwbinder \
libhidlbase \
libhidltransport \
@ -23,6 +24,7 @@ LOCAL_SHARED_LIBRARIES := libhwbinder \
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

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2018, 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
@ -64,6 +64,7 @@ using ::android::hardware::tetheroffload::control::V1_0::IOffloadControl;
using ::android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback;
#define KERNEL_PAGE 4096
class HAL : public IOffloadControl, IOffloadConfig {
public:

View file

@ -63,6 +63,8 @@ using ::std::vector;
/* ------------------------------ PUBLIC ------------------------------------ */
HAL* HAL::makeIPAHAL(int version, IOffloadManager* mgr) {
android::hardware::ProcessState::initWithMmapSize((size_t)(2 * KERNEL_PAGE));
if (DBG)
ALOGI("makeIPAHAL(%d, %s)", version,
(mgr != nullptr) ? "provided" : "null");
@ -88,7 +90,7 @@ void HAL::registerAsSystemService(const char* name) {
status_t ret = 0;
ret = IOffloadControl::registerAsService();
if (ret != 0) ALOGE("Failed to register IOffloadControl (%d)", ret);
if (ret != 0) ALOGE("Failed to register IOffloadControl (%d) name(%s)", ret, name);
else if (DBG) {
ALOGI("Successfully registered IOffloadControl");
}

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -47,6 +47,8 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
typedef struct
{
char iface_name[IPA_IFACE_NAME_LEN];
bool v4_up;
bool v6_up;
}NatIfaces;
/* for IPACM rm dependency use*/
@ -230,11 +232,11 @@ public:
void DelRmDepend(ipa_rm_resource_name rm1);
int AddNatIfaces(char *dev_name);
int AddNatIfaces(char *dev_name, ipa_ip_type ip_type);
int DelNatIfaces(char *dev_name);
int CheckNatIfaces(const char *dev_name);
int CheckNatIfaces(const char *dev_name, ipa_ip_type ip_type);
inline void SetQmapId(uint8_t id)
{
@ -252,6 +254,8 @@ public:
int DelExtProp(ipa_ip_type ip_type);
enum ipa_hw_type GetIPAVer(bool get = false);
int Init(void);
inline bool isPrivateSubnet(uint32_t ip_addr)
@ -347,6 +351,7 @@ public:
static const char *DEVICE_NAME_ODU;
private:
enum ipa_hw_type ver;
static IPACM_Config *pInstance;
static const char *DEVICE_NAME;
IPACM_Config(void);

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2017, 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
@ -102,11 +102,12 @@ private:
bool isAlgPort(uint8_t, uint16_t);
void Reset();
bool isPwrSaveIf(uint32_t);
uint32_t GenerateMetdata(uint8_t mux_id);
public:
static NatApp* GetInstance();
int AddTable(uint32_t);
int AddTable(uint32_t, uint8_t mux_id);
uint32_t GetTableHdl(uint32_t);
int DeleteTable(uint32_t);

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -195,6 +195,7 @@ typedef enum
IPA_HANDLE_VLAN_CLIENT_INFO, /* ipacm_event_data_all */
IPA_HANDLE_VLAN_IFACE_INFO, /* ipacm_event_data_all */
#endif
IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE,
IPA_LAN_DELETE_SELF, /* ipacm_event_data_fid */
IPACM_EVENT_MAX
} ipa_cm_event_id;
@ -342,6 +343,7 @@ typedef struct _ipacm_event_iface_up
uint32_t ipv6_prefix[2];
bool is_sta;
uint8_t xlat_mux_id;
uint8_t mux_id;
}ipacm_event_iface_up;
typedef struct _ipacm_event_iface_up_tether

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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 7
#define IPV6_DEFAULT_FILTERTING_RULES 8
#else
#define IPV6_DEFAULT_FILTERTING_RULES 4
#endif
@ -144,6 +144,7 @@ public:
/* software routing disable */
virtual int handle_software_routing_disable(void);
void delete_iface(void);
private:

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -241,6 +241,12 @@ protected:
/* handle tethering client */
int handle_tethering_client(bool reset, ipacm_client_enum ipa_client);
/* add tcp syn flt rule */
int add_tcp_syn_flt_rule(ipa_ip_type iptype);
/* add tcp syn flt rule for l2tp interface*/
int add_tcp_syn_flt_rule_l2tp(ipa_ip_type inner_ip_type);
/* store ipv4 UL filter rule handlers from Q6*/
uint32_t wan_ul_fl_rule_hdl_v4[MAX_WAN_UL_FILTER_RULES];
@ -272,6 +278,8 @@ protected:
bool is_downstream_set[IPA_IP_MAX];
_ipacm_offload_prefix prefix[IPA_IP_MAX];
uint32_t tcp_syn_flt_rule_hdl[IPA_IP_MAX];
private:
/* get hdr proc ctx type given source and destination l2 hdr type */

View file

@ -51,6 +51,9 @@ extern "C"
#include <pthread.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <linux/socket.h>
#include <inaddr.h>
#define sockaddr_storage __kernel_sockaddr_storage
#include <linux/if.h>
#include <linux/if_addr.h>
#include <linux/rtnetlink.h>

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2018, 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
@ -94,6 +94,8 @@ public:
bool search_framwork_cache(char * interface_name);
bool push_framework_event(const char * if_name, _ipacm_offload_prefix prefix);
private:
std::list<std::string> valid_ifaces;
@ -110,6 +112,10 @@ private:
int resetTetherStats(const char *upstream_name);
#ifdef FEATURE_IPACM_RESTART
int push_iface_up(const char *if_name, bool upstream);
#endif
static const char *DEVICE_NAME;
/* cache the add_downstream events if netdev is not ready */

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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,9 +53,10 @@ 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 6
#define IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6 7
#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
#else
#define IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6 3
#endif
@ -93,7 +94,8 @@ class IPACM_Wan : public IPACM_Iface
{
public:
/* IPACM pm_depency q6 check*/
static int ipa_pm_q6_check;
static bool wan_up;
static bool wan_up_v6;
static uint8_t xlat_mux_id;

View file

@ -234,6 +234,11 @@ private:
void handle_SCC_MCC_switch(ipa_ip_type);
#ifdef FEATURE_IPACM_RESTART
/*query wlan-clients */
int ipa_query_wlan_client();
#endif
};

View file

@ -2,6 +2,11 @@ BOARD_PLATFORM_LIST := msm8909
BOARD_PLATFORM_LIST += msm8916
BOARD_PLATFORM_LIST += msm8917
BOARD_IPAv3_LIST := msm8998
BOARD_IPAv3_LIST += sdm845
BOARD_IPAv3_LIST += sdm710
BOARD_IPAv3_LIST += msmnile
BOARD_IPAv3_LIST += $(MSMSTEPPE)
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)))
@ -12,23 +17,13 @@ include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../inc
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../ipanat/inc
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../hal/inc
ifeq ($(call is-platform-sdk-version-at-least,20),true)
LOCAL_C_INCLUDES += external/icu/icu4c/source/common
else
LOCAL_C_INCLUDES += external/icu4c/common
endif
#LOCAL_C_INCLUDES += external/dhcpcd
LOCAL_C_INCLUDES += external/libxml2/include
LOCAL_C_INCLUDES += external/libnetfilter_conntrack/include
LOCAL_C_INCLUDES += external/libnfnetlink/include
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_CFLAGS := -v
LOCAL_CFLAGS += -DFEATURE_IPA_ANDROID
LOCAL_CFLAGS += -DFEATURE_IPACM_RESTART
LOCAL_CFLAGS += -DFEATURE_IPACM_HAL -Wall -Werror -Wno-error=macro-redefined
ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DDEBUG
@ -43,7 +38,6 @@ LOCAL_CFLAGS += $(shell if [ -a $(filetoadd) ] ; then echo -include $(filetoadd)
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 \

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -123,6 +123,7 @@ void* MessageQueue::Process(void *param)
MessageQueue *MsgQueueExternal = NULL;
Message *item = NULL;
param = NULL;
const char *eventName = NULL;
IPACMDBG("MessageQueue::Process()\n");
@ -154,14 +155,22 @@ void* MessageQueue::Process(void *param)
item = MsgQueueExternal->dequeue();
if(item)
{
IPACMDBG("Get event %s from external queue.\n",
IPACM_Iface::ipacmcfg->getEventName(item->evt.data.event));
eventName = IPACM_Iface::ipacmcfg->getEventName(item->evt.data.event);
if (eventName != NULL)
{
IPACMDBG("Get event %s from external queue.\n",
eventName);
}
}
}
else
{
IPACMDBG("Get event %s from internal queue.\n",
IPACM_Iface::ipacmcfg->getEventName(item->evt.data.event));
eventName = IPACM_Iface::ipacmcfg->getEventName(item->evt.data.event);
if (eventName != NULL)
{
IPACMDBG("Get event %s from internal queue.\n",
eventName);
}
}
if(item == NULL)
@ -196,7 +205,7 @@ void* MessageQueue::Process(void *param)
return NULL;
}
IPACMDBG("Processing item %p event ID: %d\n",item,item->evt.data.event);
IPACMDBG("Processing item %pK event ID: %d\n",item,item->evt.data.event);
item->evt.callback_ptr(&item->evt.data);
delete item;
item = NULL;

View file

@ -106,6 +106,7 @@ 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_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE), /* ipacm_event_iface*/
__stringify(IPA_LAN_DELETE_SELF), /* ipacm_event_data_fid */
#ifdef FEATURE_L2TP
__stringify(IPA_ADD_VLAN_IFACE), /* ipa_ioc_vlan_iface_info */
@ -183,6 +184,7 @@ int IPACM_Config::Init(void)
{
IPACMERR("Failed opening %s.\n", DEVICE_NAME);
}
ver = GetIPAVer(true);
#ifdef FEATURE_IPACM_HAL
strlcpy(IPACM_config_file, "/vendor/etc/IPACM_cfg.xml", sizeof(IPACM_config_file));
#else
@ -466,7 +468,7 @@ int IPACM_Config::GetNatIfaces(int nIfaces, NatIfaces *pIfaces)
}
int IPACM_Config::AddNatIfaces(char *dev_name)
int IPACM_Config::AddNatIfaces(char *dev_name, ipa_ip_type ip_type)
{
int i;
/* Check if this iface already in NAT-iface*/
@ -476,7 +478,15 @@ int IPACM_Config::AddNatIfaces(char *dev_name)
pNatIfaces[i].iface_name,
sizeof(pNatIfaces[i].iface_name)) == 0)
{
IPACMDBG("Interface (%s) is add to nat iface already\n", dev_name);
IPACMDBG_H("Interface (%s) is add to nat iface already\n", dev_name);
if (ip_type == IPA_IP_v4) {
pNatIfaces[i].v4_up = true;
IPACMDBG_H("Change v4_up to (%d) \n", pNatIfaces[i].v4_up);
}
if (ip_type == IPA_IP_v6) {
pNatIfaces[i].v6_up = true;
IPACMDBG_H("Change v6_up to (%d) \n", pNatIfaces[i].v6_up);
}
return 0;
}
}
@ -493,8 +503,15 @@ int IPACM_Config::AddNatIfaces(char *dev_name)
IPACMDBG_H("Add Nat IfaceName: %s ,update nat-ifaces number: %d\n",
pNatIfaces[ipa_nat_iface_entries - 1].iface_name,
ipa_nat_iface_entries);
if (ip_type == IPA_IP_v4) {
pNatIfaces[ipa_nat_iface_entries - 1].v4_up = true;
IPACMDBG_H("Change v4_up to (%d) \n", pNatIfaces[ipa_nat_iface_entries - 1].v4_up);
}
if (ip_type == IPA_IP_v6) {
pNatIfaces[ipa_nat_iface_entries - 1].v6_up = true;
IPACMDBG_H("Change v6_up to (%d) \n", pNatIfaces[ipa_nat_iface_entries - 1].v6_up);
}
}
return 0;
}
@ -513,14 +530,20 @@ int IPACM_Config::DelNatIfaces(char *dev_name)
/* Reset the matched entry */
memset(pNatIfaces[i].iface_name, 0, IPA_IFACE_NAME_LEN);
pNatIfaces[i].v4_up = false;
pNatIfaces[i].v6_up = false;
for (; i < ipa_nat_iface_entries - 1; i++)
{
memcpy(pNatIfaces[i].iface_name,
pNatIfaces[i + 1].iface_name, IPA_IFACE_NAME_LEN);
pNatIfaces[i].v4_up = pNatIfaces[i + 1].v4_up;
pNatIfaces[i].v6_up = pNatIfaces[i + 1].v6_up;
/* Reset the copied entry */
memset(pNatIfaces[i + 1].iface_name, 0, IPA_IFACE_NAME_LEN);
pNatIfaces[i + 1].v4_up = false;
pNatIfaces[i + 1].v6_up = false;
}
ipa_nat_iface_entries--;
IPACMDBG_H("Update nat-ifaces number: %d\n", ipa_nat_iface_entries);
@ -533,23 +556,33 @@ int IPACM_Config::DelNatIfaces(char *dev_name)
return 0;
}
int IPACM_Config::CheckNatIfaces(const char *dev_name)
int IPACM_Config::CheckNatIfaces(const char *dev_name, ipa_ip_type ip_type)
{
int i = 0;
IPACMDBG_H("Check iface %s from NAT-ifaces, currently it has %d nat ifaces\n",
dev_name, ipa_nat_iface_entries);
IPACMDBG_H("Check iface %s for ip-type %d from NAT-ifaces, currently it has %d nat ifaces\n",
dev_name, ip_type, ipa_nat_iface_entries);
for (i = 0; i < ipa_nat_iface_entries; i++)
{
if (strcmp(dev_name, pNatIfaces[i].iface_name) == 0)
{
IPACMDBG_H("Find Nat IfaceName: %s ,previous nat-ifaces number: %d\n",
pNatIfaces[i].iface_name, ipa_nat_iface_entries);
IPACMDBG_H("Find Nat IfaceName: %s ,previous nat-ifaces number: %d, v4_up %d, v6_up %d \n",
pNatIfaces[i].iface_name, ipa_nat_iface_entries, pNatIfaces[i].v4_up, pNatIfaces[i].v6_up);
if (ip_type == IPA_IP_v4 && pNatIfaces[i].v4_up == true)
{
IPACMDBG_H(" v4_up=%d\n", pNatIfaces[i].v4_up);
return 0;
}
if (ip_type == IPA_IP_v6 && pNatIfaces[i].v6_up == true)
{
IPACMDBG_H(" v6_up=%d\n", pNatIfaces[i].v6_up);
return 0;
}
return -1;
}
}
IPACMDBG_H("Can't find Nat IfaceName: %s with total nat-ifaces number: %d\n",
dev_name, ipa_nat_iface_entries);
IPACMDBG_H("Can't find Nat IfaceName: %s for ip_type %d up with total nat-ifaces number: %d\n",
dev_name, ip_type, ipa_nat_iface_entries);
return -1;
}
@ -847,3 +880,21 @@ const char* IPACM_Config::getEventName(ipa_cm_event_id event_id)
return ipacm_event_name[event_id];
}
enum ipa_hw_type IPACM_Config::GetIPAVer(bool get)
{
int ret;
if(!get)
return ver;
ret = ioctl(m_fd, IPA_IOC_GET_HW_VERSION, &ver);
if(ret != 0)
{
IPACMERR("Failed to get IPA version with error %d.\n", ret);
ver = IPA_HW_None;
return IPA_HW_None;
}
IPACMDBG_H("IPA version is %d.\n", ver);
return ver;
}

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -177,8 +177,6 @@ int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Bridge_Addrs
/* retrieve bridge interface ipv4 address */
memset(&ifr, 0, sizeof(struct ifreq));
ifr.ifr_addr.sa_family = AF_INET;
(void)strlcpy(ifr.ifr_name, IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, sizeof(ifr.ifr_name));
IPACMDBG("bridge interface name (%s)\n", ifr.ifr_name);
if(strlen(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name) >= sizeof(ifr.ifr_name))
{
@ -187,6 +185,8 @@ int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Bridge_Addrs
close(fd);
return -1;
}
(void)strlcpy(ifr.ifr_name, IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, sizeof(ifr.ifr_name));
IPACMDBG("bridge interface name (%s)\n", ifr.ifr_name);
ret = ioctl(fd, SIOCGIFADDR, &ifr);
if (ret < 0)

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -373,7 +373,7 @@ void IPACM_ConntrackListener::TriggerWANUp(void *in_param)
if(nat_inst != NULL)
{
nat_inst->AddTable(wanup_data->ipv4_addr);
nat_inst->AddTable(wanup_data->ipv4_addr, wanup_data->mux_id);
}
IPACMDBG("creating nat threads\n");
@ -1037,9 +1037,9 @@ void IPACM_ConntrackListener::ProcessTCPorUDPMsg(
nat_entry.ct = ct;
nat_entry.type = type;
memset(&rule, 0, sizeof(rule));
IPACMDBG("Received type:%d with proto:%d\n", type, l4proto);
status = nfct_get_attr_u32(ct, ATTR_STATUS);
memset(&rule, 0, sizeof(rule));
IPACMDBG("Received type:%d with proto:%d\n", type, l4proto);
status = nfct_get_attr_u32(ct, ATTR_STATUS);
/* Retrieve Protocol */
rule.protocol = nfct_get_attr_u8(ct, ATTR_REPL_L4PROTO);
@ -1089,47 +1089,40 @@ void IPACM_ConntrackListener::ProcessTCPorUDPMsg(
#ifdef CT_OPT
HandleLan2Lan(ct, type, &rule);
#endif
return;
IPACMDBG("Neither source Nor destination nat\n");
goto IGNORE;
}
}
}
if(IPS_DST_NAT == status || IPS_SRC_NAT == status)
{
PopulateTCPorUDPEntry(ct, status, &rule);
rule.public_ip = wan_ipaddr;
}
else
{
IPACMDBG("Neither source Nor destination nat\n");
goto IGNORE;
}
PopulateTCPorUDPEntry(ct, status, &rule);
rule.public_ip = wan_ipaddr;
if (rule.private_ip != wan_ipaddr)
{
isAdd = AddIface(&rule, &nat_entry.isTempEntry);
if (!isAdd)
{
goto IGNORE;
}
}
else
{
if (isStaMode)
{
IPACMDBG("In STA mode, ignore connections destinated to STA interface\n");
goto IGNORE;
}
if (rule.private_ip != wan_ipaddr)
{
isAdd = AddIface(&rule, &nat_entry.isTempEntry);
if (!isAdd)
{
goto IGNORE;
}
}
else
{
if (isStaMode)
{
IPACMDBG("In STA mode, ignore connections destinated to STA interface\n");
goto IGNORE;
}
IPACMDBG("For embedded connections add dummy nat rule\n");
IPACMDBG("Change private port %d to %d\n",
rule.private_port, rule.public_port);
rule.private_port = rule.public_port;
}
IPACMDBG("For embedded connections add dummy nat rule\n");
IPACMDBG("Change private port %d to %d\n",
rule.private_port, rule.public_port);
rule.private_port = rule.public_port;
}
CheckSTAClient(&rule, &nat_entry.isTempEntry);
nat_entry.rule = &rule;
AddORDeleteNatEntry(&nat_entry);
return;
CheckSTAClient(&rule, &nat_entry.isTempEntry);
nat_entry.rule = &rule;
AddORDeleteNatEntry(&nat_entry);
return;
IGNORE:
IPACMDBG_H("ignoring below Nat Entry\n");

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -31,9 +31,13 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef FEATURE_IPACM_HAL
#include "IPACM_OffloadManager.h"
#endif
#include "IPACM_Iface.h"
#define INVALID_IP_ADDR 0x0
#define HDR_METADATA_MUX_ID_BMASK 0x00FF0000
#define HDR_METADATA_MUX_ID_SHFT 0x10
/* NatApp class Implementation */
NatApp *NatApp::pInstance = NULL;
NatApp::NatApp()
@ -90,11 +94,7 @@ int NatApp::Init(void)
}
memset(pALGPorts, 0, sizeof(ipacm_alg) * nALGPort);
if(pConfig->GetAlgPorts(nALGPort, pALGPorts) != 0)
{
IPACMERR("Unable to retrieve ALG prots\n");
goto fail;
}
pConfig->GetAlgPorts(nALGPort, pALGPorts);
IPACMDBG("Printing %d alg ports information\n", nALGPort);
for(int cnt=0; cnt<nALGPort; cnt++)
@ -102,12 +102,23 @@ int NatApp::Init(void)
IPACMDBG("%d: Proto[%d], port[%d]\n", cnt, pALGPorts[cnt].protocol, pALGPorts[cnt].port);
}
}
else
{
IPACMERR("Unable to retrieve ALG prot count\n");
goto fail;
}
return 0;
fail:
free(cache);
free(pALGPorts);
if(cache != NULL)
{
free(cache);
}
if(pALGPorts != NULL)
{
free(pALGPorts);
}
return -1;
}
@ -127,9 +138,14 @@ NatApp* NatApp::GetInstance()
return pInstance;
}
uint32_t NatApp::GenerateMetdata(uint8_t mux_id)
{
return (mux_id << HDR_METADATA_MUX_ID_SHFT) & HDR_METADATA_MUX_ID_BMASK;
}
/* NAT APP related object function definitions */
int NatApp::AddTable(uint32_t pub_ip)
int NatApp::AddTable(uint32_t pub_ip, uint8_t mux_id)
{
int ret;
int cnt = 0;
@ -151,6 +167,19 @@ int NatApp::AddTable(uint32_t pub_ip)
IPACMERR("unable to create nat table Error:%d\n", ret);
return ret;
}
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_v4_0) {
/* modify PDN 0 so it will hold the mux ID in the src metadata field */
ipa_nat_pdn_entry entry;
entry.dst_metadata = 0;
entry.src_metadata = GenerateMetdata(mux_id);
entry.public_ip = pub_ip;
ret = ipa_nat_modify_pdn(nat_table_hdl, 0, &entry);
if(ret)
{
IPACMERR("unable to modify PDN 0 entry Error:%d INIT_HDR_METADATA register values will be used!\n", ret);
}
}
/* Add back the cached NAT-entry */
if (pub_ip == pub_ip_addr_pre)

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -92,7 +92,7 @@ int IPACM_EvtDispatcher::PostEvt
IPACMDBG("Enqueing item\n");
MsgQueue->enqueue(item);
IPACMDBG("Enqueued item %p\n", item);
IPACMDBG("Enqueued item %pK\n", item);
if(pthread_cond_signal(&cond_var) != 0)
{
@ -141,7 +141,7 @@ void IPACM_EvtDispatcher::ProcessEvt(ipacm_cmd_q_data *data)
if(data->evt_data != NULL)
{
IPACMDBG("free the event:%d data: %p\n", data->event, data->evt_data);
IPACMDBG("free the event:%d data: %pK\n", data->event, data->evt_data);
free(data->evt_data);
}
return;

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -87,7 +87,7 @@ bool IPACM_Filtering::AddFilteringRule(struct ipa_ioc_add_flt_rule const *ruleTa
retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE, ruleTable);
if (retval != 0)
{
IPACMERR("Failed adding Filtering rule %p\n", ruleTable);
IPACMERR("Failed adding Filtering rule %pK\n", ruleTable);
PERROR("unable to add filter rule:");
for (int cnt = 0; cnt < ruleTable->num_rules; cnt++)
@ -110,21 +110,21 @@ bool IPACM_Filtering::AddFilteringRule(struct ipa_ioc_add_flt_rule const *ruleTa
}
}
IPACMDBG("Added Filtering rule %p\n", ruleTable);
IPACMDBG("Added Filtering rule %pK\n", ruleTable);
return true;
}
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);
#ifdef FEATURE_IPA_V3
int retval = 0;
retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE_AFTER, ruleTable);
for (int cnt = 0; cnt<ruleTable->num_rules; cnt++)
@ -138,10 +138,13 @@ bool IPACM_Filtering::AddFilteringRuleAfter(struct ipa_ioc_add_flt_rule_after co
if (retval != 0)
{
IPACMERR("Failed adding Filtering rule %p\n", ruleTable);
IPACMERR("Failed adding Filtering rule %pK\n", ruleTable);
return false;
}
IPACMDBG("Added Filtering rule %p\n", ruleTable);
IPACMDBG("Added Filtering rule %pK\n", ruleTable);
#else
if (ruleTable)
IPACMERR("Not support adding Filtering rule %pK\n", ruleTable);
#endif
return true;
}
@ -153,11 +156,11 @@ bool IPACM_Filtering::DeleteFilteringRule(struct ipa_ioc_del_flt_rule *ruleTable
retval = ioctl(fd, IPA_IOC_DEL_FLT_RULE, ruleTable);
if (retval != 0)
{
IPACMERR("Failed deleting Filtering rule %p\n", ruleTable);
IPACMERR("Failed deleting Filtering rule %pK\n", ruleTable);
return false;
}
IPACMDBG("Deleted Filtering rule %p\n", ruleTable);
IPACMDBG("Deleted Filtering rule %pK\n", ruleTable);
return true;
}
@ -447,7 +450,7 @@ bool IPACM_Filtering::AddWanDLFilteringRule(struct ipa_ioc_add_flt_rule const *r
ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE_EX, &qmi_rule_ex_msg);
if (ret != 0)
{
IPACMERR("Failed adding Filtering rule %p with ret %d\n ", &qmi_rule_ex_msg, ret);
IPACMERR("Failed adding Filtering rule %pK with ret %d\n ", &qmi_rule_ex_msg, ret);
close(fd_wwan_ioctl);
return false;
}
@ -471,12 +474,12 @@ bool IPACM_Filtering::SendFilteringRuleIndex(struct ipa_fltr_installed_notif_req
ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE_INDEX, table);
if (ret != 0)
{
IPACMERR("Failed adding filtering rule index %p with ret %d\n", table, ret);
IPACMERR("Failed adding filtering rule index %pK with ret %d\n", table, ret);
close(fd_wwan_ioctl);
return false;
}
IPACMDBG("Added Filtering rule index %p\n", table);
IPACMDBG("Added Filtering rule index %pK\n", table);
close(fd_wwan_ioctl);
return true;
}
@ -517,7 +520,7 @@ 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 %p\n", ruleTable);
IPACMERR("Failed modifying filtering rule %pK\n", ruleTable);
for (i = 0; i < ruleTable->num_rules; i++)
{

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -622,13 +622,6 @@ int IPACM_Iface::query_iface_property(void)
}
}
/* Add Natting iface to IPACM_Config if there is Rx/Tx property */
if (rx_prop != NULL || tx_prop != NULL)
{
IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name);
}
close(fd);
return res;
}
@ -653,26 +646,29 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
}
else
{
if(rx_prop != NULL)
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
{
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe],false);
}
else
{
/* only wlan may take software-path, not register Rx-property*/
if(strcmp(dev_name,dev_wlan0) == 0 || strcmp(dev_name,dev_wlan1) == 0)
if(rx_prop != NULL)
{
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
IPACMDBG_H("depend Got piperm index : %d \n", IPA_RM_RESOURCE_HSIC_PROD);
IPACM_Iface::ipacmcfg->AddRmDepend(IPA_RM_RESOURCE_HSIC_PROD,true);
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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe],false);
}
if(strcmp(dev_name,dev_ecm0) == 0)
else
{
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
IPACMDBG_H("depend Got piperm index : %d \n", IPA_RM_RESOURCE_USB_PROD);
IPACM_Iface::ipacmcfg->AddRmDepend(IPA_RM_RESOURCE_USB_PROD,true);
/* only wlan may take software-path, not register Rx-property*/
if(strcmp(dev_name,dev_wlan0) == 0 || strcmp(dev_name,dev_wlan1) == 0)
{
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
IPACMDBG_H("depend Got piperm index : %d \n", IPA_RM_RESOURCE_HSIC_PROD);
IPACM_Iface::ipacmcfg->AddRmDepend(IPA_RM_RESOURCE_HSIC_PROD,true);
}
if(strcmp(dev_name,dev_ecm0) == 0)
{
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
IPACMDBG_H("depend Got piperm index : %d \n", IPA_RM_RESOURCE_USB_PROD);
IPACM_Iface::ipacmcfg->AddRmDepend(IPA_RM_RESOURCE_USB_PROD,true);
}
}
}
}
@ -857,6 +853,20 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
memcpy(&(m_pFilteringTable->rules[3]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
#ifdef FEATURE_IPA_ANDROID
/* Add the ipv6 tcp fragment filtering rule. */
IPACMDBG_H("Adding IPv6 TCP fragment filter rule\n");
flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_DST_ADDR);
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_TCP;
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT;
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));
@ -898,17 +908,18 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
/* add TCP FIN rule*/
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_FIN_SHIFT);
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_FIN_SHIFT);
memcpy(&(m_pFilteringTable->rules[4]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
memcpy(&(m_pFilteringTable->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)<<TCP_SYN_SHIFT);
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_SYN_SHIFT);
memcpy(&(m_pFilteringTable->rules[5]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
memcpy(&(m_pFilteringTable->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)<<TCP_RST_SHIFT);
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_RST_SHIFT);
memcpy(&(m_pFilteringTable->rules[6]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
memcpy(&(m_pFilteringTable->rules[7]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
#endif
if (m_filtering.AddFilteringRule(m_pFilteringTable) == false)
{
@ -937,6 +948,12 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
}
}
/* Add Natting iface to IPACM_Config if there is Rx/Tx property */
if (rx_prop != NULL || tx_prop != NULL)
{
IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING for ip-family %d \n", dev_name, iptype);
IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, iptype);
}
fail:
free(m_pFilteringTable);
@ -1027,3 +1044,10 @@ void IPACM_Iface::config_ip_type(ipa_ip_type iptype)
return;
}
void IPACM_Iface::delete_iface(void)
{
IPACMDBG_H("netdev (%s):ipa_index (%d) instance close \n",
IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num);
delete this;
}

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -257,6 +257,12 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param)
{
IPACMDBG_H("Creating Lan interface\n");
IPACM_Lan *lan = new IPACM_Lan(ipa_interface_index);
if (lan->rx_prop == NULL && lan->tx_prop == NULL)
{
/* close the netdev instance if IPA not support*/
lan->delete_iface();
return IPACM_FAILURE;
}
IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, lan);
//IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, lan);
//IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, lan);
@ -365,6 +371,14 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param)
{
IPACMDBG_H("Creating WLan interface\n");
IPACM_Wlan *wl = new IPACM_Wlan(ipa_interface_index);
if (wl->rx_prop == NULL && wl->tx_prop == NULL)
{
/* reset the AP-iface category to unknown */
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = UNKNOWN_IF;
/* close the netdev instance if IPA not support*/
wl->delete_iface();
return IPACM_FAILURE;
}
IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, wl);
IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, wl);
IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT, wl);
@ -402,6 +416,9 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param)
IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_MCC, wl);
#else
IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, wl);
#endif
#ifdef FEATURE_IPACM_HAL
IPACM_EvtDispatcher::registr(IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE, wl);
#endif
/* IPA_LAN_DELETE_SELF should be always last */
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, wl);
@ -421,6 +438,14 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param)
if(is_sta_mode == WLAN_WAN)
{
w = new IPACM_Wan(ipa_interface_index, is_sta_mode, param->mac_addr);
if (w->rx_prop == NULL && w->tx_prop == NULL)
{
/* reset the AP-iface category to unknown */
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = UNKNOWN_IF;
/* close the netdev instance if IPA not support*/
w->delete_iface();
return IPACM_FAILURE;
}
}
else
{
@ -452,6 +477,7 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param)
IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_MCC, w);
#ifdef FEATURE_IPACM_HAL
IPACM_EvtDispatcher::registr(IPA_SSR_NOTICE, w);
IPACM_EvtDispatcher::registr(IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE, w);
#endif
#endif
}

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -193,6 +193,14 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
memset(&prefix, 0, sizeof(prefix));
#ifdef FEATURE_IPACM_HAL
/* check if Upstream was set before as WIFI with RNDIS case */
if(ipa_if_cate == LAN_IF && IPACM_Wan::backhaul_is_sta_mode == true) /* LTE */
{
IPACMDBG_H(" Skip the Upstream falg set on LAN instance (%d) with WIFI backhaul (%d)\n", ipa_if_cate, IPACM_Wan::backhaul_is_sta_mode ); /* RNDIS+WIFI not support on msm*/
return;
}
/* check if Upstream was set before */
if (IPACM_Wan::isWanUP(ipa_if_num))
{
@ -227,6 +235,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
}
int ipa_interface_index;
uint32_t i;
ipacm_ext_prop* ext_prop;
ipacm_event_iface_up_tehter* data_wan_tether;
@ -261,7 +270,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
if (rx_prop != NULL || tx_prop != NULL)
{
IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name);
IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_MAX);
}
}
break;
@ -332,6 +341,21 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
}
}
#endif
#ifdef FEATURE_ETH_BRIDGE_LE
if(rx_prop != NULL)
{
free(rx_prop);
}
if(tx_prop != NULL)
{
free(tx_prop);
}
if(iface_query != NULL)
{
free(iface_query);
}
#endif
delete this;
}
break;
@ -438,6 +462,18 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
} else {
IPACMDBG_H("Wan_V6 haven't up yet\n");
}
#else
/* check if Upstream was set before */
if (IPACM_Wan::isWanUP(ipa_if_num))
{
IPACMDBG_H("Upstream was set previously for ipv4, change is_upstream_set flag\n");
is_upstream_set[IPA_IP_v4] = true;
}
if (IPACM_Wan::isWanUP_V6(ipa_if_num))
{
IPACMDBG_H("Upstream was set previously for ipv6, change is_upstream_set flag\n");
is_upstream_set[IPA_IP_v6] = true;
}
#endif
/* Post event to NAT */
if (data->iptype == IPA_IP_v4)
@ -501,6 +537,45 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("IPA_HANDLE_WAN_UP_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
return;
}
#else /* not offload rndis on WIFI mode on MSM targets */
if (data_wan_tether->is_sta)
{
IPACMERR("Not support RNDIS offload on WIFI mode, dun install UL filter rules for WIFI mode\n");
/* clean rndis header, routing rules */
IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client);
for (i = 0; i < num_eth_client; i++)
{
/* First reset nat rules and then route rules */
if(get_client_memptr(eth_client, i)->ipv4_set == true)
{
IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, i)->v4_addr);
CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, i)->v4_addr);
}
if (delete_eth_rtrules(i, IPA_IP_v4))
IPACMERR("unbale to delete usb-client v4 route rules for index %d\n", i);
if (delete_eth_rtrules(i, IPA_IP_v6))
IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i);
IPACMDBG_H("Delete %d client header\n", num_eth_client);
if(get_client_memptr(eth_client, i)->ipv4_header_set == true)
{
if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v4)
== false)
IPACMERR("unbale to delete usb-client v4 header for index %d\n", i);
}
if(get_client_memptr(eth_client, i)->ipv6_header_set == true)
{
if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v6)
== false)
IPACMERR("unbale to delete usb-client v6 header for index %d\n", i);
}
} /* end of for loop */
return;
}
#endif
if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
{
@ -515,7 +590,8 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
if (data_wan_tether->is_sta == false)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
handle_wan_up_ex(ext_prop, IPA_IP_v4,
IPACM_Wan::getXlat_Mux_Id());
} else {
handle_wan_up(IPA_IP_v4);
}
@ -673,7 +749,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");
if (is_downstream_set[data->prefix.iptype] == false)
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);
is_downstream_set[data->prefix.iptype] = true;
@ -697,7 +773,14 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
if (IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(data->prefix.iptype);
handle_wan_up_ex(ext_prop, data->prefix.iptype, 0);
if (data->prefix.iptype == IPA_IP_v4)
{
handle_wan_up_ex(ext_prop, data->prefix.iptype,
IPACM_Wan::getXlat_Mux_Id());
}
else {
handle_wan_up_ex(ext_prop, data->prefix.iptype, 0);
}
} else {
handle_wan_up(data->prefix.iptype); /* STA */
}
@ -832,6 +915,14 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("Recieved IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT event \n");
IPACMDBG_H("check iface %s category: %d\n", dev_name, ipa_if_cate);
/* if RNDIS under WIFI mode in MSM, dun add RT rule*/
#ifdef FEATURE_IPACM_HAL
if(IPACM_Wan::backhaul_is_sta_mode == true) /* WIFI */
{
IPACMDBG_H(" dun construct header and RT-rules for RNDIS-PC in WIFI mode on MSM targets (STA %d) \n", IPACM_Wan::backhaul_is_sta_mode);
return;
}
#endif
if (ipa_interface_index == ipa_if_num && ipa_if_cate == ODU_IF)
{
IPACMDBG_H("ODU iface got v4-ip \n");
@ -860,7 +951,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
if (ipa_interface_index == ipa_if_num
#ifdef FEATURE_L2TP
|| is_vlan_event(data->iface_name) ||
|| is_vlan_event(data->iface_name)
|| (is_l2tp_event(data->iface_name) && ipa_if_cate == ODU_IF)
#endif
)
@ -887,10 +978,16 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
#ifdef FEATURE_L2TP
else if(is_l2tp_event(data->iface_name) && ipa_if_cate == ODU_IF)
{
if(tx_prop != NULL)
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
{
IPACMDBG_H("add rm dependency for L2TP interface.\n");
IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
if (tx_prop != NULL)
{
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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
}
}
eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->mac_addr, NULL, data->iface_name);
}
@ -1254,6 +1351,12 @@ int IPACM_Lan::handle_addr_evt(ipacm_event_data_addr *data)
/* initial multicast/broadcast/fragment filter rule */
init_fl_rule(data->iptype);
#ifdef FEATURE_L2TP
if(ipa_if_cate == WLAN_IF)
{
add_tcp_syn_flt_rule(data->iptype);
}
#endif
install_ipv4_icmp_flt_rule();
/* populate the flt rule offset for eth bridge */
@ -1345,6 +1448,17 @@ int IPACM_Lan::handle_addr_evt(ipacm_event_data_addr *data)
if (num_dft_rt_v6 == 0)
{
#ifdef FEATURE_L2TP
if(ipa_if_cate == WLAN_IF)
{
add_tcp_syn_flt_rule(data->iptype);
}
else if(ipa_if_cate == ODU_IF)
{
add_tcp_syn_flt_rule_l2tp(IPA_IP_v4);
add_tcp_syn_flt_rule_l2tp(IPA_IP_v6);
}
#endif
install_ipv6_icmp_flt_rule();
/* populate the flt rule offset for eth bridge */
@ -1663,9 +1777,11 @@ int IPACM_Lan::handle_wan_up_ex(ipacm_ext_prop *ext_prop, ipa_ip_type iptype, ui
IPACM_Config* ipacm_config = IPACM_Iface::ipacmcfg;
struct ipa_ioc_write_qmapid mux;
/* for newer versions metadata is overridden by NAT metadata replacement for IPAv4 and up */
/* this is still needed for IPv6 traffic in case qmapid need to be used */
if(rx_prop != NULL)
{
/* give mud ID to IPA-driver for WLAN/LAN pkts */
/* give mux ID of the default PDN to IPA-driver for WLAN/LAN pkts */
fd = open(IPA_DEVICE_NAME, O_RDWR);
if (0 == fd)
{
@ -2134,13 +2250,15 @@ int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptyp
&& get_client_memptr(eth_client, eth_index)->route_rule_set_v6 < get_client_memptr(eth_client, eth_index)->ipv6_set
))
{
/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
if (tx_prop != NULL)
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
{
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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
if (tx_prop != NULL)
{
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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
}
}
rt_rule = (struct ipa_ioc_add_rt_rule *)
calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
@ -2188,9 +2306,12 @@ int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptyp
rt_rule_entry->rule.hdr_hdl = get_client_memptr(eth_client, eth_index)->hdr_hdl_v4;
rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(eth_client, eth_index)->v4_addr;
rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
#ifdef FEATURE_IPA_V3
rt_rule_entry->rule.hashable = false;
#endif
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_v4_0)
{
rt_rule_entry->rule.hashable = true;
}
if (false == m_routing.AddRoutingRule(rt_rule))
{
IPACMERR("Routing rule addition failed!\n");
@ -2735,12 +2856,15 @@ int IPACM_Lan::handle_eth_client_down_evt(uint8_t *mac_addr)
/* Del RM dependency */
if(num_eth_client == 0)
{
/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule*/
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
if (tx_prop != NULL)
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
{
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]);
/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule*/
IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
if (tx_prop != NULL)
{
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]);
}
}
}
@ -2801,8 +2925,10 @@ int IPACM_Lan::handle_down_evt()
IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
handle_wan_down(IPACM_Wan::backhaul_is_sta_mode);
#ifdef FEATURE_IPA_ANDROID
#ifndef FEATURE_IPACM_HAL
/* Clean-up tethered-iface list */
IPACM_Wan::delete_tether_iface(IPA_IP_v4, ipa_if_num);
#endif
#endif
}
@ -2888,6 +3014,17 @@ int IPACM_Lan::handle_down_evt()
}
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
}
#ifdef FEATURE_L2TP
if(ipa_if_cate == ODU_IF)
{
if(m_filtering.DeleteFilteringHdls(tcp_syn_flt_rule_hdl, IPA_IP_v6, IPA_IP_MAX) == false)
{
IPACMERR("Error Deleting TCP SYN L2TP Filtering Rule, aborting...\n");
res = IPACM_FAILURE;
goto fail;
}
}
#endif
}
IPACMDBG_H("Finished delete default iface ipv6 filtering rules \n ");
@ -2924,14 +3061,16 @@ int IPACM_Lan::handle_down_evt()
/* free the edm clients cache */
IPACMDBG_H("Free ecm clients cache\n");
/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule */
IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
if (tx_prop != NULL)
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
{
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]);
/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule */
IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
if (tx_prop != NULL)
{
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]);
}
}
eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL, NULL, NULL);
/* Delete private subnet*/
@ -3015,21 +3154,26 @@ fail:
{
free(odu_route_rule_v6_hdl);
}
/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
if (rx_prop != NULL)
{
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
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]);
IPACMDBG_H("Finished delete dependency \n ");
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
{
/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
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]);
IPACMDBG_H("Finished delete dependency \n ");
}
#ifndef FEATURE_ETH_BRIDGE_LE
free(rx_prop);
#endif
}
if (eth_client != NULL)
{
free(eth_client);
}
#ifndef FEATURE_ETH_BRIDGE_LE
if (tx_prop != NULL)
{
free(tx_prop);
@ -3038,7 +3182,7 @@ fail:
{
free(iface_query);
}
#endif
is_active = false;
post_del_self_evt();
@ -3159,6 +3303,10 @@ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptyp
else
{
flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT;
/* NAT block will set the proper MUX ID in the metadata according to the relevant PDN */
if (IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_v4_0)
flt_rule_entry.rule.set_metadata = true;
}
}
else if(iptype == IPA_IP_v6)
@ -3194,46 +3342,46 @@ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptyp
#ifdef FEATURE_IPACM_HAL
/* add prefix equation in modem UL rules */
if(iptype == IPA_IP_v4)
if(iptype == IPA_IP_v4 && (flt_rule_entry.rule.eq_attrib.num_offset_meq_32 >= 0)
&& (flt_rule_entry.rule.eq_attrib.num_offset_meq_32 < IPA_IPFLTR_NUM_MEQ_32_EQNS))
{
flt_rule_entry.rule.eq_attrib.num_offset_meq_32++;
if(flt_rule_entry.rule.eq_attrib.num_offset_meq_32 <= IPA_IPFLTR_NUM_MEQ_32_EQNS)
{
eq_index = flt_rule_entry.rule.eq_attrib.num_offset_meq_32 - 1;
eq_index = flt_rule_entry.rule.eq_attrib.num_offset_meq_32 - 1;
#ifdef FEATURE_IPA_V3
if(eq_index == 0)
{
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<5);
}
else
{
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<6);
}
#else
if(eq_index == 0)
{
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<2);
}
else
{
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<3);
}
#endif
flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].offset = 12;
flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].mask = prefix[IPA_IP_v4].v4Mask;
flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].value = prefix[IPA_IP_v4].v4Addr;
if(eq_index == 0)
{
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<5);
}
else
{
IPACMERR("Run out of MEQ32 equation.\n");
flt_rule_entry.rule.eq_attrib.num_offset_meq_32--;
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<6);
}
#else
if(eq_index == 0)
{
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<2);
}
else
{
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<3);
}
#endif
flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].offset = 12;
flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].mask = prefix[IPA_IP_v4].v4Mask;
flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].value = prefix[IPA_IP_v4].v4Addr;
}
else if (flt_rule_entry.rule.eq_attrib.num_offset_meq_32 > IPA_IPFLTR_NUM_MEQ_32_EQNS)
{
IPACMERR("Run out of MEQ32 equation.\n");
flt_rule_entry.rule.eq_attrib.num_offset_meq_32--;
}
else
{
flt_rule_entry.rule.eq_attrib.num_offset_meq_128++;
if(flt_rule_entry.rule.eq_attrib.num_offset_meq_128 <= IPA_IPFLTR_NUM_MEQ_128_EQNS)
if ((flt_rule_entry.rule.eq_attrib.num_offset_meq_128 >= 0) &&
(flt_rule_entry.rule.eq_attrib.num_offset_meq_128
< IPA_IPFLTR_NUM_MEQ_128_EQNS))
{
flt_rule_entry.rule.eq_attrib.num_offset_meq_128++;
eq_index = flt_rule_entry.rule.eq_attrib.num_offset_meq_128 - 1;
#ifdef FEATURE_IPA_V3
if(eq_index == 0)
@ -3245,21 +3393,21 @@ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptyp
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<4);
}
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 0)
= prefix[IPA_IP_v6].v6Mask[3];
= prefix[IPA_IP_v6].v6Mask[3];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 4)
= prefix[IPA_IP_v6].v6Mask[2];
= prefix[IPA_IP_v6].v6Mask[2];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 8)
= prefix[IPA_IP_v6].v6Mask[1];
= prefix[IPA_IP_v6].v6Mask[1];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 12)
= prefix[IPA_IP_v6].v6Mask[0];
= prefix[IPA_IP_v6].v6Mask[0];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 0)
= prefix[IPA_IP_v6].v6Addr[3];
= prefix[IPA_IP_v6].v6Addr[3];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 4)
= prefix[IPA_IP_v6].v6Addr[2];
= prefix[IPA_IP_v6].v6Addr[2];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 8)
= prefix[IPA_IP_v6].v6Addr[1];
= prefix[IPA_IP_v6].v6Addr[1];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 12)
= prefix[IPA_IP_v6].v6Addr[0];
= prefix[IPA_IP_v6].v6Addr[0];
#else
if(eq_index == 0)
{
@ -3270,24 +3418,24 @@ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptyp
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<10);
}
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 0)
= prefix[IPA_IP_v6].v6Mask[0];
= prefix[IPA_IP_v6].v6Mask[0];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 4)
= prefix[IPA_IP_v6].v6Mask[1];
= prefix[IPA_IP_v6].v6Mask[1];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 8)
= prefix[IPA_IP_v6].v6Mask[2];
= prefix[IPA_IP_v6].v6Mask[2];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 12)
= prefix[IPA_IP_v6].v6Mask[3];
= prefix[IPA_IP_v6].v6Mask[3];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 0)
= prefix[IPA_IP_v6].v6Addr[0];
= prefix[IPA_IP_v6].v6Addr[0];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 4)
= prefix[IPA_IP_v6].v6Addr[1];
= prefix[IPA_IP_v6].v6Addr[1];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 8)
= prefix[IPA_IP_v6].v6Addr[2];
= prefix[IPA_IP_v6].v6Addr[2];
*(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 12)
= prefix[IPA_IP_v6].v6Addr[3];
= prefix[IPA_IP_v6].v6Addr[3];
#endif
flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].offset = 8;
}
}
else
{
IPACMERR("Run out of MEQ128 equation.\n");
@ -4335,7 +4483,7 @@ void IPACM_Lan::eth_bridge_post_event(ipa_cm_event_id evt, ipa_ip_type iptype, u
if(ipv6_addr)
{
IPACMDBG_H("IPv6 addr: %08x:%08x:%08x:%08x \n", ipv6_addr[0],
ipv6_addr[1], ipv6_addr[2], ipv6_addr[3]);
ipv6_addr[1], ipv6_addr[2], ipv6_addr[3]);
}
memset(&eth_bridge_evt, 0, sizeof(ipacm_cmd_q_data));
eth_bridge_evt.event = evt;
@ -4714,6 +4862,9 @@ int IPACM_Lan::eth_bridge_add_flt_rule(uint8_t *mac, uint32_t rt_tbl_hdl, ipa_ip
end:
free(pFilteringTable);
#else
IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
IPACMDBG_H("Not support rt_tbl_hdl %d flt_rule_hdl %p ip-type %d\n", rt_tbl_hdl, flt_rule_hdl, iptype);
#endif
return res;
}
@ -5207,6 +5358,12 @@ int IPACM_Lan::add_l2tp_rt_rule(ipa_ip_type iptype, uint8_t *dst_mac, uint32_t *
hdr_proc_ctx->hdr_hdl = hdr.hdl;
hdr_proc_ctx->l2tp_params.hdr_remove_param.hdr_len_remove = 62;
hdr_proc_ctx->l2tp_params.hdr_remove_param.eth_hdr_retained = 1;
hdr_proc_ctx->l2tp_params.is_dst_pipe_valid = 1;
hdr_proc_ctx->l2tp_params.dst_pipe = tx_prop->tx[0].dst_pipe;
IPACMDBG_H("Header_remove: hdr len %d, hdr retained %d, dst client: %d\n",
hdr_proc_ctx->l2tp_params.hdr_remove_param.hdr_len_remove,
hdr_proc_ctx->l2tp_params.hdr_remove_param.eth_hdr_retained,
hdr_proc_ctx->l2tp_params.dst_pipe);
if(m_header.AddHeaderProcCtx(hdr_proc_ctx_table) == false)
{
IPACMERR("Failed to add hdr proc ctx with status: %d\n", hdr_proc_ctx_table->proc_ctx[0].status);
@ -5567,3 +5724,127 @@ bool IPACM_Lan::is_unique_local_ipv6_addr(uint32_t* ipv6_addr)
return false;
}
#endif
/* add tcp syn flt rule */
int IPACM_Lan::add_tcp_syn_flt_rule(ipa_ip_type iptype)
{
int len;
struct ipa_flt_rule_add flt_rule_entry;
ipa_ioc_add_flt_rule *m_pFilteringTable;
if(rx_prop == NULL)
{
IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
return IPACM_SUCCESS;
}
len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len);
if(!m_pFilteringTable)
{
PERROR("Not enough memory.\n");
return IPACM_FAILURE;
}
memset(m_pFilteringTable, 0, len);
m_pFilteringTable->commit = 1;
m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
m_pFilteringTable->global = false;
m_pFilteringTable->ip = iptype;
m_pFilteringTable->num_rules = 1;
memset(&flt_rule_entry, 0, sizeof(flt_rule_entry));
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.retain_hdr = 1;
flt_rule_entry.flt_rule_hdl = -1;
flt_rule_entry.status = -1;
flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
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_TCP_SYN;
if(iptype == IPA_IP_v4)
{
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
flt_rule_entry.rule.attrib.u.v4.protocol = 6;
}
else
{
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
flt_rule_entry.rule.attrib.u.v6.next_hdr = 6;
}
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
if(false == m_filtering.AddFilteringRule(m_pFilteringTable))
{
IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
free(m_pFilteringTable);
return IPACM_FAILURE;
}
tcp_syn_flt_rule_hdl[iptype] = m_pFilteringTable->rules[0].flt_rule_hdl;
free(m_pFilteringTable);
return IPACM_SUCCESS;
}
/* add tcp syn flt rule for l2tp interface*/
int IPACM_Lan::add_tcp_syn_flt_rule_l2tp(ipa_ip_type inner_ip_type)
{
int len;
struct ipa_flt_rule_add flt_rule_entry;
ipa_ioc_add_flt_rule *m_pFilteringTable;
if(rx_prop == NULL)
{
IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
return IPACM_SUCCESS;
}
len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len);
if(!m_pFilteringTable)
{
PERROR("Not enough memory.\n");
return IPACM_FAILURE;
}
memset(m_pFilteringTable, 0, len);
m_pFilteringTable->commit = 1;
m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
m_pFilteringTable->global = false;
m_pFilteringTable->ip = IPA_IP_v6;
m_pFilteringTable->num_rules = 1;
memset(&flt_rule_entry, 0, sizeof(flt_rule_entry));
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.retain_hdr = 1;
flt_rule_entry.flt_rule_hdl = -1;
flt_rule_entry.status = -1;
flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
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_TCP_SYN_L2TP;
if(inner_ip_type == IPA_IP_v4)
{
flt_rule_entry.rule.attrib.ether_type = 0x0800;
}
else
{
flt_rule_entry.rule.attrib.ether_type = 0x86dd;
}
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
if(false == m_filtering.AddFilteringRule(m_pFilteringTable))
{
IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
free(m_pFilteringTable);
return IPACM_FAILURE;
}
tcp_syn_flt_rule_hdl[inner_ip_type] = m_pFilteringTable->rules[0].flt_rule_hdl;
free(m_pFilteringTable);
return IPACM_SUCCESS;
}

View file

@ -598,6 +598,7 @@ void IPACM_LanToLan::handle_add_l2tp_vlan_mapping(ipa_ioc_l2tp_vlan_mapping_info
list<l2tp_vlan_mapping_info>::iterator it_mapping;
list<vlan_iface_info>::iterator it_vlan;
list<IPACM_LanToLan_Iface>::iterator it_iface;
IPACM_LanToLan_Iface *l2tp_iface;
l2tp_vlan_mapping_info new_mapping;
bool has_l2tp_iface = false;
@ -641,6 +642,8 @@ void IPACM_LanToLan::handle_add_l2tp_vlan_mapping(ipa_ioc_l2tp_vlan_mapping_info
if(it_iface->set_l2tp_iface(data->vlan_iface_name) == true)
{
has_l2tp_iface = true;
l2tp_iface = &(*it_iface);
break;
}
}
@ -655,6 +658,7 @@ void IPACM_LanToLan::handle_add_l2tp_vlan_mapping(ipa_ioc_l2tp_vlan_mapping_info
it_iface->handle_l2tp_enable();
}
}
l2tp_iface->switch_to_l2tp_iface();
}
return;
}
@ -1974,7 +1978,6 @@ bool IPACM_LanToLan_Iface::set_l2tp_iface(char *vlan_iface_name)
{
IPACMDBG_H("This interface is l2tp interface.\n");
m_is_l2tp_iface = true;
switch_to_l2tp_iface();
}
}
return m_is_l2tp_iface;

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -109,6 +109,12 @@ int ipa_get_if_index(char *if_name, int *if_index);
IPACM_Neighbor *neigh;
IPACM_IfaceManager *ifacemgr;
#ifdef FEATURE_IPACM_RESTART
int ipa_reset();
/* support ipacm restart */
int ipa_query_wlan_client();
#endif
#ifdef FEATURE_IPACM_HAL
IPACM_OffloadManager* OffloadMng;
HAL *hal;
@ -233,7 +239,9 @@ void* ipa_driver_msg_notifier(void *param)
struct ipa_wlan_msg_ex *event_ex= NULL;
struct ipa_get_data_stats_resp_msg_v01 event_data_stats;
struct ipa_get_apn_data_stats_resp_msg_v01 event_network_stats;
#ifdef FEATURE_IPACM_HAL
IPACM_OffloadManager* OffloadMng;
#endif
ipacm_cmd_q_data evt_data;
ipacm_event_data_mac *data = NULL;
@ -727,6 +735,13 @@ void* ipa_driver_msg_notifier(void *param)
OffloadMng->elrInstance->onOffloadSupportAvailable();
}
continue;
#ifdef IPA_WLAN_FW_SSR_EVENT_MAX
case WLAN_FWR_SSR_BEFORE_SHUTDOWN:
IPACMDBG_H("Received WLAN_FWR_SSR_BEFORE_SHUTDOWN\n");
evt_data.event = IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE;
evt_data.evt_data = NULL;
break;
#endif
#endif
#ifdef FEATURE_L2TP
case ADD_VLAN_IFACE:
@ -845,9 +860,13 @@ int main(int argc, char **argv)
(void)argc;
(void)argv;
#ifdef FEATURE_IPACM_RESTART
IPACMDBG_H("RESET IPA-HW rules\n");
ipa_reset();
#endif
neigh = new IPACM_Neighbor();
ifacemgr = new IPACM_IfaceManager();
#ifdef FEATURE_IPACM_HAL
OffloadMng = IPACM_OffloadManager::GetInstance();
hal = HAL::makeIPAHAL(1, OffloadMng);
@ -1049,3 +1068,25 @@ int ipa_get_if_index
close(fd);
return IPACM_SUCCESS;
}
#ifdef FEATURE_IPACM_RESTART
int ipa_reset()
{
int fd = -1;
if ((fd = open(IPA_DEVICE_NAME, O_RDWR)) < 0) {
IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
return IPACM_FAILURE;
}
if (ioctl(fd, IPA_IOC_CLEANUP) < 0) {
IPACMERR("IOCTL IPA_IOC_CLEANUP call failed: %s \n", strerror(errno));
close(fd);
return IPACM_FAILURE;
}
IPACMDBG_H("send IPA_IOC_CLEANUP \n");
close(fd);
return IPACM_SUCCESS;
}
#endif

View file

@ -686,7 +686,8 @@ static int ipa_nl_decode_nlmsg
evt_data.evt_data = data_fid;
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
/* Andorid platform will use events from usb-driver directly */
#ifndef FEATURE_IPA_ANDROID
/* Add IPACM support for ECM plug-in/plug_out */
/*--------------------------------------------------------------------------
Check if the interface is running.If its a RTM_NEWLINK and the interface
@ -711,14 +712,20 @@ static int ipa_nl_decode_nlmsg
free(data_fid);
return IPACM_FAILURE;
}
IPACMDBG("Got a usb link_up event (Interface %s, %d) \n", dev_name, msg_ptr->nl_link_info.metainfo.ifi_index);
IPACMDBG_H("Got a usb link_up event (Interface %s, %d) \n", dev_name, msg_ptr->nl_link_info.metainfo.ifi_index);
/* We don't expect change in iff_flags for rmnet_data interfaces. */
if (!strncmp(dev_name,"rmnet_data",strlen("rmnet_data")))
{
IPACMERR("Don't expect iff_flags change for rmnet_data interface. IGNORE\n");
return IPACM_FAILURE;
}
/*--------------------------------------------------------------------------
Post LAN iface (ECM) link up event
---------------------------------------------------------------------------*/
evt_data.event = IPA_USB_LINK_UP_EVENT;
evt_data.evt_data = data_fid;
IPACMDBG_H("Posting usb IPA_LINK_UP_EVENT with if index: %d\n",
IPACMDBG_H("Posting usb IPA_USB_LINK_UP_EVENT with if index: %d\n",
data_fid->if_index);
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
@ -749,6 +756,7 @@ static int ipa_nl_decode_nlmsg
data_fid->if_index);
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
#endif /* not defined(FEATURE_IPA_ANDROID)*/
}
break;

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2017, The Linux Foundation. All rights reserved.
Copyright (c) 2017-2018, 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
@ -196,6 +196,7 @@ RET IPACM_OffloadManager::addDownstream(const char * downstream_name, const Pref
int index;
ipacm_cmd_q_data evt;
ipacm_event_ipahal_stream *evt_data;
bool cache_need = false;
IPACMDBG_H("addDownstream name(%s), ip-family(%d) \n", downstream_name, prefix.fam);
@ -214,6 +215,7 @@ RET IPACM_OffloadManager::addDownstream(const char * downstream_name, const Pref
IPACMERR("fail to get iface index.\n");
return FAIL_INPUT_CHECK;
}
/* Iface is valid, add to list if not present */
if (std::find(valid_ifaces.begin(), valid_ifaces.end(), std::string(downstream_name)) == valid_ifaces.end())
{
@ -222,10 +224,16 @@ RET IPACM_OffloadManager::addDownstream(const char * downstream_name, const Pref
IPACMDBG_H("add iface(%s) to list\n", downstream_name);
}
/* check if downstream netdev driver finished its configuration on IPA-HW */
if (IPACM_Iface::ipacmcfg->CheckNatIfaces(downstream_name))
/* check if upstream netdev driver finished its configuration on IPA-HW for ipv4 and ipv6 */
if (prefix.fam == V4 && IPACM_Iface::ipacmcfg->CheckNatIfaces(downstream_name, IPA_IP_v4))
cache_need = true;
if (prefix.fam == V6 && IPACM_Iface::ipacmcfg->CheckNatIfaces(downstream_name, IPA_IP_v6))
cache_need = true;
if (cache_need)
{
IPACMDBG_H("addDownstream name(%s) currently not support in ipa \n", downstream_name);
/* copy to the cache */
for(int i = 0; i < MAX_EVENT_CACHE ;i++)
{
@ -342,6 +350,7 @@ RET IPACM_OffloadManager::setUpstream(const char *upstream_name, const Prefix& g
{
int index;
RET result = SUCCESS;
bool cache_need = false;
/* if interface name is NULL, default route is removed */
if(upstream_name != NULL)
@ -355,8 +364,16 @@ RET IPACM_OffloadManager::setUpstream(const char *upstream_name, const Prefix& g
if(upstream_name == NULL)
{
if (default_gw_index == INVALID_IFACE) {
result = FAIL_INPUT_CHECK;
for (index = 0; index < MAX_EVENT_CACHE; index++) {
if (event_cache[index].valid == true &&
event_cache[index ].event == IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT) {
event_cache[index].valid = false;
result = SUCCESS;
}
}
IPACMERR("no previous upstream set before\n");
return FAIL_INPUT_CHECK;
return result;
}
if (gw_addr_v4.fam == V4 && upstream_v4_up == true) {
IPACMDBG_H("clean upstream for ipv4-fam(%d) upstream_v4_up(%d)\n", gw_addr_v4.fam, upstream_v4_up);
@ -379,10 +396,19 @@ RET IPACM_OffloadManager::setUpstream(const char *upstream_name, const Prefix& g
return FAIL_INPUT_CHECK;
}
/* check if downstream netdev driver finished its configuration on IPA-HW */
if (IPACM_Iface::ipacmcfg->CheckNatIfaces(upstream_name))
/* check if upstream netdev driver finished its configuration on IPA-HW for ipv4 and ipv6 */
if (gw_addr_v4.fam == V4 && IPACM_Iface::ipacmcfg->CheckNatIfaces(upstream_name, IPA_IP_v4))
cache_need = true;
if (gw_addr_v6.fam == V6 && IPACM_Iface::ipacmcfg->CheckNatIfaces(upstream_name, IPA_IP_v6))
cache_need = true;
if (cache_need)
{
IPACMDBG_H("setUpstream name(%s) currently not support in ipa \n", upstream_name);
#ifdef FEATURE_IPACM_RESTART
/* add ipacm restart support */
push_iface_up(upstream_name, true);
#endif
/* copy to the cache */
for(int i = 0; i < MAX_EVENT_CACHE ;i++)
{
@ -395,7 +421,7 @@ RET IPACM_OffloadManager::setUpstream(const char *upstream_name, const Prefix& g
memcpy(&event_cache[latest_cache_index].prefix_cache, &gw_addr_v4, sizeof(event_cache[latest_cache_index].prefix_cache));
memcpy(&event_cache[latest_cache_index].prefix_cache_v6, &gw_addr_v6, sizeof(event_cache[latest_cache_index].prefix_cache_v6));
if (gw_addr_v4.fam == V4) {
IPACMDBG_H("cache event(%d) ipv4 fateway: (%x) dev(%s) on entry (%d)\n",
IPACMDBG_H("cache event(%d) ipv4 gateway: (%x) dev(%s) on entry (%d)\n",
event_cache[latest_cache_index].event,
event_cache[latest_cache_index].prefix_cache.v4Addr,
event_cache[latest_cache_index].dev_name,
@ -546,7 +572,7 @@ RET IPACM_OffloadManager::stopAllOffload()
RET IPACM_OffloadManager::setQuota(const char * upstream_name /* upstream */, uint64_t mb/* limit */)
{
wan_ioctl_set_data_quota quota;
int fd = -1,rc = 0;
int fd = -1, rc = 0, err_type = 0;
if ((fd = open(DEVICE_NAME, O_RDWR)) < 0)
{
@ -570,9 +596,10 @@ RET IPACM_OffloadManager::setQuota(const char * upstream_name /* upstream */, ui
if(rc != 0)
{
err_type = errno;
close(fd);
IPACMERR("IOCTL WAN_IOCTL_SET_DATA_QUOTA call failed: %s rc: %d\n", strerror(errno),rc);
if (errno == ENODEV) {
IPACMERR("IOCTL WAN_IOCTL_SET_DATA_QUOTA call failed: %s err_type: %d\n", strerror(err_type), err_type);
if (err_type == ENODEV) {
IPACMDBG_H("Invalid argument.\n");
return FAIL_UNSUPPORTED;
}
@ -648,9 +675,15 @@ int IPACM_OffloadManager::post_route_evt(enum ipa_ip_type iptype, int index, ipa
IPACMDBG_H("IPV6 gateway: %08x:%08x:%08x:%08x \n",
evt_data_route->ipv6_addr_gw[0], evt_data_route->ipv6_addr_gw[1], evt_data_route->ipv6_addr_gw[2], evt_data_route->ipv6_addr_gw[3]);
#endif
IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) tether_fid(%d) ip-type(%d)\n", evt_data_route->if_index,
if (event == IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT) {
IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) tether_fid(%d) ip-type(%d)\n", evt_data_route->if_index,
evt_data_route->if_index_tether, evt_data_route->iptype);
}
else if (event == IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT) {
IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL: fid(%d) tether_fid(%d) ip-type(%d)\n",
evt_data_route->if_index,
evt_data_route->if_index_tether, evt_data_route->iptype);
}
memset(&evt, 0, sizeof(evt));
evt.evt_data = (void*)evt_data_route;
evt.event = event;
@ -711,9 +744,8 @@ int IPACM_OffloadManager::resetTetherStats(const char * upstream_name /* upstrea
return FAIL_INPUT_CHECK;
}
stats.reset_stats = true;
if (ioctl(fd, WAN_IOC_RESET_TETHER_STATS, &stats) < 0) {
IPACMERR("IOCTL WAN_IOC_RESET_TETHER_STATS call failed: %s", strerror(errno));
IPACMERR("IOCTL WAN_IOC_RESET_TETHER_STATS call failed: %s", strerror(errno));
close(fd);
return FAIL_HARDWARE;
}
@ -762,3 +794,142 @@ bool IPACM_OffloadManager::search_framwork_cache(char * interface_name)
IPACMDBG_H(" not found netdev (%s) has cached event\n", interface_name);
return rel;
}
#ifdef FEATURE_IPACM_RESTART
int IPACM_OffloadManager::push_iface_up(const char * if_name, bool upstream)
{
ipacm_cmd_q_data evt_data;
ipacm_event_data_fid *data_fid = NULL;
ipacm_event_data_mac *data = NULL;
int index;
IPACMDBG_H("name %s, upstream %d\n",
if_name, upstream);
if(ipa_get_if_index(if_name, &index))
{
IPACMERR("netdev(%s) not registered ignored\n", if_name);
return SUCCESS;
}
if(strncmp(if_name, "rmnet_data", 10) == 0 && upstream)
{
data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
if(data_fid == NULL)
{
IPACMERR("unable to allocate memory for event data_fid\n");
return FAIL_HARDWARE;
}
data_fid->if_index = index;
evt_data.event = IPA_LINK_UP_EVENT;
evt_data.evt_data = data_fid;
IPACMDBG_H("Posting IPA_LINK_UP_EVENT with if index: %d\n",
data_fid->if_index);
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
if(strncmp(if_name, "rndis", 5) == 0 && !upstream)
{
data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
if(data_fid == NULL)
{
IPACMERR("unable to allocate memory for event data_fid\n");
return FAIL_HARDWARE;
}
data_fid->if_index = index;
evt_data.event = IPA_USB_LINK_UP_EVENT;
evt_data.evt_data = data_fid;
IPACMDBG_H("Posting usb IPA_LINK_UP_EVENT with if index: %d\n",
data_fid->if_index);
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
if((strncmp(if_name, "softap", 6) == 0 || strncmp(if_name, "wlan", 4) == 0 ) && !upstream)
{
data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
if(data_fid == NULL)
{
IPACMERR("unable to allocate memory for event data_fid\n");
return FAIL_HARDWARE;
}
data_fid->if_index = index;
evt_data.event = IPA_WLAN_AP_LINK_UP_EVENT;
evt_data.evt_data = data_fid;
IPACMDBG_H("Posting IPA_WLAN_AP_LINK_UP_EVENT with if index: %d\n",
data_fid->if_index);
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
if(strncmp(if_name, "wlan", 4) == 0 && upstream)
{
data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
if(data == NULL)
{
IPACMERR("unable to allocate memory for event_wlan data\n");
return FAIL_HARDWARE;
}
data->if_index = index;
evt_data.event = IPA_WLAN_STA_LINK_UP_EVENT;
evt_data.evt_data = data;
IPACMDBG_H("Posting IPA_WLAN_STA_LINK_UP_EVENT with if index: %d\n",
data->if_index);
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
return IPACM_SUCCESS;
}
#endif
bool IPACM_OffloadManager::push_framework_event(const char * if_name, _ipacm_offload_prefix prefix)
{
bool ret = false;
for(int i = 0; i < MAX_EVENT_CACHE ;i++)
{
if((latest_cache_index >= 0) && (latest_cache_index < MAX_EVENT_CACHE) &&
(event_cache[latest_cache_index].valid == false))
{
//do the copy
event_cache[latest_cache_index].valid = true;
event_cache[latest_cache_index].event = IPA_DOWNSTREAM_ADD;
memcpy(event_cache[latest_cache_index].dev_name, if_name,
sizeof(event_cache[latest_cache_index].dev_name));
memcpy(&event_cache[latest_cache_index].prefix_cache, &prefix,
sizeof(event_cache[latest_cache_index].prefix_cache));
if (prefix.iptype == IPA_IP_v4) {
IPACMDBG_H("cache event(%d) subnet info v4Addr (%x) v4Mask (%x) dev(%s) on entry (%d)\n",
event_cache[latest_cache_index].event,
event_cache[latest_cache_index].prefix_cache.v4Addr,
event_cache[latest_cache_index].prefix_cache.v4Mask,
event_cache[latest_cache_index].dev_name,
latest_cache_index);
} else {
IPACMDBG_H("cache event (%d) v6Addr: %08x:%08x:%08x:%08x \n",
event_cache[latest_cache_index].event,
event_cache[latest_cache_index].prefix_cache.v6Addr[0],
event_cache[latest_cache_index].prefix_cache.v6Addr[1],
event_cache[latest_cache_index].prefix_cache.v6Addr[2],
event_cache[latest_cache_index].prefix_cache.v6Addr[3]);
IPACMDBG_H("subnet v6Mask: %08x:%08x:%08x:%08x dev(%s) on entry(%d),\n",
event_cache[latest_cache_index].prefix_cache.v6Mask[0],
event_cache[latest_cache_index].prefix_cache.v6Mask[1],
event_cache[latest_cache_index].prefix_cache.v6Mask[2],
event_cache[latest_cache_index].prefix_cache.v6Mask[3],
event_cache[latest_cache_index].dev_name,
latest_cache_index);
}
latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
ret = true;
break;
}
latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
if(i == MAX_EVENT_CACHE - 1)
{
IPACMDBG_H(" run out of event cache (%d)\n", i);
ret = false;
}
}
return ret;
}

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013, The Linux Foundation. All rights reserved.
Copyright (c) 2013, 2018 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
@ -62,6 +62,8 @@ uint32_t IPACM_Wan::curr_wan_ip = 0;
int IPACM_Wan::num_v4_flt_rule = 0;
int IPACM_Wan::num_v6_flt_rule = 0;
int IPACM_Wan::ipa_pm_q6_check = 0;
struct ipa_flt_rule_add IPACM_Wan::flt_rule_v4[IPA_MAX_FLT_RULE];
struct ipa_flt_rule_add IPACM_Wan::flt_rule_v6[IPA_MAX_FLT_RULE];
@ -172,12 +174,15 @@ IPACM_Wan::IPACM_Wan(int iface_index,
IPACMDBG(" IPACM->IPACM_Wan_eMBMS(%d)\n", ipa_if_num);
embms_is_on = true;
install_wan_filtering_rule(false);
/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
if(tx_prop != NULL)
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
{
IPACMDBG_H("dev %s add 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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
if(tx_prop != NULL)
{
IPACMDBG_H("dev %s add 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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
}
}
}
else
@ -509,12 +514,12 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
}
#ifdef FEATURE_IPACM_HAL
/* check if having pending add_downstream cache*/
/* check if having pending set_upstream cache*/
OffloadMng = IPACM_OffloadManager::GetInstance();
if (OffloadMng == NULL) {
IPACMERR("failed to get IPACM_OffloadManager instance !\n");
} else {
IPACMDBG_H(" check iface %s if having add_downstream cache events\n", dev_name);
IPACMDBG_H(" check iface %s if having set_upstream cache events\n", dev_name);
OffloadMng->search_framwork_cache(dev_name);
}
#endif
@ -1263,6 +1268,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
#ifdef FEATURE_IPACM_HAL
/* WA for WLAN to clean up NAT instance during SSR */
case IPA_SSR_NOTICE: //sky
case IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE:
IPACMDBG_H("Received IPA_SSR_NOTICE event.\n");
if(m_is_sta_mode == WLAN_WAN)
{
@ -1288,7 +1294,11 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
const int NUM = 1;
ipacm_cmd_q_data evt_data;
struct ipa_ioc_get_hdr hdr;
#ifdef WAN_IOC_NOTIFY_WAN_STATE //resolve compile issue on 4.9 kernel
struct wan_ioctl_notify_wan_state wan_state;
int fd_wwan_ioctl;
memset(&wan_state, 0, sizeof(wan_state));
#endif
IPACMDBG_H("ip-type:%d\n", iptype);
/* copy header from tx-property, see if partial or not */
@ -1619,7 +1629,11 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
{
IPACM_Wan::xlat_mux_id = 0;
wanup_data->xlat_mux_id = 0;
IPACMDBG_H("No xlat configuratio:\n");
if(m_is_sta_mode == Q6_WAN)
wanup_data->mux_id = ext_prop->ext[0].mux_id;
else
wanup_data->mux_id = 0;
IPACMDBG_H("No xlat configuration\n");
}
evt_data.event = IPA_HANDLE_WAN_UP;
evt_data.evt_data = (void *)wanup_data;
@ -1664,12 +1678,37 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
evt_data.evt_data = (void *)wanup_data;
IPACM_EvtDispatcher::PostEvt(&evt_data);
}
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
{
/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
IPACMDBG_H("dev %s add 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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
#ifdef WAN_IOC_NOTIFY_WAN_STATE
} else {
if (m_is_sta_mode == Q6_WAN && ipa_pm_q6_check == 0)
{
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 up to IPA_PM\n");
wan_state.up = true;
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);
}
ipa_pm_q6_check++;
IPACMDBG_H("update ipa_pm_q6_check to %d\n", ipa_pm_q6_check);
/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
IPACMDBG_H("dev %s add 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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
}
#else
}
#endif
if(rt_rule != NULL)
{
free(rt_rule);
@ -1709,6 +1748,7 @@ int IPACM_Wan::post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether)
if (iptype == IPA_IP_v4)
{
evt_data.event = IPA_HANDLE_WAN_UP_TETHER;
#ifndef FEATURE_IPACM_HAL
/* Add support tether ifaces to its array*/
IPACM_Wan::ipa_if_num_tether_v4[IPACM_Wan::ipa_if_num_tether_v4_total] = ipa_if_num_tether;
IPACMDBG_H("adding tether iface(%s) ipa_if_num_tether_v4_total(%d) on wan_iface(%s)\n",
@ -1716,11 +1756,13 @@ int IPACM_Wan::post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether)
IPACM_Wan::ipa_if_num_tether_v4_total,
IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
IPACM_Wan::ipa_if_num_tether_v4_total++;
#endif
}
else
{
evt_data.event = IPA_HANDLE_WAN_UP_V6_TETHER;
memcpy(wanup_data->ipv6_prefix, ipv6_prefix, sizeof(wanup_data->ipv6_prefix));
#ifndef FEATURE_IPACM_HAL
/* Add support tether ifaces to its array*/
IPACM_Wan::ipa_if_num_tether_v6[IPACM_Wan::ipa_if_num_tether_v6_total] = ipa_if_num_tether;
IPACMDBG_H("adding tether iface(%s) ipa_if_num_tether_v6_total(%d) on wan_iface(%s)\n",
@ -1728,6 +1770,7 @@ int IPACM_Wan::post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether)
IPACM_Wan::ipa_if_num_tether_v6_total,
IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
IPACM_Wan::ipa_if_num_tether_v6_total++;
#endif
}
evt_data.evt_data = (void *)wanup_data;
IPACM_EvtDispatcher::PostEvt(&evt_data);
@ -1766,22 +1809,26 @@ int IPACM_Wan::post_wan_down_tether_evt(ipa_ip_type iptype, int ipa_if_num_tethe
if (iptype == IPA_IP_v4)
{
#ifndef FEATURE_IPACM_HAL
if(delete_tether_iface(iptype, ipa_if_num_tether))
{
IPACMDBG_H("Not finding the tethered client on ipv4.\n");
free(wandown_data);
return IPACM_SUCCESS;
}
#endif
evt_data.event = IPA_HANDLE_WAN_DOWN_TETHER;
}
else
{
#ifndef FEATURE_IPACM_HAL
if(delete_tether_iface(iptype, ipa_if_num_tether))
{
IPACMDBG_H("Not finding the tethered client on ipv6.\n");
free(wandown_data);
return IPACM_SUCCESS;
}
#endif
evt_data.event = IPA_HANDLE_WAN_DOWN_V6_TETHER;
}
evt_data.evt_data = (void *)wandown_data;
@ -3202,6 +3249,13 @@ int IPACM_Wan::init_fl_rule_ex(ipa_ip_type iptype)
}
install_wan_filtering_rule(false);
/* Add Natting iface to IPACM_Config if there is Rx/Tx property */
if (rx_prop != NULL || tx_prop != NULL)
{
IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, iptype);
}
fail:
return res;
}
@ -3745,8 +3799,62 @@ int IPACM_Wan::add_dft_filtering_rule(struct ipa_flt_rule_add *rules, int rule_o
memcpy(&(rules[rule_offset + 2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
/* Add the fragment filtering rule. */
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;
#ifdef FEATURE_IPA_V3
flt_rule_entry.rule.hashable = true;
#endif
flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
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;
flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
/* Configuring fragment Filtering Rule */
memcpy(&flt_rule_entry.rule.attrib,
&rx_prop->rx[0].attrib,
sizeof(flt_rule_entry.rule.attrib));
/* remove meta data mask since we only install default flt rules once for all modem PDN*/
flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT;
memset(&flt_eq, 0, sizeof(flt_eq));
memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
flt_eq.ip = iptype;
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));
memcpy(&(rules[rule_offset + 3]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
#ifdef FEATURE_IPA_ANDROID
IPACM_Wan::num_v6_flt_rule += IPA_V2_NUM_MULTICAST_WAN_FILTER_RULE_IPV6;
IPACMDBG_H("Constructed %d default filtering rules for ip type %d\n", IPA_V2_NUM_MULTICAST_WAN_FILTER_RULE_IPV6, iptype);
#else
IPACM_Wan::num_v6_flt_rule += IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6;
IPACMDBG_H("Constructed %d default filtering rules for ip type %d\n",
IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6, iptype);
#endif
IPACM_Wan::num_v6_flt_rule += IPA_V2_NUM_FRAG_WAN_FILTER_RULE_IPV6;
IPACMDBG_H("Constructed %d default filtering rules for ip type %d\n",
IPA_V2_NUM_FRAG_WAN_FILTER_RULE_IPV6, iptype);
}
fail:
@ -3795,8 +3903,9 @@ int IPACM_Wan::add_tcpv6_filtering_rule(struct ipa_flt_rule_add *rules, int rule
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));
@ -3841,8 +3950,10 @@ int IPACM_Wan::add_tcpv6_filtering_rule(struct ipa_flt_rule_add *rules, int rule
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_RST_SHIFT);
memcpy(&(rules[rule_offset + 2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
#ifdef FEATURE_IPA_ANDROID
IPACM_Wan::num_v6_flt_rule += IPA_V2_NUM_TCP_WAN_FILTER_RULE_IPV6;
IPACMDBG_H("Constructed %d ICMP filtering rules for ip type %d\n", IPA_V2_NUM_TCP_WAN_FILTER_RULE_IPV6, IPA_IP_v6);
#endif
fail:
return res;
@ -3989,12 +4100,13 @@ 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)))
{
/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
IPACMDBG_H("dev %s add 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]);
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]);
}
for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
{
if(iptype != tx_prop->tx[tx_index].ip)
@ -4118,6 +4230,11 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype)
int IPACM_Wan::handle_route_del_evt_ex(ipa_ip_type iptype)
{
ipacm_cmd_q_data evt_data;
#ifdef WAN_IOC_NOTIFY_WAN_STATE
struct wan_ioctl_notify_wan_state wan_state;
int fd_wwan_ioctl;
memset(&wan_state, 0, sizeof(wan_state));
#endif
IPACMDBG_H("got handle_route_del_evt_ex with ip-family:%d \n", iptype);
@ -4133,12 +4250,38 @@ int IPACM_Wan::handle_route_del_evt_ex(ipa_ip_type iptype)
if (((iptype == IPA_IP_v4) && (active_v4 == true)) ||
((iptype == IPA_IP_v6) && (active_v6 == true)))
{
/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
IPACMDBG_H("dev %s add 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]);
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]);
#ifdef WAN_IOC_NOTIFY_WAN_STATE
} else {
IPACMDBG_H("ipa_pm_q6_check to %d\n", ipa_pm_q6_check);
if(ipa_pm_q6_check == 1)
{
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);
}
if (ipa_pm_q6_check > 0)
ipa_pm_q6_check--;
else
IPACMERR(" ipa_pm_q6_check becomes negative !!!\n");
}
#else
}
#endif
/* Delete the default route*/
if (iptype == IPA_IP_v6)
{
@ -4357,18 +4500,23 @@ int IPACM_Wan::config_dft_embms_rules(ipa_ioc_add_flt_rule *pFilteringTable_v4,
int IPACM_Wan::handle_down_evt()
{
int res = IPACM_SUCCESS;
uint32_t i;
uint32_t i, tether_total;
int ipa_if_num_tether_tmp[IPA_MAX_IFACE_ENTRIES];
tether_total = 0;
memset(ipa_if_num_tether_tmp, 0, IPA_MAX_IFACE_ENTRIES);
IPACMDBG_H(" wan handle_down_evt \n");
/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
if (tx_prop != NULL)
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
{
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]);
/* 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);
if (tx_prop != NULL)
{
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]);
}
}
/* no iface address up, directly close iface*/
if (ip_type == IPACM_IP_NULL)
{
@ -4378,22 +4526,61 @@ int IPACM_Wan::handle_down_evt()
/* make sure default routing rules and firewall rules are deleted*/
if (active_v4)
{
if (rx_prop != NULL)
{
if (rx_prop != NULL)
{
del_dft_firewall_rules(IPA_IP_v4);
}
handle_route_del_evt(IPA_IP_v4);
IPACMDBG_H("Delete default v4 routing rules\n");
#ifdef FEATURE_IPA_ANDROID
/* posting wan_down_tether for lan clients */
#ifdef FEATURE_IPACM_HAL
IPACMDBG_H("Posting IPA_WAN_DOWN_TETHER_EVENT for IPV4\n");
post_wan_down_tether_evt(IPA_IP_v4, 0);
#else
for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++)
{
ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v4[i];
}
tether_total = IPACM_Wan::ipa_if_num_tether_v4_total;
for (i=0; i < tether_total; i++)
{
post_wan_down_tether_evt(IPA_IP_v4, ipa_if_num_tether_tmp[i]);
IPACMDBG_H("post_wan_down_tether_v4 iface(%d: %s)\n",
i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
}
#endif
#endif
}
if (active_v6)
{
if (rx_prop != NULL)
{
if (rx_prop != NULL)
{
del_dft_firewall_rules(IPA_IP_v6);
}
handle_route_del_evt(IPA_IP_v6);
IPACMDBG_H("Delete default v6 routing rules\n");
#ifdef FEATURE_IPA_ANDROID
/* posting wan_down_tether for lan clients */
#ifdef FEATURE_IPACM_HAL
IPACMDBG_H("Posting IPA_WAN_DOWN_TETHER_EVENT for IPV6\n");
post_wan_down_tether_evt(IPA_IP_v6, 0);
#else
for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++)
{
ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v6[i];
}
tether_total = IPACM_Wan::ipa_if_num_tether_v6_total;
for (i=0; i < tether_total; i++)
{
post_wan_down_tether_evt(IPA_IP_v6, ipa_if_num_tether_tmp[i]);
IPACMDBG_H("post_wan_down_tether_v6 iface(%d: %s)\n",
i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
}
#endif
#endif
}
/* Delete default v4 RT rule */
@ -4402,7 +4589,7 @@ int IPACM_Wan::handle_down_evt()
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");
IPACMERR("Routing rule deletion failed!\n");
res = IPACM_FAILURE;
goto fail;
}
@ -4585,8 +4772,11 @@ fail:
int IPACM_Wan::handle_down_evt_ex()
{
int res = IPACM_SUCCESS;
uint32_t i, tether_total;
uint32_t i;
#ifndef FEATURE_IPACM_HAL
uint32_t tether_total;
int ipa_if_num_tether_tmp[IPA_MAX_IFACE_ENTRIES];
#endif
IPACMDBG_H(" wan handle_down_evt \n");
@ -4594,14 +4784,16 @@ int IPACM_Wan::handle_down_evt_ex()
if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == EMBMS_IF)
{
embms_is_on = false;
/* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
if (tx_prop != NULL)
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
{
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]);
/* 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);
if (tx_prop != NULL)
{
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]);
}
}
if (rx_prop != NULL)
{
install_wan_filtering_rule(false);
@ -4629,6 +4821,9 @@ int IPACM_Wan::handle_down_evt_ex()
handle_route_del_evt_ex(IPA_IP_v4);
#ifdef FEATURE_IPA_ANDROID
/* posting wan_down_tether for all lan clients */
#ifdef FEATURE_IPACM_HAL
post_wan_down_tether_evt(IPA_IP_v4, 0);
#else
for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++)
{
ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v4[i];
@ -4640,6 +4835,7 @@ int IPACM_Wan::handle_down_evt_ex()
IPACMDBG_H("post_wan_down_tether_v4 iface(%d: %s)\n",
i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
}
#endif
#endif
if(IPACM_Wan::wan_up_v6)
{
@ -4681,6 +4877,9 @@ int IPACM_Wan::handle_down_evt_ex()
handle_route_del_evt_ex(IPA_IP_v6);
#ifdef FEATURE_IPA_ANDROID
/* posting wan_down_tether for all lan clients */
#ifdef FEATURE_IPACM_HAL
post_wan_down_tether_evt(IPA_IP_v6, 0);
#else
for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++)
{
ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v6[i];
@ -4692,6 +4891,7 @@ int IPACM_Wan::handle_down_evt_ex()
IPACMDBG_H("post_wan_down_tether_v6 iface(%d: %s)\n",
i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
}
#endif
#endif
if(IPACM_Wan::wan_up)
{
@ -4737,6 +4937,10 @@ int IPACM_Wan::handle_down_evt_ex()
handle_route_del_evt_ex(IPA_IP_v4);
#ifdef FEATURE_IPA_ANDROID
/* posting wan_down_tether for all lan clients */
#ifdef FEATURE_IPACM_HAL
IPACMDBG_H("Posting IPA_WAN_DOWN_TETHER_EVENT for IPV4\n");
post_wan_down_tether_evt(IPA_IP_v4, 0);
#else
for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++)
{
ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v4[i];
@ -4748,12 +4952,17 @@ int IPACM_Wan::handle_down_evt_ex()
IPACMDBG_H("post_wan_down_tether_v4 iface(%d: %s)\n",
i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
}
#endif
#endif
IPACM_Wan::wan_up_v6 = false;
del_wan_firewall_rule(IPA_IP_v6);
handle_route_del_evt_ex(IPA_IP_v6);
#ifdef FEATURE_IPA_ANDROID
/* posting wan_down_tether for all lan clients */
#ifdef FEATURE_IPACM_HAL
IPACMDBG_H("Posting IPA_WAN_DOWN_TETHER_EVENT for IPV6\n");
post_wan_down_tether_evt(IPA_IP_v6, 0);
#else
for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++)
{
ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v6[i];
@ -4765,6 +4974,7 @@ int IPACM_Wan::handle_down_evt_ex()
IPACMDBG_H("post_wan_down_tether_v6 iface(%d: %s)\n",
i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name);
}
#endif
#endif
memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name));
@ -5593,12 +5803,13 @@ int IPACM_Wan::handle_wan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptyp
&& get_client_memptr(wan_client, wan_index)->route_rule_set_v6 < get_client_memptr(wan_client, wan_index)->ipv6_set
))
{
/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
IPACMDBG_H("dev %s add 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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
{
/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
IPACMDBG_H("dev %s add 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->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
}
rt_rule = (struct ipa_ioc_add_rt_rule *)
calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
NUM * sizeof(struct ipa_rt_rule_add));

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
Copyright (c) 2013-2018, 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
@ -49,7 +49,9 @@ Skylar Chang
#include <IPACM_Lan.h>
#include <IPACM_IfaceManager.h>
#include <IPACM_ConntrackListener.h>
#ifdef FEATURE_IPACM_HAL
#include "IPACM_OffloadManager.h"
#endif
/* static member to store the number of total wifi clients within all APs*/
int IPACM_Wlan::total_num_wifi_clients = 0;
@ -133,6 +135,7 @@ IPACM_Wlan::~IPACM_Wlan()
{
IPACM_EvtDispatcher::deregistr(this);
IPACM_IfaceManager::deregistr(this);
IPACM_Wlan::num_wlan_ap_iface--;
return;
}
@ -148,6 +151,9 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
int wlan_index;
ipacm_ext_prop* ext_prop;
ipacm_event_iface_up_tehter* data_wan_tether;
#ifdef FEATURE_IPACM_HAL
IPACM_OffloadManager* OffloadMng;
#endif
switch (event)
{
@ -196,11 +202,24 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
if(data->if_index == ipa_if_num)
{
IPACM_Wlan::num_wlan_ap_iface--;
IPACMDBG_H("Now the number of wlan AP iface is %d\n", IPACM_Wlan::num_wlan_ap_iface);
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)
{
free(rx_prop);
}
if(tx_prop != NULL)
{
free(tx_prop);
}
if(iface_query != NULL)
{
free(iface_query);
}
#endif
delete this;
}
break;
@ -253,6 +272,10 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("IPv4 address:0x%x, IPv4 address mask:0x%x\n",
info->ipv4_addr, info->addr_mask);
IPACM_EvtDispatcher::PostEvt(&evt_data);
#ifdef FEATURE_IPACM_RESTART
/* Query wlan-clients */
ipa_query_wlan_client();
#endif
}
if(handle_addr_evt(data) == IPACM_FAILURE)
@ -309,6 +332,18 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
} else {
IPACMDBG_H("Wan_V6 haven't up yet \n");
}
#else
/* check if Upstream was set before */
if (IPACM_Wan::isWanUP(ipa_if_num))
{
IPACMDBG_H("Upstream was set previously for ipv4, change is_upstream_set flag\n");
is_upstream_set[IPA_IP_v4] = true;
}
if (IPACM_Wan::isWanUP_V6(ipa_if_num))
{
IPACMDBG_H("Upstream was set previously for ipv6, change is_upstream_set flag\n");
is_upstream_set[IPA_IP_v6] = true;
}
#endif
/* checking if SW-RT_enable */
if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true)
@ -354,7 +389,8 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
if(data_wan_tether->is_sta == false)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
handle_wan_up_ex(ext_prop, IPA_IP_v4,
IPACM_Wan::getXlat_Mux_Id());
} else {
handle_wan_up(IPA_IP_v4);
}
@ -524,14 +560,14 @@ 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");
if(is_downstream_set[data->prefix.iptype] == false)
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);
is_downstream_set[data->prefix.iptype] = true;
memcpy(&prefix[data->prefix.iptype], &data->prefix,
sizeof(prefix[data->prefix.iptype]));
if(is_upstream_set[data->prefix.iptype] == true)
if (is_upstream_set[data->prefix.iptype] == true)
{
IPACMDBG_H("Upstream was set before, adding modem UL rules.\n");
if(ip_type == IPA_IP_MAX || ip_type == data->prefix.iptype)
@ -548,7 +584,14 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
if (IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(data->prefix.iptype);
handle_wan_up_ex(ext_prop, data->prefix.iptype, 0);
if (data->prefix.iptype == IPA_IP_v4)
{
handle_wan_up_ex(ext_prop, data->prefix.iptype,
IPACM_Wan::getXlat_Mux_Id());
}
else {
handle_wan_up_ex(ext_prop, data->prefix.iptype, 0);
}
} else {
handle_wan_up(data->prefix.iptype); /* STA */
}
@ -856,7 +899,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
if (rx_prop != NULL || tx_prop != NULL)
{
IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name);
IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name);
IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_MAX);
}
if (m_is_guest_ap == true && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == FULL))
@ -904,6 +947,28 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
}
break;
case IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE:
{
IPACMDBG_H("Received IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE.\n");
/* internal push add_downstream event in cache */
OffloadMng = IPACM_OffloadManager::GetInstance();
if (OffloadMng == NULL) {
IPACMERR("failed to get IPACM_OffloadManager instance !\n");
} else {
IPACMDBG_H("Update iface %s add_downstream cache events\n", dev_name);
if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
{
OffloadMng->push_framework_event(dev_name, prefix[IPA_IP_v4]);
}
else if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
{
OffloadMng->push_framework_event(dev_name, prefix[IPA_IP_v6]);
}
}
IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface
}
break;
#endif
default:
break;
@ -1431,9 +1496,12 @@ int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type ipt
rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4;
rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wlan_client, wlan_index)->v4_addr;
rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
#ifdef FEATURE_IPA_V3
rt_rule_entry->rule.hashable = false;
#endif
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_v4_0)
{
rt_rule_entry->rule.hashable = true;
}
if (false == m_routing.AddRoutingRule(rt_rule))
{
IPACMERR("Routing rule addition failed!\n");
@ -1722,8 +1790,10 @@ int IPACM_Wlan::handle_down_evt()
IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
IPACM_Lan::handle_wan_down(IPACM_Wan::backhaul_is_sta_mode);
#ifdef FEATURE_IPA_ANDROID
#ifndef FEATURE_IPACM_HAL
/* Clean-up tethered-iface list */
IPACM_Wan::delete_tether_iface(IPA_IP_v4, ipa_if_num);
#endif
#endif
}
@ -1781,6 +1851,15 @@ int IPACM_Wlan::handle_down_evt()
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_private_subnet_fl_rule);
#endif
IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n");
#ifdef FEATURE_L2TP
if(m_filtering.DeleteFilteringHdls(&tcp_syn_flt_rule_hdl[IPA_IP_v4], IPA_IP_v4, 1) == false)
{
IPACMERR("Error deleting tcp syn flt rule, aborting...\n");
res = IPACM_FAILURE;
goto fail;
}
#endif
}
/* Delete v6 filtering rules */
@ -1806,6 +1885,14 @@ int IPACM_Wlan::handle_down_evt()
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
IPACMDBG_H("Deleted default v6 filter rules successfully.\n");
}
#ifdef FEATURE_L2TP
if(m_filtering.DeleteFilteringHdls(&tcp_syn_flt_rule_hdl[IPA_IP_v6], IPA_IP_v6, 1) == false)
{
IPACMERR("Error deleting tcp syn flt rule, aborting...\n");
res = IPACM_FAILURE;
goto fail;
}
#endif
}
IPACMDBG_H("finished delete filtering rules\n ");
@ -1918,13 +2005,18 @@ fail:
}
IPACMDBG_H("finished delete software-routing filtering rules\n ");
/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
if (rx_prop != NULL)
{
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
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]);
if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
{
/* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
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
}
for (i = 0; i < num_wifi_client; i++)
@ -1938,6 +2030,7 @@ fail:
{
free(wlan_client);
}
#ifndef FEATURE_ETH_BRIDGE_LE
if (tx_prop != NULL)
{
free(tx_prop);
@ -1947,6 +2040,7 @@ fail:
{
free(iface_query);
}
#endif
is_active = false;
post_del_self_evt();
@ -2193,6 +2287,28 @@ void IPACM_Wlan::handle_SCC_MCC_switch(ipa_ip_type iptype)
return;
}
#ifdef FEATURE_IPACM_RESTART
int IPACM_Wlan::ipa_query_wlan_client()
{
int fd = -1;
if ((fd = open(IPA_DEVICE_NAME, O_RDWR)) < 0) {
IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
return IPACM_FAILURE;
}
if (ioctl(fd, IPA_IOC_QUERY_WLAN_CLIENT) < 0) {
IPACMERR("IOCTL IPA_IOC_QUERY_WLAN_CLIENT call failed: %s \n", strerror(errno));
close(fd);
return IPACM_FAILURE;
}
IPACMDBG_H("send IPA_IOC_QUERY_WLAN_CLIENT \n");
close(fd);
return IPACM_SUCCESS;
}
#endif
void IPACM_Wlan::eth_bridge_handle_wlan_mode_switch()
{
uint32_t i;

View file

@ -665,6 +665,9 @@ static int IPACM_firewall_xml_parse_tree
memcpy(content_buf, (void *)content, str_size);
config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.tos
= atoi(content_buf);
// Here we do not know if it is TOS with mask or not, so we put at both places
config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.tos_value
= atoi(content_buf);
IPACMDBG_H("\n IPV4 TOS val is %d \n",
config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.tos);
}
@ -674,13 +677,25 @@ static int IPACM_firewall_xml_parse_tree
content = IPACM_read_content_element(xml_node);
if (content)
{
uint8_t mask;
str_size = strlen(content);
memset(content_buf, 0, sizeof(content_buf));
memcpy(content_buf, (void *)content, str_size);
config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.tos
&= atoi(content_buf);
IPACMDBG_H("\n IPv4 TOS mask is %d \n",
config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.tos);
mask = atoi(content_buf);
IPACMDBG_H("\n IPv4 TOS mask is %u \n", mask);
if (mask != 0xFF) {
// TOS attribute cannot be used
config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.u.v4.tos = 0;
config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.tos_mask = mask;
config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask |=
IPA_FLT_TOS_MASKED;
config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.attrib_mask &=
~IPA_FLT_TOS;
} else {
config->extd_firewall_entries[config->num_extd_firewall_entries - 1].attrib.tos_value = 0;
}
}
}
else if (0 == IPACM_util_icmp_string((char*)xml_node->name, IPV4NextHeaderProtocol_TAG))

View file

@ -26,6 +26,8 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef IPA_NAT_DRV_H
#define IPA_NAT_DRV_H
#include "string.h" /* memset */
#include "stdlib.h" /* free, malloc */
@ -142,3 +144,4 @@ int ipa_nat_query_timestamp(uint32_t table_handle,
int ipa_nat_modify_pdn(uint32_t tbl_hdl,
uint8_t pdn_index,
ipa_nat_pdn_entry *pdn_info);
#endif /* IPA_NAT_DRV_H */

View file

@ -10,15 +10,16 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../inc
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
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
LOCAL_CFLAGS := -DDEBUG -Wall -Werror
LOCAL_CFLAGS += -DFEATURE_IPA_ANDROID
LOCAL_MODULE := libipanat

View file

@ -35,17 +35,21 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define strlcpy g_strlcpy
#else
#ifndef FEATURE_IPA_ANDROID
static size_t strlcpy(char * dst, const char * src, size_t size) {
static size_t strlcpy(char * dst, const char * src, size_t size)
{
size_t i;
if (size < 1)
return 0;
strncpy(dst, src, size - 1);
dst[size - 1] = 0;
for (i = 0; i < (size - 1) && src[i] != '\0'; i++)
dst[i] = src[i];
for (; i < size; i++)
dst[i] = '\0';
return strlen(dst);
}
#endif
#endif
struct ipa_nat_cache ipv4_nat_cache;
pthread_mutex_t nat_mutex = PTHREAD_MUTEX_INITIALIZER;