Initial Commit4
This commit is contained in:
98
data-ipa-cfg-mgr/ipacm/src/Android.mk
Normal file
98
data-ipa-cfg-mgr/ipacm/src/Android.mk
Normal file
@@ -0,0 +1,98 @@
|
||||
BOARD_PLATFORM_LIST := msm8916
|
||||
BOARD_PLATFORM_LIST += msm8909
|
||||
ifneq ($(call is-board-platform-in-list,$(BOARD_PLATFORM_LIST)),true)
|
||||
ifneq (,$(filter $(QCOM_BOARD_PLATFORMS),$(TARGET_BOARD_PLATFORM)))
|
||||
ifneq (, $(filter aarch64 arm arm64, $(TARGET_ARCH)))
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../inc
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../ipanat/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/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
|
||||
ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
|
||||
LOCAL_CFLAGS += -DDEBUG
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_BOARD_PLATFORM),msmcobalt)
|
||||
LOCAL_CFLAGS += -DFEATURE_IPA_V3
|
||||
endif
|
||||
|
||||
filetoadd = bionic/libc/kernel/arch-arm/asm/posix_types.h
|
||||
LOCAL_CFLAGS += $(shell if [ -a $(filetoadd) ] ; then echo -include $(filetoadd) ; fi ;)
|
||||
filetoadd = bionic/libc/kernel/arch-arm/asm/byteorder.h
|
||||
LOCAL_CFLAGS += $(shell if [ -a $(filetoadd) ] ; then echo -include $(filetoadd) ; fi ;)
|
||||
|
||||
LOCAL_SRC_FILES := IPACM_Main.cpp \
|
||||
IPACM_EvtDispatcher.cpp \
|
||||
IPACM_Config.cpp \
|
||||
IPACM_CmdQueue.cpp \
|
||||
IPACM_Filtering.cpp \
|
||||
IPACM_Routing.cpp \
|
||||
IPACM_Header.cpp \
|
||||
IPACM_Lan.cpp \
|
||||
IPACM_Iface.cpp \
|
||||
IPACM_Wlan.cpp \
|
||||
IPACM_Wan.cpp \
|
||||
IPACM_IfaceManager.cpp \
|
||||
IPACM_Neighbor.cpp \
|
||||
IPACM_Netlink.cpp \
|
||||
IPACM_Xml.cpp \
|
||||
IPACM_Conntrack_NATApp.cpp\
|
||||
IPACM_ConntrackClient.cpp \
|
||||
IPACM_ConntrackListener.cpp \
|
||||
IPACM_Log.cpp
|
||||
|
||||
LOCAL_MODULE := ipacm
|
||||
LOCAL_CLANG := false
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libipanat
|
||||
LOCAL_SHARED_LIBRARIES += libxml2
|
||||
LOCAL_SHARED_LIBRARIES += libnfnetlink
|
||||
LOCAL_SHARED_LIBRARIES += libnetfilter_conntrack
|
||||
LOCAL_CLANG := true
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
################################################################################
|
||||
|
||||
define ADD_TEST
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := $1
|
||||
LOCAL_SRC_FILES := $1
|
||||
LOCAL_MODULE_CLASS := ipacm
|
||||
LOCAL_MODULE_TAGS := debug
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
endef
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := IPACM_cfg.xml
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_SRC_FILES := $(LOCAL_MODULE)
|
||||
LOCAL_MODULE_OWNER := ipacm
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
endif # $(TARGET_ARCH)
|
||||
endif
|
||||
endif
|
||||
205
data-ipa-cfg-mgr/ipacm/src/IPACM_CmdQueue.cpp
Normal file
205
data-ipa-cfg-mgr/ipacm/src/IPACM_CmdQueue.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
Copyright (c) 2013-2016, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.
|
||||
*/
|
||||
/*!
|
||||
@file
|
||||
IPACM_CmdQueue.cpp
|
||||
|
||||
@brief
|
||||
This file implements the IPAM Comment Queue functionality
|
||||
|
||||
@Author
|
||||
Sunil
|
||||
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "IPACM_CmdQueue.h"
|
||||
#include "IPACM_Log.h"
|
||||
#include "IPACM_Iface.h"
|
||||
|
||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
MessageQueue* MessageQueue::inst_internal = NULL;
|
||||
MessageQueue* MessageQueue::inst_external = NULL;
|
||||
|
||||
MessageQueue* MessageQueue::getInstanceInternal()
|
||||
{
|
||||
if(inst_internal == NULL)
|
||||
{
|
||||
inst_internal = new MessageQueue();
|
||||
if(inst_internal == NULL)
|
||||
{
|
||||
IPACMERR("unable to create internal Message Queue instance\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return inst_internal;
|
||||
}
|
||||
|
||||
MessageQueue* MessageQueue::getInstanceExternal()
|
||||
{
|
||||
if(inst_external == NULL)
|
||||
{
|
||||
inst_external = new MessageQueue();
|
||||
if(inst_external == NULL)
|
||||
{
|
||||
IPACMERR("unable to create external Message Queue instance\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return inst_external;
|
||||
}
|
||||
|
||||
void MessageQueue::enqueue(Message *item)
|
||||
{
|
||||
if(!Head)
|
||||
{
|
||||
Tail = item;
|
||||
Head = item;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Tail == NULL)
|
||||
{
|
||||
IPACMDBG("Tail is null\n");
|
||||
Head->setnext(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
Tail->setnext(item);
|
||||
}
|
||||
Tail = item;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Message* MessageQueue::dequeue(void)
|
||||
{
|
||||
if(Head == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Message *tmp = Head;
|
||||
Head = Head->getnext();
|
||||
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void* MessageQueue::Process(void *param)
|
||||
{
|
||||
MessageQueue *MsgQueueInternal = NULL;
|
||||
MessageQueue *MsgQueueExternal = NULL;
|
||||
Message *item = NULL;
|
||||
IPACMDBG("MessageQueue::Process()\n");
|
||||
|
||||
MsgQueueInternal = MessageQueue::getInstanceInternal();
|
||||
if(MsgQueueInternal == NULL)
|
||||
{
|
||||
IPACMERR("unable to start internal cmd queue process\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MsgQueueExternal = MessageQueue::getInstanceExternal();
|
||||
if(MsgQueueExternal == NULL)
|
||||
{
|
||||
IPACMERR("unable to start external cmd queue process\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(pthread_mutex_lock(&mutex) != 0)
|
||||
{
|
||||
IPACMERR("unable to lock the mutex\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item = MsgQueueInternal->dequeue();
|
||||
if(item == NULL)
|
||||
{
|
||||
item = MsgQueueExternal->dequeue();
|
||||
if(item)
|
||||
{
|
||||
IPACMDBG("Get event %s from external queue.\n",
|
||||
IPACM_Iface::ipacmcfg->getEventName(item->evt.data.event));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG("Get event %s from internal queue.\n",
|
||||
IPACM_Iface::ipacmcfg->getEventName(item->evt.data.event));
|
||||
}
|
||||
|
||||
if(item == NULL)
|
||||
{
|
||||
IPACMDBG("Waiting for Message\n");
|
||||
|
||||
if(pthread_cond_wait(&cond_var, &mutex) != 0)
|
||||
{
|
||||
IPACMERR("unable to lock the mutex\n");
|
||||
|
||||
if(pthread_mutex_unlock(&mutex) != 0)
|
||||
{
|
||||
IPACMERR("unable to unlock the mutex\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(pthread_mutex_unlock(&mutex) != 0)
|
||||
{
|
||||
IPACMERR("unable to unlock the mutex\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pthread_mutex_unlock(&mutex) != 0)
|
||||
{
|
||||
IPACMERR("unable to unlock the mutex\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IPACMDBG("Processing item %p event ID: %d\n",item,item->evt.data.event);
|
||||
item->evt.callback_ptr(&item->evt.data);
|
||||
delete item;
|
||||
item = NULL;
|
||||
}
|
||||
|
||||
} /* Go forever until a termination indication is received */
|
||||
|
||||
}
|
||||
824
data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp
Normal file
824
data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp
Normal file
@@ -0,0 +1,824 @@
|
||||
/*
|
||||
Copyright (c) 2013-2016, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.
|
||||
*/
|
||||
/*!
|
||||
@file
|
||||
IPACM_Config.cpp
|
||||
|
||||
@brief
|
||||
This file implements the IPACM Configuration from XML file
|
||||
|
||||
@Author
|
||||
Skylar Chang
|
||||
|
||||
*/
|
||||
#include <IPACM_Config.h>
|
||||
#include <IPACM_Log.h>
|
||||
#include <IPACM_Iface.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
IPACM_Config *IPACM_Config::pInstance = NULL;
|
||||
const char *IPACM_Config::DEVICE_NAME = "/dev/ipa";
|
||||
const char *IPACM_Config::DEVICE_NAME_ODU = "/dev/odu_ipa_bridge";
|
||||
|
||||
#define __stringify(x...) #x
|
||||
|
||||
const char *ipacm_event_name[] = {
|
||||
__stringify(IPA_CFG_CHANGE_EVENT), /* NULL */
|
||||
__stringify(IPA_PRIVATE_SUBNET_CHANGE_EVENT), /* ipacm_event_data_fid */
|
||||
__stringify(IPA_FIREWALL_CHANGE_EVENT), /* NULL */
|
||||
__stringify(IPA_LINK_UP_EVENT), /* ipacm_event_data_fid */
|
||||
__stringify(IPA_LINK_DOWN_EVENT), /* ipacm_event_data_fid */
|
||||
__stringify(IPA_USB_LINK_UP_EVENT), /* ipacm_event_data_fid */
|
||||
__stringify(IPA_BRIDGE_LINK_UP_EVENT), /* ipacm_event_data_all */
|
||||
__stringify(IPA_WAN_EMBMS_LINK_UP_EVENT), /* ipacm_event_data_mac */
|
||||
__stringify(IPA_ADDR_ADD_EVENT), /* ipacm_event_data_addr */
|
||||
__stringify(IPA_ADDR_DEL_EVENT), /* no use */
|
||||
__stringify(IPA_ROUTE_ADD_EVENT), /* ipacm_event_data_addr */
|
||||
__stringify(IPA_ROUTE_DEL_EVENT), /* ipacm_event_data_addr */
|
||||
__stringify(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT), /* ipacm_event_data_fid */
|
||||
__stringify(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT), /* ipacm_event_data_fid */
|
||||
__stringify(IPA_WLAN_AP_LINK_UP_EVENT), /* ipacm_event_data_mac */
|
||||
__stringify(IPA_WLAN_STA_LINK_UP_EVENT), /* ipacm_event_data_mac */
|
||||
__stringify(IPA_WLAN_LINK_DOWN_EVENT), /* ipacm_event_data_mac */
|
||||
__stringify(IPA_WLAN_CLIENT_ADD_EVENT), /* ipacm_event_data_mac */
|
||||
__stringify(IPA_WLAN_CLIENT_ADD_EVENT_EX), /* ipacm_event_data_wlan_ex */
|
||||
__stringify(IPA_WLAN_CLIENT_DEL_EVENT), /* ipacm_event_data_mac */
|
||||
__stringify(IPA_WLAN_CLIENT_POWER_SAVE_EVENT), /* ipacm_event_data_mac */
|
||||
__stringify(IPA_WLAN_CLIENT_RECOVER_EVENT), /* ipacm_event_data_mac */
|
||||
__stringify(IPA_NEW_NEIGH_EVENT), /* ipacm_event_data_all */
|
||||
__stringify(IPA_DEL_NEIGH_EVENT), /* ipacm_event_data_all */
|
||||
__stringify(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT), /* ipacm_event_data_all */
|
||||
__stringify(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT), /* ipacm_event_data_all */
|
||||
__stringify(IPA_SW_ROUTING_ENABLE), /* NULL */
|
||||
__stringify(IPA_SW_ROUTING_DISABLE), /* NULL */
|
||||
__stringify(IPA_PROCESS_CT_MESSAGE), /* ipacm_ct_evt_data */
|
||||
__stringify(IPA_PROCESS_CT_MESSAGE_V6), /* ipacm_ct_evt_data */
|
||||
__stringify(IPA_LAN_TO_LAN_NEW_CONNECTION), /* ipacm_event_connection */
|
||||
__stringify(IPA_LAN_TO_LAN_DEL_CONNECTION), /* ipacm_event_connection */
|
||||
__stringify(IPA_WLAN_SWITCH_TO_SCC), /* No Data */
|
||||
__stringify(IPA_WLAN_SWITCH_TO_MCC), /* No Data */
|
||||
__stringify(IPA_CRADLE_WAN_MODE_SWITCH), /* ipacm_event_cradle_wan_mode */
|
||||
__stringify(IPA_WAN_XLAT_CONNECT_EVENT), /* ipacm_event_data_fid */
|
||||
__stringify(IPA_TETHERING_STATS_UPDATE_EVENT), /* ipacm_event_data_fid */
|
||||
__stringify(IPA_NETWORK_STATS_UPDATE_EVENT), /* ipacm_event_data_fid */
|
||||
__stringify(IPA_EXTERNAL_EVENT_MAX),
|
||||
__stringify(IPA_HANDLE_WAN_UP), /* ipacm_event_iface_up */
|
||||
__stringify(IPA_HANDLE_WAN_DOWN), /* ipacm_event_iface_up */
|
||||
__stringify(IPA_HANDLE_WAN_UP_V6), /* NULL */
|
||||
__stringify(IPA_HANDLE_WAN_DOWN_V6), /* NULL */
|
||||
__stringify(IPA_HANDLE_WAN_UP_TETHER), /* ipacm_event_iface_up_tehter */
|
||||
__stringify(IPA_HANDLE_WAN_DOWN_TETHER), /* ipacm_event_iface_up_tehter */
|
||||
__stringify(IPA_HANDLE_WAN_UP_V6_TETHER), /* ipacm_event_iface_up_tehter */
|
||||
__stringify(IPA_HANDLE_WAN_DOWN_V6_TETHER), /* ipacm_event_iface_up_tehter */
|
||||
__stringify(IPA_HANDLE_WLAN_UP), /* ipacm_event_iface_up */
|
||||
__stringify(IPA_HANDLE_LAN_UP), /* ipacm_event_iface_up */
|
||||
__stringify(IPA_ETH_BRIDGE_IFACE_UP), /* ipacm_event_eth_bridge*/
|
||||
__stringify(IPA_ETH_BRIDGE_IFACE_DOWN), /* ipacm_event_eth_bridge*/
|
||||
__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_LAN_DELETE_SELF), /* ipacm_event_data_fid */
|
||||
__stringify(IPACM_EVENT_MAX),
|
||||
};
|
||||
|
||||
IPACM_Config::IPACM_Config()
|
||||
{
|
||||
iface_table = NULL;
|
||||
alg_table = NULL;
|
||||
pNatIfaces = NULL;
|
||||
memset(&ipa_client_rm_map_tbl, 0, sizeof(ipa_client_rm_map_tbl));
|
||||
memset(&ipa_rm_tbl, 0, sizeof(ipa_rm_tbl));
|
||||
ipa_rm_a2_check=0;
|
||||
ipacm_odu_enable = false;
|
||||
ipacm_odu_router_mode = false;
|
||||
ipa_num_wlan_guest_ap = 0;
|
||||
|
||||
ipa_num_ipa_interfaces = 0;
|
||||
ipa_num_private_subnet = 0;
|
||||
ipa_num_alg_ports = 0;
|
||||
ipa_nat_max_entries = 0;
|
||||
ipa_nat_iface_entries = 0;
|
||||
ipa_sw_rt_enable = false;
|
||||
ipa_bridge_enable = false;
|
||||
isMCC_Mode = false;
|
||||
ipa_max_valid_rm_entry = 0;
|
||||
|
||||
memset(&rt_tbl_default_v4, 0, sizeof(rt_tbl_default_v4));
|
||||
memset(&rt_tbl_lan_v4, 0, sizeof(rt_tbl_lan_v4));
|
||||
memset(&rt_tbl_wan_v4, 0, sizeof(rt_tbl_wan_v4));
|
||||
memset(&rt_tbl_v6, 0, sizeof(rt_tbl_v6));
|
||||
memset(&rt_tbl_wan_v6, 0, sizeof(rt_tbl_wan_v6));
|
||||
memset(&rt_tbl_wan_dl, 0, sizeof(rt_tbl_wan_dl));
|
||||
memset(&rt_tbl_odu_v4, 0, sizeof(rt_tbl_odu_v4));
|
||||
memset(&rt_tbl_odu_v6, 0, sizeof(rt_tbl_odu_v6));
|
||||
|
||||
memset(&ext_prop_v4, 0, sizeof(ext_prop_v4));
|
||||
memset(&ext_prop_v6, 0, sizeof(ext_prop_v6));
|
||||
|
||||
qmap_id = ~0;
|
||||
|
||||
memset(flt_rule_count_v4, 0, (IPA_CLIENT_CONS - IPA_CLIENT_PROD)*sizeof(int));
|
||||
memset(flt_rule_count_v6, 0, (IPA_CLIENT_CONS - IPA_CLIENT_PROD)*sizeof(int));
|
||||
memset(bridge_mac, 0, IPA_MAC_ADDR_SIZE*sizeof(uint8_t));
|
||||
|
||||
IPACMDBG_H(" create IPACM_Config constructor\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int IPACM_Config::Init(void)
|
||||
{
|
||||
/* Read IPACM Config file */
|
||||
char IPACM_config_file[IPA_MAX_FILE_LEN];
|
||||
IPACM_conf_t *cfg;
|
||||
cfg = (IPACM_conf_t *)malloc(sizeof(IPACM_conf_t));
|
||||
if(cfg == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate cfg memory.\n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
uint32_t subnet_addr;
|
||||
uint32_t subnet_mask;
|
||||
int i, ret = IPACM_SUCCESS;
|
||||
struct in_addr in_addr_print;
|
||||
|
||||
m_fd = open(DEVICE_NAME, O_RDWR);
|
||||
if (0 > m_fd)
|
||||
{
|
||||
IPACMERR("Failed opening %s.\n", DEVICE_NAME);
|
||||
}
|
||||
strncpy(IPACM_config_file, "/etc/IPACM_cfg.xml", sizeof(IPACM_config_file));
|
||||
|
||||
IPACMDBG_H("\n IPACM XML file is %s \n", IPACM_config_file);
|
||||
if (IPACM_SUCCESS == ipacm_read_cfg_xml(IPACM_config_file, cfg))
|
||||
{
|
||||
IPACMDBG_H("\n IPACM XML read OK \n");
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMERR("\n IPACM XML read failed \n");
|
||||
ret = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Check wlan AP-AP access mode configuration */
|
||||
if (cfg->num_wlan_guest_ap == 2)
|
||||
{
|
||||
IPACMDBG_H("IPACM_Config::Both wlan APs can not be configured in guest ap mode. \n");
|
||||
IPACMDBG_H("IPACM_Config::configure both APs in full access mode or at least one in guest ap mode. \n");
|
||||
ret = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
/* Construct IPACM Iface table */
|
||||
ipa_num_ipa_interfaces = cfg->iface_config.num_iface_entries;
|
||||
if (iface_table != NULL)
|
||||
{
|
||||
free(iface_table);
|
||||
iface_table = NULL;
|
||||
IPACMDBG_H("RESET IPACM_Config::iface_table\n");
|
||||
}
|
||||
iface_table = (ipa_ifi_dev_name_t *)calloc(ipa_num_ipa_interfaces,
|
||||
sizeof(ipa_ifi_dev_name_t));
|
||||
if(iface_table == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate iface_table memory.\n");
|
||||
ret = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < cfg->iface_config.num_iface_entries; i++)
|
||||
{
|
||||
strncpy(iface_table[i].iface_name, cfg->iface_config.iface_entries[i].iface_name, sizeof(iface_table[i].iface_name));
|
||||
iface_table[i].if_cat = cfg->iface_config.iface_entries[i].if_cat;
|
||||
iface_table[i].if_mode = cfg->iface_config.iface_entries[i].if_mode;
|
||||
iface_table[i].wlan_mode = cfg->iface_config.iface_entries[i].wlan_mode;
|
||||
IPACMDBG_H("IPACM_Config::iface_table[%d] = %s, cat=%d, mode=%d wlan-mode=%d \n", i, iface_table[i].iface_name,
|
||||
iface_table[i].if_cat, iface_table[i].if_mode, iface_table[i].wlan_mode);
|
||||
/* copy bridge interface name to ipacmcfg */
|
||||
if( iface_table[i].if_cat == VIRTUAL_IF)
|
||||
{
|
||||
strlcpy(ipa_virtual_iface_name, iface_table[i].iface_name, sizeof(ipa_virtual_iface_name));
|
||||
IPACMDBG_H("ipa_virtual_iface_name(%s) \n", ipa_virtual_iface_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct IPACM Private_Subnet table */
|
||||
memset(&private_subnet_table, 0, sizeof(private_subnet_table));
|
||||
ipa_num_private_subnet = cfg->private_subnet_config.num_subnet_entries;
|
||||
|
||||
for (i = 0; i < cfg->private_subnet_config.num_subnet_entries; i++)
|
||||
{
|
||||
memcpy(&private_subnet_table[i].subnet_addr,
|
||||
&cfg->private_subnet_config.private_subnet_entries[i].subnet_addr,
|
||||
sizeof(cfg->private_subnet_config.private_subnet_entries[i].subnet_addr));
|
||||
|
||||
memcpy(&private_subnet_table[i].subnet_mask,
|
||||
&cfg->private_subnet_config.private_subnet_entries[i].subnet_mask,
|
||||
sizeof(cfg->private_subnet_config.private_subnet_entries[i].subnet_mask));
|
||||
|
||||
subnet_addr = htonl(private_subnet_table[i].subnet_addr);
|
||||
memcpy(&in_addr_print,&subnet_addr,sizeof(in_addr_print));
|
||||
IPACMDBG_H("%dst::private_subnet_table= %s \n ", i,
|
||||
inet_ntoa(in_addr_print));
|
||||
|
||||
subnet_mask = htonl(private_subnet_table[i].subnet_mask);
|
||||
memcpy(&in_addr_print,&subnet_mask,sizeof(in_addr_print));
|
||||
IPACMDBG_H("%dst::private_subnet_table= %s \n ", i,
|
||||
inet_ntoa(in_addr_print));
|
||||
}
|
||||
|
||||
/* Construct IPACM ALG table */
|
||||
ipa_num_alg_ports = cfg->alg_config.num_alg_entries;
|
||||
if (alg_table != NULL)
|
||||
{
|
||||
free(alg_table);
|
||||
alg_table = NULL;
|
||||
IPACMDBG_H("RESET IPACM_Config::alg_table \n");
|
||||
}
|
||||
alg_table = (ipacm_alg *)calloc(ipa_num_alg_ports,
|
||||
sizeof(ipacm_alg));
|
||||
if(alg_table == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate alg_table memory.\n");
|
||||
ret = IPACM_FAILURE;
|
||||
free(iface_table);
|
||||
goto fail;;
|
||||
}
|
||||
for (i = 0; i < cfg->alg_config.num_alg_entries; i++)
|
||||
{
|
||||
alg_table[i].protocol = cfg->alg_config.alg_entries[i].protocol;
|
||||
alg_table[i].port = cfg->alg_config.alg_entries[i].port;
|
||||
IPACMDBG_H("IPACM_Config::ipacm_alg[%d] = %d, port=%d\n", i, alg_table[i].protocol, alg_table[i].port);
|
||||
}
|
||||
|
||||
ipa_nat_max_entries = cfg->nat_max_entries;
|
||||
IPACMDBG_H("Nat Maximum Entries %d\n", ipa_nat_max_entries);
|
||||
|
||||
/* Find ODU is either router mode or bridge mode*/
|
||||
ipacm_odu_enable = cfg->odu_enable;
|
||||
ipacm_odu_router_mode = cfg->router_mode_enable;
|
||||
ipacm_odu_embms_enable = cfg->odu_embms_enable;
|
||||
IPACMDBG_H("ipacm_odu_enable %d\n", ipacm_odu_enable);
|
||||
IPACMDBG_H("ipacm_odu_mode %d\n", ipacm_odu_router_mode);
|
||||
IPACMDBG_H("ipacm_odu_embms_enable %d\n", ipacm_odu_embms_enable);
|
||||
|
||||
ipacm_ip_passthrough_mode = cfg->ip_passthrough_mode;
|
||||
IPACMDBG_H("ipacm_ip_passthrough_mode %d. \n", ipacm_ip_passthrough_mode);
|
||||
|
||||
ipa_num_wlan_guest_ap = cfg->num_wlan_guest_ap;
|
||||
IPACMDBG_H("ipa_num_wlan_guest_ap %d\n",ipa_num_wlan_guest_ap);
|
||||
|
||||
/* Allocate more non-nat entries if the monitored iface dun have Tx/Rx properties */
|
||||
if (pNatIfaces != NULL)
|
||||
{
|
||||
free(pNatIfaces);
|
||||
pNatIfaces = NULL;
|
||||
IPACMDBG_H("RESET IPACM_Config::pNatIfaces \n");
|
||||
}
|
||||
ipa_nat_iface_entries = 0;
|
||||
pNatIfaces = (NatIfaces *)calloc(ipa_num_ipa_interfaces, sizeof(NatIfaces));
|
||||
if (pNatIfaces == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate nat ifaces\n");
|
||||
ret = IPACM_FAILURE;
|
||||
free(iface_table);
|
||||
free(alg_table);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Construct the routing table ictol name in iface static member*/
|
||||
rt_tbl_default_v4.ip = IPA_IP_v4;
|
||||
strncpy(rt_tbl_default_v4.name, V4_DEFAULT_ROUTE_TABLE_NAME, sizeof(rt_tbl_default_v4.name));
|
||||
|
||||
rt_tbl_lan_v4.ip = IPA_IP_v4;
|
||||
strncpy(rt_tbl_lan_v4.name, V4_LAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_lan_v4.name));
|
||||
|
||||
rt_tbl_wan_v4.ip = IPA_IP_v4;
|
||||
strncpy(rt_tbl_wan_v4.name, V4_WAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_v4.name));
|
||||
|
||||
rt_tbl_v6.ip = IPA_IP_v6;
|
||||
strncpy(rt_tbl_v6.name, V6_COMMON_ROUTE_TABLE_NAME, sizeof(rt_tbl_v6.name));
|
||||
|
||||
rt_tbl_wan_v6.ip = IPA_IP_v6;
|
||||
strncpy(rt_tbl_wan_v6.name, V6_WAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_v6.name));
|
||||
|
||||
rt_tbl_odu_v4.ip = IPA_IP_v4;
|
||||
strncpy(rt_tbl_odu_v4.name, V4_ODU_ROUTE_TABLE_NAME, sizeof(rt_tbl_odu_v4.name));
|
||||
|
||||
rt_tbl_odu_v6.ip = IPA_IP_v6;
|
||||
strncpy(rt_tbl_odu_v6.name, V6_ODU_ROUTE_TABLE_NAME, sizeof(rt_tbl_odu_v6.name));
|
||||
|
||||
rt_tbl_wan_dl.ip = IPA_IP_MAX;
|
||||
strncpy(rt_tbl_wan_dl.name, WAN_DL_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_dl.name));
|
||||
|
||||
/* Construct IPACM ipa_client map to rm_resource table */
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_WLAN1_PROD]= IPA_RM_RESOURCE_WLAN_PROD;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_USB_PROD]= IPA_RM_RESOURCE_USB_PROD;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_A5_WLAN_AMPDU_PROD]= IPA_RM_RESOURCE_HSIC_PROD;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_A2_EMBEDDED_PROD]= IPA_RM_RESOURCE_Q6_PROD;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_A2_TETHERED_PROD]= IPA_RM_RESOURCE_Q6_PROD;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_APPS_LAN_WAN_PROD]= IPA_RM_RESOURCE_Q6_PROD;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_WLAN1_CONS]= IPA_RM_RESOURCE_WLAN_CONS;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_WLAN2_CONS]= IPA_RM_RESOURCE_WLAN_CONS;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_WLAN3_CONS]= IPA_RM_RESOURCE_WLAN_CONS;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_WLAN4_CONS]= IPA_RM_RESOURCE_WLAN_CONS;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_USB_CONS]= IPA_RM_RESOURCE_USB_CONS;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_A2_EMBEDDED_CONS]= IPA_RM_RESOURCE_Q6_CONS;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_A2_TETHERED_CONS]= IPA_RM_RESOURCE_Q6_CONS;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_APPS_WAN_CONS]= IPA_RM_RESOURCE_Q6_CONS;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_ODU_PROD]= IPA_RM_RESOURCE_ODU_ADAPT_PROD;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_ODU_EMB_CONS]= IPA_RM_RESOURCE_ODU_ADAPT_CONS;
|
||||
ipa_client_rm_map_tbl[IPA_CLIENT_ODU_TETH_CONS]= IPA_RM_RESOURCE_ODU_ADAPT_CONS;
|
||||
|
||||
/* Create the entries which IPACM wants to add dependencies on */
|
||||
ipa_rm_tbl[0].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD;
|
||||
ipa_rm_tbl[0].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS;
|
||||
ipa_rm_tbl[0].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD;
|
||||
ipa_rm_tbl[0].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS;
|
||||
|
||||
ipa_rm_tbl[1].producer_rm1 = IPA_RM_RESOURCE_USB_PROD;
|
||||
ipa_rm_tbl[1].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS;
|
||||
ipa_rm_tbl[1].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD;
|
||||
ipa_rm_tbl[1].consumer_rm2 = IPA_RM_RESOURCE_USB_CONS;
|
||||
|
||||
ipa_rm_tbl[2].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD;
|
||||
ipa_rm_tbl[2].consumer_rm1 = IPA_RM_RESOURCE_USB_CONS;
|
||||
ipa_rm_tbl[2].producer_rm2 = IPA_RM_RESOURCE_USB_PROD;
|
||||
ipa_rm_tbl[2].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS;
|
||||
|
||||
ipa_rm_tbl[3].producer_rm1 = IPA_RM_RESOURCE_ODU_ADAPT_PROD;
|
||||
ipa_rm_tbl[3].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS;
|
||||
ipa_rm_tbl[3].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD;
|
||||
ipa_rm_tbl[3].consumer_rm2 = IPA_RM_RESOURCE_ODU_ADAPT_CONS;
|
||||
|
||||
ipa_rm_tbl[4].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD;
|
||||
ipa_rm_tbl[4].consumer_rm1 = IPA_RM_RESOURCE_ODU_ADAPT_CONS;
|
||||
ipa_rm_tbl[4].producer_rm2 = IPA_RM_RESOURCE_ODU_ADAPT_PROD;
|
||||
ipa_rm_tbl[4].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS;
|
||||
|
||||
ipa_rm_tbl[5].producer_rm1 = IPA_RM_RESOURCE_ODU_ADAPT_PROD;
|
||||
ipa_rm_tbl[5].consumer_rm1 = IPA_RM_RESOURCE_USB_CONS;
|
||||
ipa_rm_tbl[5].producer_rm2 = IPA_RM_RESOURCE_USB_PROD;
|
||||
ipa_rm_tbl[5].consumer_rm2 = IPA_RM_RESOURCE_ODU_ADAPT_CONS;
|
||||
ipa_max_valid_rm_entry = 6; /* max is IPA_MAX_RM_ENTRY (6)*/
|
||||
|
||||
IPACMDBG_H(" depend MAP-0 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_Q6_CONS);
|
||||
IPACMDBG_H(" depend MAP-1 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_USB_PROD, IPA_RM_RESOURCE_Q6_CONS);
|
||||
IPACMDBG_H(" depend MAP-2 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_USB_CONS);
|
||||
IPACMDBG_H(" depend MAP-3 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_ODU_ADAPT_PROD, IPA_RM_RESOURCE_Q6_CONS);
|
||||
IPACMDBG_H(" depend MAP-4 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_ODU_ADAPT_CONS);
|
||||
IPACMDBG_H(" depend MAP-5 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_ODU_ADAPT_PROD, IPA_RM_RESOURCE_USB_CONS);
|
||||
|
||||
fail:
|
||||
if (cfg != NULL)
|
||||
{
|
||||
free(cfg);
|
||||
cfg = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
IPACM_Config* IPACM_Config::GetInstance()
|
||||
{
|
||||
int res = IPACM_SUCCESS;
|
||||
|
||||
if (pInstance == NULL)
|
||||
{
|
||||
pInstance = new IPACM_Config();
|
||||
|
||||
res = pInstance->Init();
|
||||
if (res != IPACM_SUCCESS)
|
||||
{
|
||||
delete pInstance;
|
||||
IPACMERR("unable to initialize config instance\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pInstance;
|
||||
}
|
||||
|
||||
int IPACM_Config::GetAlgPorts(int nPorts, ipacm_alg *pAlgPorts)
|
||||
{
|
||||
if (nPorts <= 0 || pAlgPorts == NULL)
|
||||
{
|
||||
IPACMERR("Invalid input\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int cnt = 0; cnt < nPorts; cnt++)
|
||||
{
|
||||
pAlgPorts[cnt].protocol = alg_table[cnt].protocol;
|
||||
pAlgPorts[cnt].port = alg_table[cnt].port;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IPACM_Config::GetNatIfaces(int nIfaces, NatIfaces *pIfaces)
|
||||
{
|
||||
if (nIfaces <= 0 || pIfaces == NULL)
|
||||
{
|
||||
IPACMERR("Invalid input\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int cnt=0; cnt<nIfaces; cnt++)
|
||||
{
|
||||
memcpy(pIfaces[cnt].iface_name,
|
||||
pNatIfaces[cnt].iface_name,
|
||||
sizeof(pIfaces[cnt].iface_name));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int IPACM_Config::AddNatIfaces(char *dev_name)
|
||||
{
|
||||
int i;
|
||||
/* Check if this iface already in NAT-iface*/
|
||||
for(i = 0; i < ipa_nat_iface_entries; i++)
|
||||
{
|
||||
if(strncmp(dev_name,
|
||||
pNatIfaces[i].iface_name,
|
||||
sizeof(pNatIfaces[i].iface_name)) == 0)
|
||||
{
|
||||
IPACMDBG("Interface (%s) is add to nat iface already\n", dev_name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
IPACMDBG_H("Add iface %s to NAT-ifaces, origin it has %d nat ifaces\n",
|
||||
dev_name, ipa_nat_iface_entries);
|
||||
ipa_nat_iface_entries++;
|
||||
|
||||
if (ipa_nat_iface_entries < ipa_num_ipa_interfaces)
|
||||
{
|
||||
memcpy(pNatIfaces[ipa_nat_iface_entries - 1].iface_name,
|
||||
dev_name, IPA_IFACE_NAME_LEN);
|
||||
|
||||
IPACMDBG_H("Add Nat IfaceName: %s ,update nat-ifaces number: %d\n",
|
||||
pNatIfaces[ipa_nat_iface_entries - 1].iface_name,
|
||||
ipa_nat_iface_entries);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IPACM_Config::DelNatIfaces(char *dev_name)
|
||||
{
|
||||
int i = 0;
|
||||
IPACMDBG_H("Del iface %s from NAT-ifaces, origin it has %d nat ifaces\n",
|
||||
dev_name, 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);
|
||||
|
||||
/* Reset the matched entry */
|
||||
memset(pNatIfaces[i].iface_name, 0, IPA_IFACE_NAME_LEN);
|
||||
|
||||
for (; i < ipa_nat_iface_entries - 1; i++)
|
||||
{
|
||||
memcpy(pNatIfaces[i].iface_name,
|
||||
pNatIfaces[i + 1].iface_name, IPA_IFACE_NAME_LEN);
|
||||
|
||||
/* Reset the copied entry */
|
||||
memset(pNatIfaces[i + 1].iface_name, 0, IPA_IFACE_NAME_LEN);
|
||||
}
|
||||
ipa_nat_iface_entries--;
|
||||
IPACMDBG_H("Update nat-ifaces number: %d\n", ipa_nat_iface_entries);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
IPACMDBG_H("Can't find Nat IfaceName: %s with total nat-ifaces number: %d\n",
|
||||
dev_name, ipa_nat_iface_entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* for IPACM resource manager dependency usage
|
||||
add either Tx or Rx ipa_rm_resource_name and
|
||||
also indicate that endpoint property if valid */
|
||||
void IPACM_Config::AddRmDepend(ipa_rm_resource_name rm1,bool rx_bypass_ipa)
|
||||
{
|
||||
int retval = 0;
|
||||
struct ipa_ioc_rm_dependency dep;
|
||||
|
||||
IPACMDBG_H(" Got rm add-depend index : %d \n", rm1);
|
||||
/* ipa_rm_a2_check: IPA_RM_RESOURCE_Q6_CONS*/
|
||||
if(rm1 == IPA_RM_RESOURCE_Q6_CONS)
|
||||
{
|
||||
ipa_rm_a2_check+=1;
|
||||
IPACMDBG_H("got %d times default RT routing from A2 \n", ipa_rm_a2_check);
|
||||
}
|
||||
|
||||
for(int i=0;i<ipa_max_valid_rm_entry;i++)
|
||||
{
|
||||
if(rm1 == ipa_rm_tbl[i].producer_rm1)
|
||||
{
|
||||
ipa_rm_tbl[i].producer1_up = true;
|
||||
/* entry1's producer actually dun have registered Rx-property */
|
||||
ipa_rm_tbl[i].rx_bypass_ipa = rx_bypass_ipa;
|
||||
IPACMDBG_H("Matched RM_table entry: %d's producer_rm1 with non_rx_prop: %d \n", i,ipa_rm_tbl[i].rx_bypass_ipa);
|
||||
|
||||
if(ipa_rm_tbl[i].consumer1_up == true && ipa_rm_tbl[i].rm_set == false)
|
||||
{
|
||||
IPACMDBG_H("SETUP RM_table entry %d's bi-direction dependency \n", i);
|
||||
/* add bi-directional dependency*/
|
||||
if(ipa_rm_tbl[i].rx_bypass_ipa)
|
||||
{
|
||||
IPACMDBG_H("Skip ADD entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&dep, 0, sizeof(dep));
|
||||
dep.resource_name = ipa_rm_tbl[i].producer_rm1;
|
||||
dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1;
|
||||
retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep);
|
||||
IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
|
||||
}
|
||||
}
|
||||
memset(&dep, 0, sizeof(dep));
|
||||
dep.resource_name = ipa_rm_tbl[i].producer_rm2;
|
||||
dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2;
|
||||
retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep);
|
||||
IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
|
||||
}
|
||||
ipa_rm_tbl[i].rm_set = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG_H("Not SETUP RM_table entry %d: prod_up:%d, cons_up:%d, rm_set: %d \n", i,ipa_rm_tbl[i].producer1_up, ipa_rm_tbl[i].consumer1_up, ipa_rm_tbl[i].rm_set);
|
||||
}
|
||||
}
|
||||
|
||||
if(rm1 == ipa_rm_tbl[i].consumer_rm1)
|
||||
{
|
||||
ipa_rm_tbl[i].consumer1_up = true;
|
||||
IPACMDBG_H("Matched RM_table entry: %d's consumer_rm1 \n", i);
|
||||
|
||||
if(ipa_rm_tbl[i].producer1_up == true && ipa_rm_tbl[i].rm_set == false)
|
||||
{
|
||||
IPACMDBG_H("SETUP RM_table entry %d's bi-direction dependency \n", i);
|
||||
/* add bi-directional dependency*/
|
||||
if(ipa_rm_tbl[i].rx_bypass_ipa)
|
||||
{
|
||||
IPACMDBG_H("Skip ADD entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&dep, 0, sizeof(dep));
|
||||
dep.resource_name = ipa_rm_tbl[i].producer_rm1;
|
||||
dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1;
|
||||
retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep);
|
||||
IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
|
||||
}
|
||||
}
|
||||
|
||||
memset(&dep, 0, sizeof(dep));
|
||||
dep.resource_name = ipa_rm_tbl[i].producer_rm2;
|
||||
dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2;
|
||||
retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep);
|
||||
IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
|
||||
}
|
||||
ipa_rm_tbl[i].rm_set = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG_H("Not SETUP RM_table entry %d: prod_up:%d, cons_up:%d, rm_set: %d \n", i,ipa_rm_tbl[i].producer1_up, ipa_rm_tbl[i].consumer1_up, ipa_rm_tbl[i].rm_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
/* for IPACM resource manager dependency usage
|
||||
delete either Tx or Rx ipa_rm_resource_name */
|
||||
|
||||
void IPACM_Config::DelRmDepend(ipa_rm_resource_name rm1)
|
||||
{
|
||||
int retval = 0;
|
||||
struct ipa_ioc_rm_dependency dep;
|
||||
|
||||
IPACMDBG_H(" Got rm del-depend index : %d \n", rm1);
|
||||
/* ipa_rm_a2_check: IPA_RM_RESOURCE_Q6_CONS*/
|
||||
if(rm1 == IPA_RM_RESOURCE_Q6_CONS)
|
||||
{
|
||||
ipa_rm_a2_check-=1;
|
||||
IPACMDBG_H("Left %d times default RT routing from A2 \n", ipa_rm_a2_check);
|
||||
}
|
||||
|
||||
for(int i=0;i<ipa_max_valid_rm_entry;i++)
|
||||
{
|
||||
|
||||
if(rm1 == ipa_rm_tbl[i].producer_rm1)
|
||||
{
|
||||
if(ipa_rm_tbl[i].rm_set == true)
|
||||
{
|
||||
IPACMDBG_H("Matched RM_table entry: %d's producer_rm1 and dependency is up \n", i);
|
||||
ipa_rm_tbl[i].rm_set = false;
|
||||
|
||||
/* delete bi-directional dependency*/
|
||||
if(ipa_rm_tbl[i].rx_bypass_ipa)
|
||||
{
|
||||
IPACMDBG_H("Skip DEL entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&dep, 0, sizeof(dep));
|
||||
dep.resource_name = ipa_rm_tbl[i].producer_rm1;
|
||||
dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1;
|
||||
retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep);
|
||||
IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
|
||||
}
|
||||
}
|
||||
memset(&dep, 0, sizeof(dep));
|
||||
dep.resource_name = ipa_rm_tbl[i].producer_rm2;
|
||||
dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2;
|
||||
retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep);
|
||||
IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
|
||||
}
|
||||
}
|
||||
ipa_rm_tbl[i].producer1_up = false;
|
||||
ipa_rm_tbl[i].rx_bypass_ipa = false;
|
||||
}
|
||||
if(rm1 == ipa_rm_tbl[i].consumer_rm1)
|
||||
{
|
||||
/* ipa_rm_a2_check: IPA_RM_RESOURCE_!6_CONS*/
|
||||
if(ipa_rm_tbl[i].consumer_rm1 == IPA_RM_RESOURCE_Q6_CONS && ipa_rm_a2_check == 1)
|
||||
{
|
||||
IPACMDBG_H(" still have %d default RT routing from A2 \n", ipa_rm_a2_check);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(ipa_rm_tbl[i].rm_set == true)
|
||||
{
|
||||
IPACMDBG_H("Matched RM_table entry: %d's consumer_rm1 and dependency is up \n", i);
|
||||
ipa_rm_tbl[i].rm_set = false;
|
||||
/* delete bi-directional dependency*/
|
||||
if(ipa_rm_tbl[i].rx_bypass_ipa)
|
||||
{
|
||||
IPACMDBG_H("Skip DEL entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&dep, 0, sizeof(dep));
|
||||
dep.resource_name = ipa_rm_tbl[i].producer_rm1;
|
||||
dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1;
|
||||
retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep);
|
||||
IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
|
||||
}
|
||||
}
|
||||
|
||||
memset(&dep, 0, sizeof(dep));
|
||||
dep.resource_name = ipa_rm_tbl[i].producer_rm2;
|
||||
dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2;
|
||||
retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep);
|
||||
IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval);
|
||||
}
|
||||
}
|
||||
ipa_rm_tbl[i].consumer1_up = false;
|
||||
}
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
int IPACM_Config::SetExtProp(ipa_ioc_query_intf_ext_props *prop)
|
||||
{
|
||||
int i, num;
|
||||
|
||||
if(prop == NULL || prop->num_ext_props <= 0)
|
||||
{
|
||||
IPACMERR("There is no extended property!\n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
num = prop->num_ext_props;
|
||||
for(i=0; i<num; i++)
|
||||
{
|
||||
if(prop->ext[i].ip == IPA_IP_v4)
|
||||
{
|
||||
if(ext_prop_v4.num_ext_props >= MAX_NUM_EXT_PROPS)
|
||||
{
|
||||
IPACMERR("IPv4 extended property table is full!\n");
|
||||
continue;
|
||||
}
|
||||
memcpy(&ext_prop_v4.prop[ext_prop_v4.num_ext_props], &prop->ext[i], sizeof(struct ipa_ioc_ext_intf_prop));
|
||||
ext_prop_v4.num_ext_props++;
|
||||
}
|
||||
else if(prop->ext[i].ip == IPA_IP_v6)
|
||||
{
|
||||
if(ext_prop_v6.num_ext_props >= MAX_NUM_EXT_PROPS)
|
||||
{
|
||||
IPACMERR("IPv6 extended property table is full!\n");
|
||||
continue;
|
||||
}
|
||||
memcpy(&ext_prop_v6.prop[ext_prop_v6.num_ext_props], &prop->ext[i], sizeof(struct ipa_ioc_ext_intf_prop));
|
||||
ext_prop_v6.num_ext_props++;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMERR("The IP type is not expected!\n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
IPACMDBG_H("Set extended property succeeded.\n");
|
||||
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
ipacm_ext_prop* IPACM_Config::GetExtProp(ipa_ip_type ip_type)
|
||||
{
|
||||
if(ip_type == IPA_IP_v4)
|
||||
return &ext_prop_v4;
|
||||
else if(ip_type == IPA_IP_v6)
|
||||
return &ext_prop_v6;
|
||||
else
|
||||
{
|
||||
IPACMERR("Failed to get extended property: the IP version is neither IPv4 nor IPv6!\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int IPACM_Config::DelExtProp(ipa_ip_type ip_type)
|
||||
{
|
||||
if(ip_type != IPA_IP_v6)
|
||||
{
|
||||
memset(&ext_prop_v4, 0, sizeof(ext_prop_v4));
|
||||
}
|
||||
|
||||
if(ip_type != IPA_IP_v4)
|
||||
{
|
||||
memset(&ext_prop_v6, 0, sizeof(ext_prop_v6));
|
||||
}
|
||||
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
const char* IPACM_Config::getEventName(ipa_cm_event_id event_id)
|
||||
{
|
||||
if(event_id >= sizeof(ipacm_event_name)/sizeof(ipacm_event_name[0]))
|
||||
{
|
||||
IPACMERR("Event name array is not consistent with event array!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ipacm_event_name[event_id];
|
||||
}
|
||||
652
data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackClient.cpp
Normal file
652
data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackClient.cpp
Normal file
@@ -0,0 +1,652 @@
|
||||
/*
|
||||
Copyright (c) 2013-2016, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include "IPACM_Iface.h"
|
||||
#include "IPACM_ConntrackListener.h"
|
||||
#include "IPACM_ConntrackClient.h"
|
||||
#include "IPACM_Log.h"
|
||||
|
||||
#define LO_NAME "lo"
|
||||
|
||||
extern IPACM_EvtDispatcher cm_dis;
|
||||
extern void ParseCTMessage(struct nf_conntrack *ct);
|
||||
|
||||
IPACM_ConntrackClient *IPACM_ConntrackClient::pInstance = NULL;
|
||||
IPACM_ConntrackListener *CtList = NULL;
|
||||
|
||||
/* ================================
|
||||
Local Function Definitions
|
||||
=================================
|
||||
*/
|
||||
IPACM_ConntrackClient::IPACM_ConntrackClient()
|
||||
{
|
||||
IPACMDBG("\n");
|
||||
|
||||
tcp_hdl = NULL;
|
||||
udp_hdl = NULL;
|
||||
tcp_filter = NULL;
|
||||
udp_filter = NULL;
|
||||
}
|
||||
|
||||
IPACM_ConntrackClient* IPACM_ConntrackClient::GetInstance()
|
||||
{
|
||||
if(pInstance == NULL)
|
||||
{
|
||||
pInstance = new IPACM_ConntrackClient();
|
||||
|
||||
pInstance->udp_filter = nfct_filter_create();
|
||||
if(pInstance->udp_filter == NULL)
|
||||
{
|
||||
IPACMERR("unable to create UDP filter\n");
|
||||
delete pInstance;
|
||||
return NULL;
|
||||
}
|
||||
IPACMDBG("Created UDP filter\n");
|
||||
|
||||
pInstance->tcp_filter = nfct_filter_create();
|
||||
if(pInstance->tcp_filter == NULL)
|
||||
{
|
||||
IPACMERR("unable to create TCP filter\n");
|
||||
delete pInstance;
|
||||
return NULL;
|
||||
}
|
||||
IPACMDBG("Created TCP filter\n");
|
||||
}
|
||||
|
||||
return pInstance;
|
||||
}
|
||||
|
||||
int IPACM_ConntrackClient::IPAConntrackEventCB
|
||||
(
|
||||
enum nf_conntrack_msg_type type,
|
||||
struct nf_conntrack *ct,
|
||||
void *data
|
||||
)
|
||||
{
|
||||
ipacm_cmd_q_data evt_data;
|
||||
ipacm_ct_evt_data *ct_data;
|
||||
uint8_t ip_type = 0;
|
||||
|
||||
IPACMDBG("Event callback called with msgtype: %d\n",type);
|
||||
|
||||
/* Retrieve ip type */
|
||||
ip_type = nfct_get_attr_u8(ct, ATTR_REPL_L3PROTO);
|
||||
|
||||
#ifndef CT_OPT
|
||||
if(AF_INET6 == ip_type)
|
||||
{
|
||||
IPACMDBG("Ignoring ipv6(%d) connections\n", ip_type);
|
||||
goto IGNORE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ct_data = (ipacm_ct_evt_data *)malloc(sizeof(ipacm_ct_evt_data));
|
||||
if(ct_data == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory \n");
|
||||
goto IGNORE;
|
||||
}
|
||||
|
||||
ct_data->ct = ct;
|
||||
ct_data->type = type;
|
||||
|
||||
evt_data.event = IPA_PROCESS_CT_MESSAGE;
|
||||
evt_data.evt_data = (void *)ct_data;
|
||||
|
||||
#ifdef CT_OPT
|
||||
if(AF_INET6 == ip_type)
|
||||
{
|
||||
evt_data.event = IPA_PROCESS_CT_MESSAGE_V6;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(0 != IPACM_EvtDispatcher::PostEvt(&evt_data))
|
||||
{
|
||||
IPACMERR("Error sending Conntrack message to processing thread!\n");
|
||||
free(ct_data);
|
||||
goto IGNORE;
|
||||
}
|
||||
|
||||
/* NFCT_CB_STOLEN means that the conntrack object is not released after the
|
||||
callback That must be manually done later when the object is no longer needed. */
|
||||
return NFCT_CB_STOLEN;
|
||||
|
||||
IGNORE:
|
||||
nfct_destroy(ct);
|
||||
return NFCT_CB_STOLEN;
|
||||
|
||||
}
|
||||
|
||||
int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Bridge_Addrs
|
||||
(
|
||||
struct nfct_filter *filter
|
||||
)
|
||||
{
|
||||
int fd;
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if(fd < 0)
|
||||
{
|
||||
PERROR("unable to open socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret;
|
||||
uint32_t ipv4_addr;
|
||||
struct ifreq ifr;
|
||||
|
||||
/* retrieve bridge interface ipv4 address */
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
(void)strncpy(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)
|
||||
{
|
||||
IPACMERR("unable to retrieve (%s) interface address\n",ifr.ifr_name);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
IPACMDBG("Interface (%s) address %s\n", ifr.ifr_name, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
|
||||
ipv4_addr = ntohl(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr);
|
||||
close(fd);
|
||||
|
||||
/* ignore whatever is destined to or originates from broadcast ip address */
|
||||
struct nfct_filter_ipv4 filter_ipv4;
|
||||
|
||||
filter_ipv4.addr = ipv4_addr;
|
||||
filter_ipv4.mask = 0xffffffff;
|
||||
|
||||
nfct_filter_set_logic(filter,
|
||||
NFCT_FILTER_DST_IPV4,
|
||||
NFCT_FILTER_LOGIC_NEGATIVE);
|
||||
|
||||
nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
|
||||
|
||||
nfct_filter_set_logic(filter,
|
||||
NFCT_FILTER_SRC_IPV4,
|
||||
NFCT_FILTER_LOGIC_NEGATIVE);
|
||||
|
||||
nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Local_Iface
|
||||
(
|
||||
struct nfct_filter *filter,
|
||||
ipacm_event_iface_up *param
|
||||
)
|
||||
{
|
||||
struct nfct_filter_ipv4 filter_ipv4;
|
||||
|
||||
filter_ipv4.addr = param->ipv4_addr;
|
||||
filter_ipv4.mask = 0xffffffff;
|
||||
|
||||
/* ignore whatever is destined to local interfaces */
|
||||
IPACMDBG("Ignore connections destinated to interface %s", param->ifname);
|
||||
iptodot("with ipv4 address", param->ipv4_addr);
|
||||
nfct_filter_set_logic(filter,
|
||||
NFCT_FILTER_DST_IPV4,
|
||||
NFCT_FILTER_LOGIC_NEGATIVE);
|
||||
|
||||
nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
|
||||
|
||||
IPACMDBG("Ignore connections orignated from interface %s", param->ifname);
|
||||
iptodot("with ipv4 address", filter_ipv4.addr);
|
||||
nfct_filter_set_logic(filter,
|
||||
NFCT_FILTER_SRC_IPV4,
|
||||
NFCT_FILTER_LOGIC_NEGATIVE);
|
||||
|
||||
nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4);
|
||||
|
||||
/* Retrieve broadcast address */
|
||||
/* Intialize with 255.255.255.255 */
|
||||
uint32_t bc_ip_addr = 0xFFFFFFFF;
|
||||
|
||||
/* calculate broadcast address from addr and addr_mask */
|
||||
bc_ip_addr = (bc_ip_addr & (~param->addr_mask));
|
||||
bc_ip_addr = (bc_ip_addr | (param->ipv4_addr & param->addr_mask));
|
||||
|
||||
/* netfitler expecting in host-byte order */
|
||||
filter_ipv4.addr = bc_ip_addr;
|
||||
filter_ipv4.mask = 0xffffffff;
|
||||
|
||||
iptodot("with broadcast address", filter_ipv4.addr);
|
||||
nfct_filter_set_logic(filter,
|
||||
NFCT_FILTER_DST_IPV4,
|
||||
NFCT_FILTER_LOGIC_NEGATIVE);
|
||||
|
||||
nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Function which sets up filters to ignore
|
||||
connections to and from local interfaces */
|
||||
int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Local_Addrs
|
||||
(
|
||||
struct nfct_filter *filter
|
||||
)
|
||||
{
|
||||
struct nfct_filter_ipv4 filter_ipv4;
|
||||
|
||||
/* ignore whatever is destined to or originates from broadcast ip address */
|
||||
filter_ipv4.addr = 0xffffffff;
|
||||
filter_ipv4.mask = 0xffffffff;
|
||||
|
||||
nfct_filter_set_logic(filter,
|
||||
NFCT_FILTER_DST_IPV4,
|
||||
NFCT_FILTER_LOGIC_NEGATIVE);
|
||||
|
||||
nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
|
||||
|
||||
nfct_filter_set_logic(filter,
|
||||
NFCT_FILTER_SRC_IPV4,
|
||||
NFCT_FILTER_LOGIC_NEGATIVE);
|
||||
|
||||
nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4);
|
||||
|
||||
return 0;
|
||||
} /* IPA_Conntrack_Filters_Ignore_Local_Addrs() */
|
||||
|
||||
/* Initialize TCP Filter */
|
||||
int IPACM_ConntrackClient::IPA_Conntrack_TCP_Filter_Init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
IPACM_ConntrackClient *pClient;
|
||||
|
||||
IPACMDBG("\n");
|
||||
|
||||
pClient = IPACM_ConntrackClient::GetInstance();
|
||||
if(pClient == NULL)
|
||||
{
|
||||
IPACMERR("unable to get conntrack client instance\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = nfct_filter_set_logic(pClient->tcp_filter,
|
||||
NFCT_FILTER_L4PROTO,
|
||||
NFCT_FILTER_LOGIC_POSITIVE);
|
||||
if(ret == -1)
|
||||
{
|
||||
IPACMERR("Unable to set filter logic\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set protocol filters as tcp and udp */
|
||||
nfct_filter_add_attr_u32(pClient->tcp_filter, NFCT_FILTER_L4PROTO, IPPROTO_TCP);
|
||||
|
||||
|
||||
struct nfct_filter_proto tcp_proto_state;
|
||||
tcp_proto_state.proto = IPPROTO_TCP;
|
||||
tcp_proto_state.state = TCP_CONNTRACK_ESTABLISHED;
|
||||
|
||||
ret = nfct_filter_set_logic(pClient->tcp_filter,
|
||||
NFCT_FILTER_L4PROTO_STATE,
|
||||
NFCT_FILTER_LOGIC_POSITIVE);
|
||||
if(ret == -1)
|
||||
{
|
||||
IPACMERR("unable to set filter logic\n");
|
||||
return -1;
|
||||
}
|
||||
nfct_filter_add_attr(pClient->tcp_filter,
|
||||
NFCT_FILTER_L4PROTO_STATE,
|
||||
&tcp_proto_state);
|
||||
|
||||
|
||||
tcp_proto_state.proto = IPPROTO_TCP;
|
||||
tcp_proto_state.state = TCP_CONNTRACK_FIN_WAIT;
|
||||
ret = nfct_filter_set_logic(pClient->tcp_filter,
|
||||
NFCT_FILTER_L4PROTO_STATE,
|
||||
NFCT_FILTER_LOGIC_POSITIVE);
|
||||
if(ret == -1)
|
||||
{
|
||||
IPACMERR("unable to set filter logic\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
nfct_filter_add_attr(pClient->tcp_filter,
|
||||
NFCT_FILTER_L4PROTO_STATE,
|
||||
&tcp_proto_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize UDP Filter */
|
||||
int IPACM_ConntrackClient::IPA_Conntrack_UDP_Filter_Init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
IPACM_ConntrackClient *pClient = IPACM_ConntrackClient::GetInstance();
|
||||
if(pClient == NULL)
|
||||
{
|
||||
IPACMERR("unable to get conntrack client instance\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = nfct_filter_set_logic(pClient->udp_filter,
|
||||
NFCT_FILTER_L4PROTO,
|
||||
NFCT_FILTER_LOGIC_POSITIVE);
|
||||
if(ret == -1)
|
||||
{
|
||||
IPACMERR("unable to set filter logic\n");
|
||||
}
|
||||
/* set protocol filters as tcp and udp */
|
||||
nfct_filter_add_attr_u32(pClient->udp_filter, NFCT_FILTER_L4PROTO, IPPROTO_UDP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* IPACM_ConntrackClient::UDPConnTimeoutUpdate(void *ptr)
|
||||
{
|
||||
|
||||
NatApp *nat_inst = NULL;
|
||||
#ifdef IPACM_DEBUG
|
||||
IPACMDBG("\n");
|
||||
#endif
|
||||
|
||||
nat_inst = NatApp::GetInstance();
|
||||
if(nat_inst == NULL)
|
||||
{
|
||||
IPACMERR("unable to create nat instance\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
nat_inst->UpdateUDPTimeStamp();
|
||||
sleep(UDP_TIMEOUT_UPDATE);
|
||||
} /* end of while(1) loop */
|
||||
|
||||
#ifdef IPACM_DEBUG
|
||||
IPACMDBG("Returning from %s() %d\n", __FUNCTION__, __LINE__);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Thread to initialize TCP Conntrack Filters*/
|
||||
void* IPACM_ConntrackClient::TCPRegisterWithConnTrack(void *)
|
||||
{
|
||||
int ret;
|
||||
IPACM_ConntrackClient *pClient;
|
||||
unsigned subscrips = 0;
|
||||
|
||||
IPACMDBG("\n");
|
||||
|
||||
pClient = IPACM_ConntrackClient::GetInstance();
|
||||
if(pClient == NULL)
|
||||
{
|
||||
IPACMERR("unable to get conntrack client instance\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subscrips = (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
|
||||
#ifdef CT_OPT
|
||||
subscrips |= NF_NETLINK_CONNTRACK_NEW;
|
||||
#endif
|
||||
|
||||
pClient->tcp_hdl = nfct_open(CONNTRACK, subscrips);
|
||||
if(pClient->tcp_hdl == NULL)
|
||||
{
|
||||
PERROR("nfct_open\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the filter */
|
||||
ret = IPA_Conntrack_TCP_Filter_Init();
|
||||
if(ret == -1)
|
||||
{
|
||||
IPACMERR("Unable to initliaze TCP Filter\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Attach the filter to net filter handler */
|
||||
ret = nfct_filter_attach(nfct_fd(pClient->tcp_hdl), pClient->tcp_filter);
|
||||
if(ret == -1)
|
||||
{
|
||||
IPACMDBG("unable to attach TCP filter\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Register callback with netfilter handler */
|
||||
IPACMDBG_H("tcp handle:%p, fd:%d\n", pClient->tcp_hdl, nfct_fd(pClient->tcp_hdl));
|
||||
#ifndef CT_OPT
|
||||
nfct_callback_register(pClient->tcp_hdl,
|
||||
(nf_conntrack_msg_type) (NFCT_T_UPDATE | NFCT_T_DESTROY | NFCT_T_NEW),
|
||||
IPAConntrackEventCB, NULL);
|
||||
#else
|
||||
nfct_callback_register(pClient->tcp_hdl, (nf_conntrack_msg_type) NFCT_T_ALL, IPAConntrackEventCB, NULL);
|
||||
#endif
|
||||
|
||||
/* Block to catch events from net filter connection track */
|
||||
/* nfct_catch() receives conntrack events from kernel-space, by default it
|
||||
blocks waiting for events. */
|
||||
IPACMDBG("Waiting for events\n");
|
||||
|
||||
ret = nfct_catch(pClient->tcp_hdl);
|
||||
if(ret == -1)
|
||||
{
|
||||
IPACMERR("(%d)(%s)\n", ret, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IPACMDBG("Exit from tcp thread\n");
|
||||
|
||||
/* destroy the filter.. this will not detach the filter */
|
||||
nfct_filter_destroy(pClient->tcp_filter);
|
||||
pClient->tcp_filter = NULL;
|
||||
|
||||
/* de-register the callback */
|
||||
nfct_callback_unregister(pClient->tcp_hdl);
|
||||
/* close the handle */
|
||||
nfct_close(pClient->tcp_hdl);
|
||||
pClient->tcp_hdl = NULL;
|
||||
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Thread to initialize UDP Conntrack Filters*/
|
||||
void* IPACM_ConntrackClient::UDPRegisterWithConnTrack(void *)
|
||||
{
|
||||
int ret;
|
||||
IPACM_ConntrackClient *pClient = NULL;
|
||||
|
||||
IPACMDBG("\n");
|
||||
|
||||
pClient = IPACM_ConntrackClient::GetInstance();
|
||||
if(pClient == NULL)
|
||||
{
|
||||
IPACMERR("unable to retrieve instance of conntrack client\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pClient->udp_hdl = nfct_open(CONNTRACK,
|
||||
(NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY));
|
||||
if(pClient->udp_hdl == NULL)
|
||||
{
|
||||
PERROR("nfct_open\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize Filter */
|
||||
ret = IPA_Conntrack_UDP_Filter_Init();
|
||||
if(-1 == ret)
|
||||
{
|
||||
IPACMDBG("Unable to initalize udp filters\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Attach the filter to net filter handler */
|
||||
ret = nfct_filter_attach(nfct_fd(pClient->udp_hdl), pClient->udp_filter);
|
||||
if(ret == -1)
|
||||
{
|
||||
IPACMDBG("unable to attach the filter\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Register callback with netfilter handler */
|
||||
IPACMDBG_H("udp handle:%p, fd:%d\n", pClient->udp_hdl, nfct_fd(pClient->udp_hdl));
|
||||
nfct_callback_register(pClient->udp_hdl,
|
||||
(nf_conntrack_msg_type)(NFCT_T_NEW | NFCT_T_DESTROY),
|
||||
IPAConntrackEventCB,
|
||||
NULL);
|
||||
|
||||
/* Block to catch events from net filter connection track */
|
||||
ctcatch:
|
||||
ret = nfct_catch(pClient->udp_hdl);
|
||||
if(ret == -1)
|
||||
{
|
||||
IPACMDBG("(%d)(%s)\n", ret, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG("ctcatch ret:%d\n", ret);
|
||||
goto ctcatch;
|
||||
}
|
||||
|
||||
IPACMDBG("Exit from udp thread with ret: %d\n", ret);
|
||||
|
||||
/* destroy the filter.. this will not detach the filter */
|
||||
nfct_filter_destroy(pClient->udp_filter);
|
||||
pClient->udp_filter = NULL;
|
||||
|
||||
/* de-register the callback */
|
||||
nfct_callback_unregister(pClient->udp_hdl);
|
||||
/* close the handle */
|
||||
nfct_close(pClient->udp_hdl);
|
||||
pClient->udp_hdl = NULL;
|
||||
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void IPACM_ConntrackClient::UpdateUDPFilters(void *param, bool isWan)
|
||||
{
|
||||
static bool isIgnore = false;
|
||||
int ret = 0;
|
||||
IPACM_ConntrackClient *pClient = NULL;
|
||||
|
||||
pClient = IPACM_ConntrackClient::GetInstance();
|
||||
if(pClient == NULL)
|
||||
{
|
||||
IPACMERR("unable to retrieve conntrack client instance\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(pClient->udp_filter == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!isWan)
|
||||
{
|
||||
IPA_Conntrack_Filters_Ignore_Local_Iface(pClient->udp_filter,
|
||||
(ipacm_event_iface_up *)param);
|
||||
|
||||
if(!isIgnore)
|
||||
{
|
||||
IPA_Conntrack_Filters_Ignore_Bridge_Addrs(pClient->udp_filter);
|
||||
IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter);
|
||||
isIgnore = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Attach the filter to udp handle */
|
||||
if(pClient->udp_hdl != NULL)
|
||||
{
|
||||
IPACMDBG("attaching the filter to udp handle\n");
|
||||
ret = nfct_filter_attach(nfct_fd(pClient->udp_hdl), pClient->udp_filter);
|
||||
if(ret == -1)
|
||||
{
|
||||
PERROR("unable to attach the filter to udp handle\n");
|
||||
IPACMERR("udp handle:%p, fd:%d Error: %d\n",pClient->udp_hdl, nfct_fd(pClient->udp_hdl), ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void IPACM_ConntrackClient::UpdateTCPFilters(void *param, bool isWan)
|
||||
{
|
||||
static bool isIgnore = false;
|
||||
int ret = 0;
|
||||
IPACM_ConntrackClient *pClient = NULL;
|
||||
|
||||
pClient = IPACM_ConntrackClient::GetInstance();
|
||||
if(pClient == NULL)
|
||||
{
|
||||
IPACMERR("unable to retrieve conntrack client instance\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(pClient->tcp_filter == NULL)
|
||||
return;
|
||||
|
||||
if(!isWan)
|
||||
{
|
||||
IPA_Conntrack_Filters_Ignore_Local_Iface(pClient->tcp_filter,
|
||||
(ipacm_event_iface_up *)param);
|
||||
|
||||
if(!isIgnore)
|
||||
{
|
||||
IPA_Conntrack_Filters_Ignore_Bridge_Addrs(pClient->udp_filter);
|
||||
IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter);
|
||||
isIgnore = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Attach the filter to tcp handle */
|
||||
if(pClient->tcp_hdl != NULL)
|
||||
{
|
||||
IPACMDBG("attaching the filter to tcp handle\n");
|
||||
ret = nfct_filter_attach(nfct_fd(pClient->tcp_hdl), pClient->tcp_filter);
|
||||
if(ret == -1)
|
||||
{
|
||||
PERROR("unable to attach the filter to tcp handle\n");
|
||||
IPACMERR("tcp handle:%p, fd:%d Error: %d\n",pClient->tcp_hdl, nfct_fd(pClient->tcp_hdl), ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1200
data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp
Normal file
1200
data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp
Normal file
File diff suppressed because it is too large
Load Diff
969
data-ipa-cfg-mgr/ipacm/src/IPACM_Conntrack_NATApp.cpp
Normal file
969
data-ipa-cfg-mgr/ipacm/src/IPACM_Conntrack_NATApp.cpp
Normal file
@@ -0,0 +1,969 @@
|
||||
/*
|
||||
Copyright (c) 2013-2016, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.
|
||||
*/
|
||||
#include "IPACM_Conntrack_NATApp.h"
|
||||
#include "IPACM_ConntrackClient.h"
|
||||
|
||||
#define INVALID_IP_ADDR 0x0
|
||||
|
||||
/* NatApp class Implementation */
|
||||
NatApp *NatApp::pInstance = NULL;
|
||||
NatApp::NatApp()
|
||||
{
|
||||
max_entries = 0;
|
||||
cache = NULL;
|
||||
|
||||
nat_table_hdl = 0;
|
||||
pub_ip_addr = 0;
|
||||
|
||||
curCnt = 0;
|
||||
|
||||
pALGPorts = NULL;
|
||||
nALGPort = 0;
|
||||
|
||||
ct = NULL;
|
||||
ct_hdl = NULL;
|
||||
|
||||
memset(temp, 0, sizeof(temp));
|
||||
}
|
||||
|
||||
int NatApp::Init(void)
|
||||
{
|
||||
IPACM_Config *pConfig;
|
||||
int size = 0;
|
||||
|
||||
pConfig = IPACM_Config::GetInstance();
|
||||
if(pConfig == NULL)
|
||||
{
|
||||
IPACMERR("Unable to get Config instance\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
max_entries = pConfig->GetNatMaxEntries();
|
||||
|
||||
size = (sizeof(nat_table_entry) * max_entries);
|
||||
cache = (nat_table_entry *)malloc(size);
|
||||
if(cache == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate memory for cache\n");
|
||||
goto fail;
|
||||
}
|
||||
IPACMDBG("Allocated %d bytes for config manager nat cache\n", size);
|
||||
memset(cache, 0, size);
|
||||
|
||||
nALGPort = pConfig->GetAlgPortCnt();
|
||||
if(nALGPort > 0)
|
||||
{
|
||||
pALGPorts = (ipacm_alg *)malloc(sizeof(ipacm_alg) * nALGPort);
|
||||
if(pALGPorts == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate memory for alg prots\n");
|
||||
goto fail;
|
||||
}
|
||||
memset(pALGPorts, 0, sizeof(ipacm_alg) * nALGPort);
|
||||
|
||||
if(pConfig->GetAlgPorts(nALGPort, pALGPorts) != 0)
|
||||
{
|
||||
IPACMERR("Unable to retrieve ALG prots\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
IPACMDBG("Printing %d alg ports information\n", nALGPort);
|
||||
for(int cnt=0; cnt<nALGPort; cnt++)
|
||||
{
|
||||
IPACMDBG("%d: Proto[%d], port[%d]\n", cnt, pALGPorts[cnt].protocol, pALGPorts[cnt].port);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
free(cache);
|
||||
free(pALGPorts);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NatApp* NatApp::GetInstance()
|
||||
{
|
||||
if(pInstance == NULL)
|
||||
{
|
||||
pInstance = new NatApp();
|
||||
|
||||
if(pInstance->Init())
|
||||
{
|
||||
delete pInstance;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pInstance;
|
||||
}
|
||||
|
||||
/* NAT APP related object function definitions */
|
||||
|
||||
int NatApp::AddTable(uint32_t pub_ip)
|
||||
{
|
||||
int ret;
|
||||
int cnt = 0;
|
||||
ipa_nat_ipv4_rule nat_rule;
|
||||
IPACMDBG_H("%s() %d\n", __FUNCTION__, __LINE__);
|
||||
|
||||
/* Not reset the cache wait it timeout by destroy event */
|
||||
#if 0
|
||||
if (pub_ip != pub_ip_addr_pre)
|
||||
{
|
||||
IPACMDBG("Reset the cache because NAT-ipv4 different\n");
|
||||
memset(cache, 0, sizeof(nat_table_entry) * max_entries);
|
||||
curCnt = 0;
|
||||
}
|
||||
#endif
|
||||
ret = ipa_nat_add_ipv4_tbl(pub_ip, max_entries, &nat_table_hdl);
|
||||
if(ret)
|
||||
{
|
||||
IPACMERR("unable to create nat table Error:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add back the cached NAT-entry */
|
||||
if (pub_ip == pub_ip_addr_pre)
|
||||
{
|
||||
IPACMDBG("Restore the cache to ipa NAT-table\n");
|
||||
for(cnt = 0; cnt < max_entries; cnt++)
|
||||
{
|
||||
if(cache[cnt].private_ip !=0)
|
||||
{
|
||||
memset(&nat_rule, 0 , sizeof(nat_rule));
|
||||
nat_rule.private_ip = cache[cnt].private_ip;
|
||||
nat_rule.target_ip = cache[cnt].target_ip;
|
||||
nat_rule.target_port = cache[cnt].target_port;
|
||||
nat_rule.private_port = cache[cnt].private_port;
|
||||
nat_rule.public_port = cache[cnt].public_port;
|
||||
nat_rule.protocol = cache[cnt].protocol;
|
||||
|
||||
if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
|
||||
{
|
||||
IPACMERR("unable to add the rule delete from cache\n");
|
||||
memset(&cache[cnt], 0, sizeof(cache[cnt]));
|
||||
curCnt--;
|
||||
continue;
|
||||
}
|
||||
cache[cnt].enabled = true;
|
||||
|
||||
IPACMDBG("On wan-iface reset added below rule successfully\n");
|
||||
iptodot("Private IP", nat_rule.private_ip);
|
||||
iptodot("Target IP", nat_rule.target_ip);
|
||||
IPACMDBG("Private Port:%d \t Target Port: %d\t", nat_rule.private_port, nat_rule.target_port);
|
||||
IPACMDBG("Public Port:%d\n", nat_rule.public_port);
|
||||
IPACMDBG("protocol: %d\n", nat_rule.protocol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub_ip_addr = pub_ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NatApp::Reset()
|
||||
{
|
||||
int cnt = 0;
|
||||
|
||||
nat_table_hdl = 0;
|
||||
pub_ip_addr = 0;
|
||||
/* NAT tbl deleted, reset enabled bit */
|
||||
for(cnt = 0; cnt < max_entries; cnt++)
|
||||
{
|
||||
cache[cnt].enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
int NatApp::DeleteTable(uint32_t pub_ip)
|
||||
{
|
||||
int ret;
|
||||
IPACMDBG_H("%s() %d\n", __FUNCTION__, __LINE__);
|
||||
|
||||
CHK_TBL_HDL();
|
||||
|
||||
if(pub_ip_addr != pub_ip)
|
||||
{
|
||||
IPACMDBG("Public ip address is not matching\n");
|
||||
IPACMERR("unable to delete the nat table\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ipa_nat_del_ipv4_tbl(nat_table_hdl);
|
||||
if(ret)
|
||||
{
|
||||
IPACMERR("unable to delete nat table Error: %d\n", ret);;
|
||||
return ret;
|
||||
}
|
||||
|
||||
pub_ip_addr_pre = pub_ip_addr;
|
||||
Reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for duplicate entries */
|
||||
bool NatApp::ChkForDup(const nat_table_entry *rule)
|
||||
{
|
||||
int cnt = 0;
|
||||
IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
|
||||
|
||||
for(; cnt < max_entries; cnt++)
|
||||
{
|
||||
if(cache[cnt].private_ip == rule->private_ip &&
|
||||
cache[cnt].target_ip == rule->target_ip &&
|
||||
cache[cnt].private_port == rule->private_port &&
|
||||
cache[cnt].target_port == rule->target_port &&
|
||||
cache[cnt].protocol == rule->protocol)
|
||||
{
|
||||
log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
|
||||
rule->target_port,"Duplicate Rule\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Delete the entry from Nat table on connection close */
|
||||
int NatApp::DeleteEntry(const nat_table_entry *rule)
|
||||
{
|
||||
int cnt = 0;
|
||||
IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
|
||||
|
||||
log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
|
||||
rule->target_port,"for deletion\n");
|
||||
|
||||
|
||||
for(; cnt < max_entries; cnt++)
|
||||
{
|
||||
if(cache[cnt].private_ip == rule->private_ip &&
|
||||
cache[cnt].target_ip == rule->target_ip &&
|
||||
cache[cnt].private_port == rule->private_port &&
|
||||
cache[cnt].target_port == rule->target_port &&
|
||||
cache[cnt].protocol == rule->protocol)
|
||||
{
|
||||
|
||||
if(cache[cnt].enabled == true)
|
||||
{
|
||||
if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
|
||||
{
|
||||
IPACMERR("%s() %d deletion failed\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
IPACMDBG_H("Deleted Nat entry(%d) Successfully\n", cnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG_H("Deleted Nat entry(%d) only from cache\n", cnt);
|
||||
}
|
||||
|
||||
memset(&cache[cnt], 0, sizeof(cache[cnt]));
|
||||
curCnt--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add new entry to the nat table on new connection */
|
||||
int NatApp::AddEntry(const nat_table_entry *rule)
|
||||
{
|
||||
int cnt = 0;
|
||||
ipa_nat_ipv4_rule nat_rule;
|
||||
|
||||
IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
|
||||
|
||||
CHK_TBL_HDL();
|
||||
log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
|
||||
rule->target_port,"for addition\n");
|
||||
if(isAlgPort(rule->protocol, rule->private_port) ||
|
||||
isAlgPort(rule->protocol, rule->target_port))
|
||||
{
|
||||
IPACMERR("connection using ALG Port, ignore\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(rule->private_ip == 0 ||
|
||||
rule->target_ip == 0 ||
|
||||
rule->private_port == 0 ||
|
||||
rule->target_port == 0 ||
|
||||
rule->protocol == 0)
|
||||
{
|
||||
IPACMERR("Invalid Connection, ignoring it\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!ChkForDup(rule))
|
||||
{
|
||||
for(; cnt < max_entries; cnt++)
|
||||
{
|
||||
if(cache[cnt].private_ip == 0 &&
|
||||
cache[cnt].target_ip == 0 &&
|
||||
cache[cnt].private_port == 0 &&
|
||||
cache[cnt].target_port == 0 &&
|
||||
cache[cnt].protocol == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(max_entries == cnt)
|
||||
{
|
||||
IPACMERR("Error: Unable to add, reached maximum rules\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nat_rule.private_ip = rule->private_ip;
|
||||
nat_rule.target_ip = rule->target_ip;
|
||||
nat_rule.target_port = rule->target_port;
|
||||
nat_rule.private_port = rule->private_port;
|
||||
nat_rule.public_port = rule->public_port;
|
||||
nat_rule.protocol = rule->protocol;
|
||||
|
||||
if(isPwrSaveIf(rule->private_ip) ||
|
||||
isPwrSaveIf(rule->target_ip))
|
||||
{
|
||||
IPACMDBG("Device is Power Save mode: Dont insert into nat table but cache\n");
|
||||
cache[cnt].enabled = false;
|
||||
cache[cnt].rule_hdl = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
|
||||
{
|
||||
IPACMERR("unable to add the rule\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cache[cnt].enabled = true;
|
||||
}
|
||||
|
||||
cache[cnt].private_ip = rule->private_ip;
|
||||
cache[cnt].target_ip = rule->target_ip;
|
||||
cache[cnt].target_port = rule->target_port;
|
||||
cache[cnt].private_port = rule->private_port;
|
||||
cache[cnt].protocol = rule->protocol;
|
||||
cache[cnt].timestamp = 0;
|
||||
cache[cnt].public_port = rule->public_port;
|
||||
cache[cnt].dst_nat = rule->dst_nat;
|
||||
curCnt++;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMERR("Duplicate rule. Ignore it\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(cache[cnt].enabled == true)
|
||||
{
|
||||
IPACMDBG_H("Added rule(%d) successfully\n", cnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG_H("Cached rule(%d) successfully\n", cnt);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NatApp::UpdateCTUdpTs(nat_table_entry *rule, uint32_t new_ts)
|
||||
{
|
||||
int ret;
|
||||
|
||||
iptodot("Private IP:", rule->private_ip);
|
||||
iptodot("Target IP:", rule->target_ip);
|
||||
IPACMDBG("Private Port: %d, Target Port: %d\n", rule->private_port, rule->target_port);
|
||||
|
||||
if(!ct_hdl)
|
||||
{
|
||||
ct_hdl = nfct_open(CONNTRACK, 0);
|
||||
if(!ct_hdl)
|
||||
{
|
||||
PERROR("nfct_open");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ct)
|
||||
{
|
||||
ct = nfct_new();
|
||||
if(!ct)
|
||||
{
|
||||
PERROR("nfct_new");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
|
||||
if(rule->protocol == IPPROTO_UDP)
|
||||
{
|
||||
nfct_set_attr_u8(ct, ATTR_L4PROTO, rule->protocol);
|
||||
nfct_set_attr_u32(ct, ATTR_TIMEOUT, udp_timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
nfct_set_attr_u8(ct, ATTR_L4PROTO, rule->protocol);
|
||||
nfct_set_attr_u32(ct, ATTR_TIMEOUT, tcp_timeout);
|
||||
}
|
||||
|
||||
if(rule->dst_nat == false)
|
||||
{
|
||||
nfct_set_attr_u32(ct, ATTR_IPV4_SRC, htonl(rule->private_ip));
|
||||
nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(rule->private_port));
|
||||
|
||||
nfct_set_attr_u32(ct, ATTR_IPV4_DST, htonl(rule->target_ip));
|
||||
nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(rule->target_port));
|
||||
|
||||
IPACMDBG("dst nat is not set\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
nfct_set_attr_u32(ct, ATTR_IPV4_SRC, htonl(rule->target_ip));
|
||||
nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(rule->target_port));
|
||||
|
||||
nfct_set_attr_u32(ct, ATTR_IPV4_DST, htonl(pub_ip_addr));
|
||||
nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(rule->public_port));
|
||||
|
||||
IPACMDBG("dst nat is set\n");
|
||||
}
|
||||
|
||||
iptodot("Source IP:", nfct_get_attr_u32(ct, ATTR_IPV4_SRC));
|
||||
iptodot("Destination IP:", nfct_get_attr_u32(ct, ATTR_IPV4_DST));
|
||||
IPACMDBG("Source Port: %d, Destination Port: %d\n",
|
||||
nfct_get_attr_u16(ct, ATTR_PORT_SRC), nfct_get_attr_u16(ct, ATTR_PORT_DST));
|
||||
|
||||
IPACMDBG("updating %d connection with time: %d\n",
|
||||
rule->protocol, nfct_get_attr_u32(ct, ATTR_TIMEOUT));
|
||||
|
||||
ret = nfct_query(ct_hdl, NFCT_Q_UPDATE, ct);
|
||||
if(ret == -1)
|
||||
{
|
||||
IPACMERR("unable to update time stamp");
|
||||
DeleteEntry(rule);
|
||||
}
|
||||
else
|
||||
{
|
||||
rule->timestamp = new_ts;
|
||||
IPACMDBG("Updated time stamp successfully\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void NatApp::UpdateUDPTimeStamp()
|
||||
{
|
||||
int cnt;
|
||||
uint32_t ts;
|
||||
bool read_to = false;
|
||||
|
||||
for(cnt = 0; cnt < max_entries; cnt++)
|
||||
{
|
||||
ts = 0;
|
||||
if(cache[cnt].enabled == true &&
|
||||
(cache[cnt].private_ip != cache[cnt].public_ip))
|
||||
{
|
||||
IPACMDBG("\n");
|
||||
if(ipa_nat_query_timestamp(nat_table_hdl, cache[cnt].rule_hdl, &ts) < 0)
|
||||
{
|
||||
IPACMERR("unable to retrieve timeout for rule hanle: %d\n", cache[cnt].rule_hdl);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(cache[cnt].timestamp == ts)
|
||||
{
|
||||
IPACMDBG("No Change in Time Stamp: cahce:%d, ipahw:%d\n",
|
||||
cache[cnt].timestamp, ts);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (read_to == false) {
|
||||
read_to = true;
|
||||
Read_TcpUdp_Timeout();
|
||||
}
|
||||
|
||||
UpdateCTUdpTs(&cache[cnt], ts);
|
||||
} /* end of outer if */
|
||||
|
||||
} /* end of for loop */
|
||||
|
||||
}
|
||||
|
||||
bool NatApp::isAlgPort(uint8_t proto, uint16_t port)
|
||||
{
|
||||
int cnt;
|
||||
for(cnt = 0; cnt < nALGPort; cnt++)
|
||||
{
|
||||
if(proto == pALGPorts[cnt].protocol &&
|
||||
port == pALGPorts[cnt].port)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NatApp::isPwrSaveIf(uint32_t ip_addr)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
|
||||
{
|
||||
if(0 != PwrSaveIfs[cnt] &&
|
||||
ip_addr == PwrSaveIfs[cnt])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int NatApp::UpdatePwrSaveIf(uint32_t client_lan_ip)
|
||||
{
|
||||
int cnt;
|
||||
IPACMDBG_H("Received IP address: 0x%x\n", client_lan_ip);
|
||||
|
||||
if(client_lan_ip == INVALID_IP_ADDR)
|
||||
{
|
||||
IPACMERR("Invalid ip address received\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check for duplicate events */
|
||||
for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
|
||||
{
|
||||
if(PwrSaveIfs[cnt] == client_lan_ip)
|
||||
{
|
||||
IPACMDBG("The client 0x%x is already in power save\n", client_lan_ip);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
|
||||
{
|
||||
if(PwrSaveIfs[cnt] == 0)
|
||||
{
|
||||
PwrSaveIfs[cnt] = client_lan_ip;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(cnt = 0; cnt < max_entries; cnt++)
|
||||
{
|
||||
if(cache[cnt].private_ip == client_lan_ip &&
|
||||
cache[cnt].enabled == true)
|
||||
{
|
||||
if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
|
||||
{
|
||||
IPACMERR("unable to delete the rule\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
cache[cnt].enabled = false;
|
||||
cache[cnt].rule_hdl = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NatApp::ResetPwrSaveIf(uint32_t client_lan_ip)
|
||||
{
|
||||
int cnt;
|
||||
ipa_nat_ipv4_rule nat_rule;
|
||||
|
||||
IPACMDBG_H("Received ip address: 0x%x\n", client_lan_ip);
|
||||
|
||||
if(client_lan_ip == INVALID_IP_ADDR)
|
||||
{
|
||||
IPACMERR("Invalid ip address received\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
|
||||
{
|
||||
if(PwrSaveIfs[cnt] == client_lan_ip)
|
||||
{
|
||||
PwrSaveIfs[cnt] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(cnt = 0; cnt < max_entries; cnt++)
|
||||
{
|
||||
IPACMDBG("cache (%d): enable %d, ip 0x%x\n", cnt, cache[cnt].enabled, cache[cnt].private_ip);
|
||||
|
||||
if(cache[cnt].private_ip == client_lan_ip &&
|
||||
cache[cnt].enabled == false)
|
||||
{
|
||||
memset(&nat_rule, 0 , sizeof(nat_rule));
|
||||
nat_rule.private_ip = cache[cnt].private_ip;
|
||||
nat_rule.target_ip = cache[cnt].target_ip;
|
||||
nat_rule.target_port = cache[cnt].target_port;
|
||||
nat_rule.private_port = cache[cnt].private_port;
|
||||
nat_rule.public_port = cache[cnt].public_port;
|
||||
nat_rule.protocol = cache[cnt].protocol;
|
||||
|
||||
if(ipa_nat_add_ipv4_rule(nat_table_hdl, &nat_rule, &cache[cnt].rule_hdl) < 0)
|
||||
{
|
||||
IPACMERR("unable to add the rule delete from cache\n");
|
||||
memset(&cache[cnt], 0, sizeof(cache[cnt]));
|
||||
curCnt--;
|
||||
continue;
|
||||
}
|
||||
cache[cnt].enabled = true;
|
||||
|
||||
IPACMDBG("On power reset added below rule successfully\n");
|
||||
iptodot("Private IP", nat_rule.private_ip);
|
||||
iptodot("Target IP", nat_rule.target_ip);
|
||||
IPACMDBG("Private Port:%d \t Target Port: %d\t", nat_rule.private_port, nat_rule.target_port);
|
||||
IPACMDBG("Public Port:%d\n", nat_rule.public_port);
|
||||
IPACMDBG("protocol: %d\n", nat_rule.protocol);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t NatApp::GetTableHdl(uint32_t in_ip_addr)
|
||||
{
|
||||
if(in_ip_addr == pub_ip_addr)
|
||||
{
|
||||
return nat_table_hdl;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void NatApp::AddTempEntry(const nat_table_entry *new_entry)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
IPACMDBG("Received below Temp Nat entry\n");
|
||||
iptodot("Private IP", new_entry->private_ip);
|
||||
iptodot("Target IP", new_entry->target_ip);
|
||||
IPACMDBG("Private Port: %d\t Target Port: %d\t", new_entry->private_port, new_entry->target_port);
|
||||
IPACMDBG("protocolcol: %d\n", new_entry->protocol);
|
||||
|
||||
if(isAlgPort(new_entry->protocol, new_entry->private_port) ||
|
||||
isAlgPort(new_entry->protocol, new_entry->target_port))
|
||||
{
|
||||
IPACMDBG("connection using ALG Port. Dont insert into nat cache\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ChkForDup(new_entry))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
|
||||
{
|
||||
if(temp[cnt].private_ip == new_entry->private_ip &&
|
||||
temp[cnt].target_ip == new_entry->target_ip &&
|
||||
temp[cnt].private_port == new_entry->private_port &&
|
||||
temp[cnt].target_port == new_entry->target_port &&
|
||||
temp[cnt].protocol == new_entry->protocol)
|
||||
{
|
||||
IPACMDBG("Received duplicate Temp entry\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
|
||||
{
|
||||
if(temp[cnt].private_ip == 0 &&
|
||||
temp[cnt].target_ip == 0)
|
||||
{
|
||||
memcpy(&temp[cnt], new_entry, sizeof(nat_table_entry));
|
||||
IPACMDBG("Added Temp Entry\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IPACMDBG("Unable to add temp entry, cache full\n");
|
||||
return;
|
||||
}
|
||||
|
||||
void NatApp::DeleteTempEntry(const nat_table_entry *entry)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
IPACMDBG("Received below nat entry\n");
|
||||
iptodot("Private IP", entry->private_ip);
|
||||
iptodot("Target IP", entry->target_ip);
|
||||
IPACMDBG("Private Port: %d\t Target Port: %d\n", entry->private_port, entry->target_port);
|
||||
IPACMDBG("protocol: %d\n", entry->protocol);
|
||||
|
||||
for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
|
||||
{
|
||||
if(temp[cnt].private_ip == entry->private_ip &&
|
||||
temp[cnt].target_ip == entry->target_ip &&
|
||||
temp[cnt].private_port == entry->private_port &&
|
||||
temp[cnt].target_port == entry->target_port &&
|
||||
temp[cnt].protocol == entry->protocol)
|
||||
{
|
||||
memset(&temp[cnt], 0, sizeof(nat_table_entry));
|
||||
IPACMDBG("Delete Temp Entry\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IPACMDBG("No Such Temp Entry exists\n");
|
||||
return;
|
||||
}
|
||||
|
||||
void NatApp::FlushTempEntries(uint32_t ip_addr, bool isAdd,
|
||||
bool isDummy)
|
||||
{
|
||||
int cnt;
|
||||
int ret;
|
||||
|
||||
IPACMDBG_H("Received below with isAdd:%d ", isAdd);
|
||||
iptodot("IP Address: ", ip_addr);
|
||||
|
||||
for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
|
||||
{
|
||||
if(temp[cnt].private_ip == ip_addr ||
|
||||
temp[cnt].target_ip == ip_addr)
|
||||
{
|
||||
if(isAdd)
|
||||
{
|
||||
if(temp[cnt].public_ip == pub_ip_addr)
|
||||
{
|
||||
if (isDummy) {
|
||||
/* To avoild DL expections for non IPA path */
|
||||
temp[cnt].private_ip = temp[cnt].public_ip;
|
||||
temp[cnt].private_port = temp[cnt].public_port;
|
||||
IPACMDBG("Flushing dummy temp rule");
|
||||
iptodot("Private IP", temp[cnt].private_ip);
|
||||
}
|
||||
|
||||
ret = AddEntry(&temp[cnt]);
|
||||
if(ret)
|
||||
{
|
||||
IPACMERR("unable to add temp entry: %d\n", ret);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
memset(&temp[cnt], 0, sizeof(nat_table_entry));
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int NatApp::DelEntriesOnClntDiscon(uint32_t ip_addr)
|
||||
{
|
||||
int cnt, tmp = 0;
|
||||
IPACMDBG_H("Received IP address: 0x%x\n", ip_addr);
|
||||
|
||||
if(ip_addr == INVALID_IP_ADDR)
|
||||
{
|
||||
IPACMERR("Invalid ip address received\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(cnt = 0; cnt < IPA_MAX_NUM_WIFI_CLIENTS; cnt++)
|
||||
{
|
||||
if(PwrSaveIfs[cnt] == ip_addr)
|
||||
{
|
||||
PwrSaveIfs[cnt] = 0;
|
||||
IPACMDBG("Remove %d power save entry\n", cnt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(cnt = 0; cnt < max_entries; cnt++)
|
||||
{
|
||||
if(cache[cnt].private_ip == ip_addr)
|
||||
{
|
||||
if(cache[cnt].enabled == true)
|
||||
{
|
||||
if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
|
||||
{
|
||||
IPACMERR("unable to delete the rule\n");
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG("won't delete the rule\n");
|
||||
cache[cnt].enabled = false;
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
IPACMDBG("won't delete the rule for entry %d, enabled %d\n",cnt, cache[cnt].enabled);
|
||||
}
|
||||
}
|
||||
|
||||
IPACMDBG("Deleted (but cached) %d entries\n", tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NatApp::DelEntriesOnSTAClntDiscon(uint32_t ip_addr)
|
||||
{
|
||||
int cnt, tmp = curCnt;
|
||||
IPACMDBG_H("Received IP address: 0x%x\n", ip_addr);
|
||||
|
||||
if(ip_addr == INVALID_IP_ADDR)
|
||||
{
|
||||
IPACMERR("Invalid ip address received\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
for(cnt = 0; cnt < max_entries; cnt++)
|
||||
{
|
||||
if(cache[cnt].target_ip == ip_addr)
|
||||
{
|
||||
if(cache[cnt].enabled == true)
|
||||
{
|
||||
if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
|
||||
{
|
||||
IPACMERR("unable to delete the rule\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&cache[cnt], 0, sizeof(cache[cnt]));
|
||||
curCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
IPACMDBG("Deleted %d entries\n", (tmp - curCnt));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NatApp::CacheEntry(const nat_table_entry *rule)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
if(rule->private_ip == 0 ||
|
||||
rule->target_ip == 0 ||
|
||||
rule->private_port == 0 ||
|
||||
rule->target_port == 0 ||
|
||||
rule->protocol == 0)
|
||||
{
|
||||
IPACMERR("Invalid Connection, ignoring it\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ChkForDup(rule))
|
||||
{
|
||||
for(cnt=0; cnt < max_entries; cnt++)
|
||||
{
|
||||
if(cache[cnt].private_ip == 0 &&
|
||||
cache[cnt].target_ip == 0 &&
|
||||
cache[cnt].private_port == 0 &&
|
||||
cache[cnt].target_port == 0 &&
|
||||
cache[cnt].protocol == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(max_entries == cnt)
|
||||
{
|
||||
IPACMERR("Error: Unable to add, reached maximum rules\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
cache[cnt].enabled = false;
|
||||
cache[cnt].rule_hdl = 0;
|
||||
cache[cnt].private_ip = rule->private_ip;
|
||||
cache[cnt].target_ip = rule->target_ip;
|
||||
cache[cnt].target_port = rule->target_port;
|
||||
cache[cnt].private_port = rule->private_port;
|
||||
cache[cnt].protocol = rule->protocol;
|
||||
cache[cnt].timestamp = 0;
|
||||
cache[cnt].public_port = rule->public_port;
|
||||
cache[cnt].public_ip = rule->public_ip;
|
||||
cache[cnt].dst_nat = rule->dst_nat;
|
||||
curCnt++;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMERR("Duplicate rule. Ignore it\n");
|
||||
return;
|
||||
}
|
||||
|
||||
IPACMDBG("Cached rule(%d) successfully\n", cnt);
|
||||
return;
|
||||
}
|
||||
|
||||
void NatApp::Read_TcpUdp_Timeout(void) {
|
||||
FILE *udp_fd = NULL, *tcp_fd = NULL;
|
||||
|
||||
/* Read UDP timeout value */
|
||||
udp_fd = fopen(IPACM_UDP_FULL_FILE_NAME, "r");
|
||||
if (udp_fd == NULL) {
|
||||
IPACMERR("unable to open %s\n", IPACM_UDP_FULL_FILE_NAME);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fscanf(udp_fd, "%d", &udp_timeout) != 1) {
|
||||
IPACMERR("Error reading udp timeout\n");
|
||||
}
|
||||
IPACMDBG_H("udp timeout value: %d\n", udp_timeout);
|
||||
|
||||
|
||||
/* Read TCP timeout value */
|
||||
tcp_fd = fopen(IPACM_TCP_FULL_FILE_NAME, "r");
|
||||
if (tcp_fd == NULL) {
|
||||
IPACMERR("unable to open %s\n", IPACM_TCP_FULL_FILE_NAME);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
if (fscanf(tcp_fd, "%d", &tcp_timeout) != 1) {
|
||||
IPACMERR("Error reading tcp timeout\n");
|
||||
}
|
||||
IPACMDBG_H("tcp timeout value: %d\n", tcp_timeout);
|
||||
|
||||
fail:
|
||||
if (udp_fd) {
|
||||
fclose(udp_fd);
|
||||
}
|
||||
if (tcp_fd) {
|
||||
fclose(tcp_fd);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
214
data-ipa-cfg-mgr/ipacm/src/IPACM_EvtDispatcher.cpp
Normal file
214
data-ipa-cfg-mgr/ipacm/src/IPACM_EvtDispatcher.cpp
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
Copyright (c) 2013-2016, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.
|
||||
*/
|
||||
/*!
|
||||
@file
|
||||
IPACM_EvtDispatcher.cpp
|
||||
|
||||
@brief
|
||||
This file implements the IPAM event dispatcher functionality
|
||||
|
||||
@Author
|
||||
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <IPACM_EvtDispatcher.h>
|
||||
#include <IPACM_Neighbor.h>
|
||||
#include "IPACM_CmdQueue.h"
|
||||
#include "IPACM_Defs.h"
|
||||
|
||||
|
||||
extern pthread_mutex_t mutex;
|
||||
extern pthread_cond_t cond_var;
|
||||
|
||||
cmd_evts *IPACM_EvtDispatcher::head = NULL;
|
||||
extern uint32_t ipacm_event_stats[IPACM_EVENT_MAX];
|
||||
|
||||
int IPACM_EvtDispatcher::PostEvt
|
||||
(
|
||||
ipacm_cmd_q_data *data
|
||||
)
|
||||
{
|
||||
Message *item = NULL;
|
||||
MessageQueue *MsgQueue = NULL;
|
||||
|
||||
if(data->event < IPA_EXTERNAL_EVENT_MAX)
|
||||
{
|
||||
IPACMDBG("Insert event into external queue.\n");
|
||||
MsgQueue = MessageQueue::getInstanceExternal();
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG("Insert event into internal queue.\n");
|
||||
MsgQueue = MessageQueue::getInstanceInternal();
|
||||
}
|
||||
if(MsgQueue == NULL)
|
||||
{
|
||||
IPACMERR("unable to retrieve MsgQueue instance\n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
item = new Message();
|
||||
if(item == NULL)
|
||||
{
|
||||
IPACMERR("unable to create new message item\n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
item->evt.callback_ptr = IPACM_EvtDispatcher::ProcessEvt;
|
||||
memcpy(&item->evt.data, data, sizeof(ipacm_cmd_q_data));
|
||||
|
||||
if(pthread_mutex_lock(&mutex) != 0)
|
||||
{
|
||||
IPACMERR("unable to lock the mutex\n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
IPACMDBG("Enqueing item\n");
|
||||
MsgQueue->enqueue(item);
|
||||
IPACMDBG("Enqueued item %p\n", item);
|
||||
|
||||
if(pthread_cond_signal(&cond_var) != 0)
|
||||
{
|
||||
IPACMDBG("unable to lock the mutex\n");
|
||||
/* Release the mutex before you return failure */
|
||||
if(pthread_mutex_unlock(&mutex) != 0)
|
||||
{
|
||||
IPACMERR("unable to unlock the mutex\n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
if(pthread_mutex_unlock(&mutex) != 0)
|
||||
{
|
||||
IPACMERR("unable to unlock the mutex\n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
void IPACM_EvtDispatcher::ProcessEvt(ipacm_cmd_q_data *data)
|
||||
{
|
||||
|
||||
cmd_evts *tmp = head, tmp1;
|
||||
|
||||
if(head == NULL)
|
||||
{
|
||||
IPACMDBG("Queue is empty\n");
|
||||
}
|
||||
|
||||
while(tmp != NULL)
|
||||
{
|
||||
memcpy(&tmp1, tmp, sizeof(tmp1));
|
||||
if(data->event == tmp1.event)
|
||||
{
|
||||
ipacm_event_stats[data->event]++;
|
||||
tmp1.obj->event_callback(data->event, data->evt_data);
|
||||
IPACMDBG(" Find matched registered events\n");
|
||||
}
|
||||
tmp = tmp1.next;
|
||||
}
|
||||
|
||||
IPACMDBG(" Finished process events\n");
|
||||
|
||||
if(data->evt_data != NULL)
|
||||
{
|
||||
IPACMDBG("free the event:%d data: %p\n", data->event, data->evt_data);
|
||||
free(data->evt_data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int IPACM_EvtDispatcher::registr(ipa_cm_event_id event, IPACM_Listener *obj)
|
||||
{
|
||||
cmd_evts *tmp = head,*nw;
|
||||
|
||||
nw = (cmd_evts *)malloc(sizeof(cmd_evts));
|
||||
if(nw != NULL)
|
||||
{
|
||||
nw->event = event;
|
||||
nw->obj = obj;
|
||||
nw->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
if(head == NULL)
|
||||
{
|
||||
head = nw;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(tmp->next)
|
||||
{
|
||||
tmp = tmp->next;
|
||||
}
|
||||
tmp->next = nw;
|
||||
}
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int IPACM_EvtDispatcher::deregistr(IPACM_Listener *param)
|
||||
{
|
||||
cmd_evts *tmp = head,*tmp1,*prev = head;
|
||||
|
||||
while(tmp != NULL)
|
||||
{
|
||||
if(tmp->obj == param)
|
||||
{
|
||||
tmp1 = tmp;
|
||||
if(tmp == head)
|
||||
{
|
||||
head = head->next;
|
||||
}
|
||||
else if(tmp->next == NULL)
|
||||
{
|
||||
prev->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev->next = tmp->next;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
free(tmp1);
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
536
data-ipa-cfg-mgr/ipacm/src/IPACM_Filtering.cpp
Normal file
536
data-ipa-cfg-mgr/ipacm/src/IPACM_Filtering.cpp
Normal file
@@ -0,0 +1,536 @@
|
||||
/*
|
||||
Copyright (c) 2013-2016, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.
|
||||
*/
|
||||
/*!
|
||||
@file
|
||||
IPACM_Filtering.cpp
|
||||
|
||||
@brief
|
||||
This file implements the IPACM filtering functionality.
|
||||
|
||||
@Author
|
||||
Skylar Chang
|
||||
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "IPACM_Filtering.h"
|
||||
#include <IPACM_Log.h>
|
||||
#include "IPACM_Defs.h"
|
||||
|
||||
|
||||
const char *IPACM_Filtering::DEVICE_NAME = "/dev/ipa";
|
||||
|
||||
IPACM_Filtering::IPACM_Filtering()
|
||||
{
|
||||
fd = open(DEVICE_NAME, O_RDWR);
|
||||
if (fd < 0)
|
||||
{
|
||||
IPACMERR("Failed opening %s.\n", DEVICE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
IPACM_Filtering::~IPACM_Filtering()
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
bool IPACM_Filtering::DeviceNodeIsOpened()
|
||||
{
|
||||
return fd;
|
||||
}
|
||||
|
||||
bool IPACM_Filtering::AddFilteringRule(struct ipa_ioc_add_flt_rule const *ruleTable)
|
||||
{
|
||||
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 and global value: %d\n", ruleTable->ep, ruleTable->global);
|
||||
IPACMDBG("commit value: %d\n", ruleTable->commit);
|
||||
for (int cnt=0; cnt<ruleTable->num_rules; cnt++)
|
||||
{
|
||||
IPACMDBG("Filter rule:%d attrib mask: 0x%x\n", cnt,
|
||||
ruleTable->rules[cnt].rule.attrib.attrib_mask);
|
||||
}
|
||||
|
||||
retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE, ruleTable);
|
||||
if (retval != 0)
|
||||
{
|
||||
IPACMERR("Failed adding Filtering rule %p\n", ruleTable);
|
||||
PERROR("unable to add filter rule:");
|
||||
|
||||
for (int cnt = 0; cnt < ruleTable->num_rules; cnt++)
|
||||
{
|
||||
if (ruleTable->rules[cnt].status != 0)
|
||||
{
|
||||
IPACMERR("Adding Filter rule:%d failed with status:%d\n",
|
||||
cnt, ruleTable->rules[cnt].status);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int cnt = 0; cnt<ruleTable->num_rules; cnt++)
|
||||
{
|
||||
if(ruleTable->rules[cnt].status != 0)
|
||||
{
|
||||
IPACMERR("Adding Filter rule:%d failed with status:%d\n",
|
||||
cnt, ruleTable->rules[cnt].status);
|
||||
}
|
||||
}
|
||||
|
||||
IPACMDBG("Added Filtering rule %p\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);
|
||||
|
||||
retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE_AFTER, ruleTable);
|
||||
|
||||
for (int cnt = 0; cnt<ruleTable->num_rules; cnt++)
|
||||
{
|
||||
if(ruleTable->rules[cnt].status != 0)
|
||||
{
|
||||
IPACMERR("Adding Filter rule:%d failed with status:%d\n",
|
||||
cnt, ruleTable->rules[cnt].status);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != 0)
|
||||
{
|
||||
IPACMERR("Failed adding Filtering rule %p\n", ruleTable);
|
||||
return false;
|
||||
}
|
||||
IPACMDBG("Added Filtering rule %p\n", ruleTable);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPACM_Filtering::DeleteFilteringRule(struct ipa_ioc_del_flt_rule *ruleTable)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
retval = ioctl(fd, IPA_IOC_DEL_FLT_RULE, ruleTable);
|
||||
if (retval != 0)
|
||||
{
|
||||
IPACMERR("Failed deleting Filtering rule %p\n", ruleTable);
|
||||
return false;
|
||||
}
|
||||
|
||||
IPACMDBG("Deleted Filtering rule %p\n", ruleTable);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPACM_Filtering::Commit(enum ipa_ip_type ip)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
retval = ioctl(fd, IPA_IOC_COMMIT_FLT, ip);
|
||||
if (retval != 0)
|
||||
{
|
||||
IPACMERR("failed committing Filtering rules.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
IPACMDBG("Committed Filtering rules to IPA HW.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPACM_Filtering::Reset(enum ipa_ip_type ip)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
retval = ioctl(fd, IPA_IOC_RESET_FLT, ip);
|
||||
retval |= ioctl(fd, IPA_IOC_COMMIT_FLT, ip);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("failed resetting Filtering block.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
IPACMDBG("Reset command issued to IPA Filtering block.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPACM_Filtering::DeleteFilteringHdls
|
||||
(
|
||||
uint32_t *flt_rule_hdls,
|
||||
ipa_ip_type ip,
|
||||
uint8_t num_rules
|
||||
)
|
||||
{
|
||||
struct ipa_ioc_del_flt_rule *flt_rule;
|
||||
bool res = true;
|
||||
int len = 0, cnt = 0;
|
||||
const uint8_t UNIT_RULES = 1;
|
||||
|
||||
len = (sizeof(struct ipa_ioc_del_flt_rule)) + (UNIT_RULES * sizeof(struct ipa_flt_rule_del));
|
||||
flt_rule = (struct ipa_ioc_del_flt_rule *)malloc(len);
|
||||
if (flt_rule == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for del filter rule\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (cnt = 0; cnt < num_rules; cnt++)
|
||||
{
|
||||
memset(flt_rule, 0, len);
|
||||
flt_rule->commit = 1;
|
||||
flt_rule->num_hdls = UNIT_RULES;
|
||||
flt_rule->ip = ip;
|
||||
|
||||
if (flt_rule_hdls[cnt] == 0)
|
||||
{
|
||||
IPACMERR("invalid filter handle passed, ignoring it: %d\n", cnt)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
flt_rule->hdl[0].status = -1;
|
||||
flt_rule->hdl[0].hdl = flt_rule_hdls[cnt];
|
||||
IPACMDBG("Deleting filter hdl:(0x%x) with ip type: %d\n", flt_rule_hdls[cnt], ip);
|
||||
|
||||
if (DeleteFilteringRule(flt_rule) == false)
|
||||
{
|
||||
PERROR("Filter rule deletion failed!\n");
|
||||
res = false;
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (flt_rule->hdl[0].status != 0)
|
||||
{
|
||||
IPACMERR("Filter rule hdl 0x%x deletion failed with error:%d\n",
|
||||
flt_rule->hdl[0].hdl, flt_rule->hdl[0].status);
|
||||
res = false;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
free(flt_rule);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool IPACM_Filtering::AddWanDLFilteringRule(struct ipa_ioc_add_flt_rule const *rule_table_v4, struct ipa_ioc_add_flt_rule const * rule_table_v6, uint8_t mux_id)
|
||||
{
|
||||
int ret = 0, cnt, num_rules = 0, pos = 0;
|
||||
ipa_install_fltr_rule_req_msg_v01 qmi_rule_msg;
|
||||
#ifdef FEATURE_IPA_V3
|
||||
ipa_install_fltr_rule_req_ex_msg_v01 qmi_rule_ex_msg;
|
||||
#endif
|
||||
|
||||
int 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;
|
||||
}
|
||||
|
||||
if(rule_table_v4 != NULL)
|
||||
{
|
||||
num_rules += rule_table_v4->num_rules;
|
||||
IPACMDBG_H("Get %d WAN DL IPv4 filtering rules.\n", rule_table_v4->num_rules);
|
||||
}
|
||||
if(rule_table_v6 != NULL)
|
||||
{
|
||||
num_rules += rule_table_v6->num_rules;
|
||||
IPACMDBG_H("Get %d WAN DL IPv6 filtering rules.\n", rule_table_v6->num_rules);
|
||||
}
|
||||
|
||||
/* if it is not IPA v3, use old QMI format */
|
||||
#ifndef FEATURE_IPA_V3
|
||||
if(num_rules > QMI_IPA_MAX_FILTERS_V01)
|
||||
{
|
||||
IPACMERR("The number of filtering rules exceed limit.\n");
|
||||
close(fd_wwan_ioctl);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&qmi_rule_msg, 0, sizeof(qmi_rule_msg));
|
||||
|
||||
if (num_rules > 0)
|
||||
{
|
||||
qmi_rule_msg.filter_spec_list_valid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
qmi_rule_msg.filter_spec_list_valid = false;
|
||||
}
|
||||
|
||||
qmi_rule_msg.filter_spec_list_len = num_rules;
|
||||
qmi_rule_msg.source_pipe_index_valid = 0;
|
||||
|
||||
IPACMDBG_H("Get %d WAN DL filtering rules in total.\n", num_rules);
|
||||
|
||||
if(rule_table_v4 != NULL)
|
||||
{
|
||||
for(cnt = rule_table_v4->num_rules - 1; cnt >= 0; cnt--)
|
||||
{
|
||||
if (pos < QMI_IPA_MAX_FILTERS_V01)
|
||||
{
|
||||
qmi_rule_msg.filter_spec_list[pos].filter_spec_identifier = pos;
|
||||
qmi_rule_msg.filter_spec_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
|
||||
qmi_rule_msg.filter_spec_list[pos].filter_action = GetQmiFilterAction(rule_table_v4->rules[cnt].rule.action);
|
||||
qmi_rule_msg.filter_spec_list[pos].is_routing_table_index_valid = 1;
|
||||
qmi_rule_msg.filter_spec_list[pos].route_table_index = rule_table_v4->rules[cnt].rule.rt_tbl_idx;
|
||||
qmi_rule_msg.filter_spec_list[pos].is_mux_id_valid = 1;
|
||||
qmi_rule_msg.filter_spec_list[pos].mux_id = mux_id;
|
||||
memcpy(&qmi_rule_msg.filter_spec_list[pos].filter_rule,
|
||||
&rule_table_v4->rules[cnt].rule.eq_attrib,
|
||||
sizeof(struct ipa_filter_rule_type_v01));
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(rule_table_v6 != NULL)
|
||||
{
|
||||
for(cnt = rule_table_v6->num_rules - 1; cnt >= 0; cnt--)
|
||||
{
|
||||
if (pos < QMI_IPA_MAX_FILTERS_V01)
|
||||
{
|
||||
qmi_rule_msg.filter_spec_list[pos].filter_spec_identifier = pos;
|
||||
qmi_rule_msg.filter_spec_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
|
||||
qmi_rule_msg.filter_spec_list[pos].filter_action = GetQmiFilterAction(rule_table_v6->rules[cnt].rule.action);
|
||||
qmi_rule_msg.filter_spec_list[pos].is_routing_table_index_valid = 1;
|
||||
qmi_rule_msg.filter_spec_list[pos].route_table_index = rule_table_v6->rules[cnt].rule.rt_tbl_idx;
|
||||
qmi_rule_msg.filter_spec_list[pos].is_mux_id_valid = 1;
|
||||
qmi_rule_msg.filter_spec_list[pos].mux_id = mux_id;
|
||||
memcpy(&qmi_rule_msg.filter_spec_list[pos].filter_rule,
|
||||
&rule_table_v6->rules[cnt].rule.eq_attrib,
|
||||
sizeof(struct ipa_filter_rule_type_v01));
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE, &qmi_rule_msg);
|
||||
if (ret != 0)
|
||||
{
|
||||
IPACMERR("Failed adding Filtering rule %p with ret %d\n ", &qmi_rule_msg, ret);
|
||||
close(fd_wwan_ioctl);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* if it is IPA v3, use new QMI format */
|
||||
#else
|
||||
if(num_rules > QMI_IPA_MAX_FILTERS_EX_V01)
|
||||
{
|
||||
IPACMERR("The number of filtering rules exceed limit.\n");
|
||||
close(fd_wwan_ioctl);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&qmi_rule_ex_msg, 0, sizeof(qmi_rule_ex_msg));
|
||||
|
||||
if (num_rules > 0)
|
||||
{
|
||||
qmi_rule_ex_msg.filter_spec_ex_list_valid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
qmi_rule_ex_msg.filter_spec_ex_list_valid = false;
|
||||
}
|
||||
qmi_rule_ex_msg.filter_spec_ex_list_len = num_rules;
|
||||
qmi_rule_ex_msg.source_pipe_index_valid = 0;
|
||||
|
||||
IPACMDBG_H("Get %d WAN DL filtering rules in total.\n", num_rules);
|
||||
|
||||
if(rule_table_v4 != NULL)
|
||||
{
|
||||
for(cnt = rule_table_v4->num_rules - 1; cnt >= 0; cnt--)
|
||||
{
|
||||
if (pos < QMI_IPA_MAX_FILTERS_EX_V01)
|
||||
{
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_action = GetQmiFilterAction(rule_table_v4->rules[cnt].rule.action);
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_routing_table_index_valid = 1;
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].route_table_index = rule_table_v4->rules[cnt].rule.rt_tbl_idx;
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_mux_id_valid = 1;
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].mux_id = mux_id;
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].rule_id = rule_table_v4->rules[cnt].rule.rule_id;
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_rule_hashable = rule_table_v4->rules[cnt].rule.hashable;
|
||||
memcpy(&qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_rule,
|
||||
&rule_table_v4->rules[cnt].rule.eq_attrib,
|
||||
sizeof(struct ipa_filter_rule_type_v01));
|
||||
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_EX_V01, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(rule_table_v6 != NULL)
|
||||
{
|
||||
for(cnt = rule_table_v6->num_rules - 1; cnt >= 0; cnt--)
|
||||
{
|
||||
if (pos < QMI_IPA_MAX_FILTERS_EX_V01)
|
||||
{
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_action = GetQmiFilterAction(rule_table_v6->rules[cnt].rule.action);
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_routing_table_index_valid = 1;
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].route_table_index = rule_table_v6->rules[cnt].rule.rt_tbl_idx;
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_mux_id_valid = 1;
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].mux_id = mux_id;
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].rule_id = rule_table_v6->rules[cnt].rule.rule_id;
|
||||
qmi_rule_ex_msg.filter_spec_ex_list[pos].is_rule_hashable = rule_table_v6->rules[cnt].rule.hashable;
|
||||
memcpy(&qmi_rule_ex_msg.filter_spec_ex_list[pos].filter_rule,
|
||||
&rule_table_v6->rules[cnt].rule.eq_attrib,
|
||||
sizeof(struct ipa_filter_rule_type_v01));
|
||||
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_EX_V01, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_FLT_RULE_EX, &qmi_rule_ex_msg);
|
||||
if (ret != 0)
|
||||
{
|
||||
IPACMERR("Failed adding Filtering rule %p with ret %d\n ", &qmi_rule_ex_msg, ret);
|
||||
close(fd_wwan_ioctl);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
close(fd_wwan_ioctl);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPACM_Filtering::SendFilteringRuleIndex(struct ipa_fltr_installed_notif_req_msg_v01* table)
|
||||
{
|
||||
int ret = 0;
|
||||
int 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;
|
||||
}
|
||||
|
||||
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);
|
||||
close(fd_wwan_ioctl);
|
||||
return false;
|
||||
}
|
||||
|
||||
IPACMDBG("Added Filtering rule index %p\n", table);
|
||||
close(fd_wwan_ioctl);
|
||||
return true;
|
||||
}
|
||||
|
||||
ipa_filter_action_enum_v01 IPACM_Filtering::GetQmiFilterAction(ipa_flt_action action)
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case IPA_PASS_TO_ROUTING:
|
||||
return QMI_IPA_FILTER_ACTION_ROUTING_V01;
|
||||
|
||||
case IPA_PASS_TO_SRC_NAT:
|
||||
return QMI_IPA_FILTER_ACTION_SRC_NAT_V01;
|
||||
|
||||
case IPA_PASS_TO_DST_NAT:
|
||||
return QMI_IPA_FILTER_ACTION_DST_NAT_V01;
|
||||
|
||||
case IPA_PASS_TO_EXCEPTION:
|
||||
return QMI_IPA_FILTER_ACTION_EXCEPTION_V01;
|
||||
|
||||
default:
|
||||
return IPA_FILTER_ACTION_ENUM_MAX_ENUM_VAL_V01;
|
||||
}
|
||||
}
|
||||
|
||||
bool IPACM_Filtering::ModifyFilteringRule(struct ipa_ioc_mdfy_flt_rule* ruleTable)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
IPACMDBG("Printing filtering add attributes\n");
|
||||
IPACMDBG("IP type: %d Number of rules: %d commit value: %d\n", ruleTable->ip, ruleTable->num_rules, ruleTable->commit);
|
||||
|
||||
for (i=0; i<ruleTable->num_rules; i++)
|
||||
{
|
||||
IPACMDBG("Filter rule:%d attrib mask: 0x%x\n", i, ruleTable->rules[i].rule.attrib.attrib_mask);
|
||||
}
|
||||
|
||||
ret = ioctl(fd, IPA_IOC_MDFY_FLT_RULE, ruleTable);
|
||||
if (ret != 0)
|
||||
{
|
||||
IPACMERR("Failed modifying filtering rule %p\n", ruleTable);
|
||||
|
||||
for (i = 0; i < ruleTable->num_rules; i++)
|
||||
{
|
||||
if (ruleTable->rules[i].status != 0)
|
||||
{
|
||||
IPACMERR("Modifying filter rule %d failed\n", i);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
IPACMDBG("Modified filtering rule %p\n", ruleTable);
|
||||
return true;
|
||||
}
|
||||
|
||||
236
data-ipa-cfg-mgr/ipacm/src/IPACM_Header.cpp
Normal file
236
data-ipa-cfg-mgr/ipacm/src/IPACM_Header.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
Copyright (c) 2013, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "IPACM_Header.h"
|
||||
#include "IPACM_Log.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//All interaction through the driver are made through this inode.
|
||||
static const char *DEVICE_NAME = "/dev/ipa";
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IPACM_Header::IPACM_Header()
|
||||
{
|
||||
m_fd = open(DEVICE_NAME, O_RDWR);
|
||||
if (-1 == m_fd)
|
||||
{
|
||||
IPACMERR("Failed to open %s in IPACM_Header test application constructor.\n", DEVICE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IPACM_Header::~IPACM_Header()
|
||||
{
|
||||
if (-1 != m_fd)
|
||||
{
|
||||
close(m_fd);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool IPACM_Header::DeviceNodeIsOpened()
|
||||
{
|
||||
return (-1 != m_fd);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool IPACM_Header::AddHeader(struct ipa_ioc_add_hdr *pHeaderTableToAdd)
|
||||
{
|
||||
int nRetVal = 0;
|
||||
//call the Driver ioctl in order to add header
|
||||
nRetVal = ioctl(m_fd, IPA_IOC_ADD_HDR, pHeaderTableToAdd);
|
||||
IPACMDBG("return value: %d\n", nRetVal);
|
||||
return (-1 != nRetVal);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool IPACM_Header::DeleteHeader(struct ipa_ioc_del_hdr *pHeaderTableToDelete)
|
||||
{
|
||||
int nRetVal = 0;
|
||||
//call the Driver ioctl in order to remove header
|
||||
nRetVal = ioctl(m_fd, IPA_IOC_DEL_HDR, pHeaderTableToDelete);
|
||||
IPACMDBG("return value: %d\n", nRetVal);
|
||||
return (-1 != nRetVal);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool IPACM_Header::Commit()
|
||||
{
|
||||
int nRetVal = 0;
|
||||
nRetVal = ioctl(m_fd, IPA_IOC_COMMIT_HDR);
|
||||
IPACMDBG("return value: %d\n", nRetVal);
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool IPACM_Header::Reset()
|
||||
{
|
||||
int nRetVal = 0;
|
||||
|
||||
nRetVal = ioctl(m_fd, IPA_IOC_RESET_HDR);
|
||||
nRetVal |= ioctl(m_fd, IPA_IOC_COMMIT_HDR);
|
||||
IPACMDBG("return value: %d\n", nRetVal);
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool IPACM_Header::GetHeaderHandle(struct ipa_ioc_get_hdr *pHeaderStruct)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (!DeviceNodeIsOpened()) return false;
|
||||
|
||||
retval = ioctl(m_fd, IPA_IOC_GET_HDR, pHeaderStruct);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("IPA_IOC_GET_HDR ioctl failed, routingTable =0x%p, retval=0x%x.\n", pHeaderStruct, retval);
|
||||
return false;
|
||||
}
|
||||
|
||||
IPACMDBG("IPA_IOC_GET_HDR ioctl issued to IPA header insertion block.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool IPACM_Header::CopyHeader(struct ipa_ioc_copy_hdr *pCopyHeaderStruct)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (!DeviceNodeIsOpened()) return false;
|
||||
|
||||
retval = ioctl(m_fd, IPA_IOC_COPY_HDR, pCopyHeaderStruct);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("IPA_IOC_COPY_HDR ioctl failed, retval=0x%x.\n", retval);
|
||||
return false;
|
||||
}
|
||||
|
||||
IPACMDBG("IPA_IOC_COPY_HDR ioctl issued to IPA header insertion block.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPACM_Header::DeleteHeaderHdl(uint32_t hdr_hdl)
|
||||
{
|
||||
const uint8_t NUM_HDLS = 1;
|
||||
struct ipa_ioc_del_hdr *pHeaderDescriptor = NULL;
|
||||
struct ipa_hdr_del *hd_rule_entry;
|
||||
int len = 0;
|
||||
bool res = true;
|
||||
|
||||
if (hdr_hdl == 0)
|
||||
{
|
||||
IPACMERR("Invalid header handle passed. Ignoring it\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
len = (sizeof(struct ipa_ioc_del_hdr)) + (NUM_HDLS * sizeof(struct ipa_hdr_del));
|
||||
pHeaderDescriptor = (struct ipa_ioc_del_hdr *)malloc(len);
|
||||
if (pHeaderDescriptor == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate memory for del header\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(pHeaderDescriptor, 0, len);
|
||||
pHeaderDescriptor->commit = true;
|
||||
pHeaderDescriptor->num_hdls = NUM_HDLS;
|
||||
hd_rule_entry = &pHeaderDescriptor->hdl[0];
|
||||
|
||||
hd_rule_entry->hdl = hdr_hdl;
|
||||
hd_rule_entry->status = -1;
|
||||
|
||||
IPACMDBG("Deleting Header hdl:(%x)\n", hd_rule_entry->hdl);
|
||||
if ((false == DeleteHeader(pHeaderDescriptor)) ||
|
||||
(hd_rule_entry->status))
|
||||
{
|
||||
IPACMERR("Header hdl:(%x) deletion failed! status: %d\n", hd_rule_entry->hdl,hd_rule_entry->status);
|
||||
res = false;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
IPACMDBG_H("Deleted Header hdl:(%x) successfully\n", hd_rule_entry->hdl);
|
||||
|
||||
fail:
|
||||
free(pHeaderDescriptor);
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
bool IPACM_Header::AddHeaderProcCtx(struct ipa_ioc_add_hdr_proc_ctx* pHeader)
|
||||
{
|
||||
int ret = 0;
|
||||
//call the Driver ioctl to add header processing context
|
||||
ret = ioctl(m_fd, IPA_IOC_ADD_HDR_PROC_CTX, pHeader);
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
bool IPACM_Header::DeleteHeaderProcCtx(uint32_t hdl)
|
||||
{
|
||||
int len, ret;
|
||||
struct ipa_ioc_del_hdr_proc_ctx* pHeaderTable = NULL;
|
||||
|
||||
len = sizeof(struct ipa_ioc_del_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_del);
|
||||
pHeaderTable = (struct ipa_ioc_del_hdr_proc_ctx*)malloc(len);
|
||||
if(pHeaderTable == NULL)
|
||||
{
|
||||
IPACMERR("Failed to allocate buffer.\n");
|
||||
return false;
|
||||
}
|
||||
memset(pHeaderTable, 0, len);
|
||||
|
||||
pHeaderTable->commit = 1;
|
||||
pHeaderTable->num_hdls = 1;
|
||||
pHeaderTable->hdl[0].hdl = hdl;
|
||||
|
||||
ret = ioctl(m_fd, IPA_IOC_DEL_HDR_PROC_CTX, pHeaderTable);
|
||||
if(ret != 0)
|
||||
{
|
||||
IPACMERR("Failed to delete hdr proc ctx: return value %d, status %d\n",
|
||||
ret, pHeaderTable->hdl[0].status);
|
||||
}
|
||||
free(pHeaderTable);
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
995
data-ipa-cfg-mgr/ipacm/src/IPACM_Iface.cpp
Normal file
995
data-ipa-cfg-mgr/ipacm/src/IPACM_Iface.cpp
Normal file
@@ -0,0 +1,995 @@
|
||||
/*
|
||||
Copyright (c) 2013, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.Z
|
||||
*/
|
||||
/*!
|
||||
@file
|
||||
IPACM_Iface.cpp
|
||||
|
||||
@brief
|
||||
This file implements the basis Iface functionality.
|
||||
|
||||
@Author
|
||||
Skylar Chang
|
||||
|
||||
*/
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <IPACM_Netlink.h>
|
||||
#include <IPACM_Iface.h>
|
||||
#include <IPACM_Lan.h>
|
||||
#include <IPACM_Wan.h>
|
||||
#include <IPACM_Wlan.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <ifaddrs.h>
|
||||
}
|
||||
|
||||
|
||||
const char *IPACM_Iface::DEVICE_NAME = "/dev/ipa";
|
||||
IPACM_Routing IPACM_Iface::m_routing;
|
||||
IPACM_Filtering IPACM_Iface::m_filtering;
|
||||
IPACM_Header IPACM_Iface::m_header;
|
||||
|
||||
IPACM_Config *IPACM_Iface::ipacmcfg = IPACM_Config::GetInstance();
|
||||
|
||||
IPACM_Iface::IPACM_Iface(int iface_index)
|
||||
{
|
||||
ip_type = IPACM_IP_NULL; /* initially set invalid */
|
||||
num_dft_rt_v6 = 0;
|
||||
softwarerouting_act = false;
|
||||
ipa_if_num = iface_index;
|
||||
ipa_if_cate = IPACM_Iface::ipacmcfg->iface_table[iface_index].if_cat;
|
||||
|
||||
iface_query = NULL;
|
||||
tx_prop = NULL;
|
||||
rx_prop = NULL;
|
||||
|
||||
memcpy(dev_name,
|
||||
IPACM_Iface::ipacmcfg->iface_table[iface_index].iface_name,
|
||||
sizeof(IPACM_Iface::ipacmcfg->iface_table[iface_index].iface_name));
|
||||
|
||||
memset(dft_v4fl_rule_hdl, 0, sizeof(dft_v4fl_rule_hdl));
|
||||
memset(dft_v6fl_rule_hdl, 0, sizeof(dft_v6fl_rule_hdl));
|
||||
|
||||
memset(dft_rt_rule_hdl, 0, sizeof(dft_rt_rule_hdl));
|
||||
memset(software_routing_fl_rule_hdl, 0, sizeof(software_routing_fl_rule_hdl));
|
||||
memset(ipv6_addr, 0, sizeof(ipv6_addr));
|
||||
|
||||
query_iface_property();
|
||||
IPACMDBG_H(" create iface-index(%d) constructor\n", ipa_if_num);
|
||||
return;
|
||||
}
|
||||
|
||||
/* software routing enable */
|
||||
int IPACM_Iface::handle_software_routing_enable(void)
|
||||
{
|
||||
|
||||
int res = IPACM_SUCCESS;
|
||||
struct ipa_flt_rule_add flt_rule_entry;
|
||||
ipa_ioc_add_flt_rule *m_pFilteringTable;
|
||||
|
||||
IPACMDBG("\n");
|
||||
if (softwarerouting_act == true)
|
||||
{
|
||||
IPACMDBG("already setup software_routing rule for (%s)iface ip-family %d\n",
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ip_type);
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
if(rx_prop == NULL)
|
||||
{
|
||||
IPACMDBG("No rx properties registered for iface %s\n", dev_name);
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)
|
||||
calloc(1,
|
||||
sizeof(struct ipa_ioc_add_flt_rule) +
|
||||
1 * sizeof(struct ipa_flt_rule_add)
|
||||
);
|
||||
if (!m_pFilteringTable)
|
||||
{
|
||||
IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
m_pFilteringTable->commit = 1;
|
||||
m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
|
||||
m_pFilteringTable->global = false;
|
||||
m_pFilteringTable->num_rules = (uint8_t)1;
|
||||
|
||||
|
||||
/* Configuring Software-Routing Filtering Rule */
|
||||
memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
flt_rule_entry.at_rear = false;
|
||||
flt_rule_entry.flt_rule_hdl = -1;
|
||||
flt_rule_entry.status = -1;
|
||||
flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
|
||||
#ifdef FEATURE_IPA_V3
|
||||
flt_rule_entry.rule.hashable = true;
|
||||
#endif
|
||||
memcpy(&flt_rule_entry.rule.attrib,
|
||||
&rx_prop->rx[0].attrib,
|
||||
sizeof(flt_rule_entry.rule.attrib));
|
||||
|
||||
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
/* check iface is v4 or v6 or both*/
|
||||
// if (ip_type == IPA_IP_MAX)
|
||||
// {
|
||||
/* handle v4 */
|
||||
m_pFilteringTable->ip = IPA_IP_v4;
|
||||
if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
|
||||
{
|
||||
IPACMERR("Error Adding Filtering rule, aborting...\n");
|
||||
res = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
else if (m_pFilteringTable->rules[0].status)
|
||||
{
|
||||
IPACMERR("adding flt rule failed status=0x%x\n", m_pFilteringTable->rules[0].status);
|
||||
res = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
|
||||
IPACMDBG("soft-routing flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl);
|
||||
/* copy filter hdls */
|
||||
software_routing_fl_rule_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl;
|
||||
|
||||
|
||||
/* handle v6*/
|
||||
m_pFilteringTable->ip = IPA_IP_v6;
|
||||
if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
|
||||
{
|
||||
IPACMERR("Error Adding Filtering rule, aborting...\n");
|
||||
res = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
else if (m_pFilteringTable->rules[0].status)
|
||||
{
|
||||
IPACMDBG("adding flt rule failed status=0x%x\n", m_pFilteringTable->rules[0].status);
|
||||
res = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
|
||||
IPACMDBG("soft-routing flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl);
|
||||
/* copy filter hdls */
|
||||
software_routing_fl_rule_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl;
|
||||
softwarerouting_act = true;
|
||||
#if 0
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ip_type == IPA_IP_v4)
|
||||
{
|
||||
m_pFilteringTable->ip = IPA_IP_v4;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pFilteringTable->ip = IPA_IP_v6;
|
||||
}
|
||||
|
||||
if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
|
||||
{
|
||||
IPACMERR("Error Adding Filtering rule, aborting...\n");
|
||||
res = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
else if (m_pFilteringTable->rules[0].status)
|
||||
{
|
||||
IPACMERR("adding flt rule failed status=0x%x\n", m_pFilteringTable->rules[0].status);
|
||||
res = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, ip_type, 1);
|
||||
IPACMDBG("soft-routing flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl);
|
||||
/* copy filter hdls */
|
||||
if (ip_type == IPA_IP_v4)
|
||||
{
|
||||
software_routing_fl_rule_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl;
|
||||
}
|
||||
else
|
||||
{
|
||||
software_routing_fl_rule_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl;
|
||||
}
|
||||
softwarerouting_act = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
fail:
|
||||
free(m_pFilteringTable);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* software routing disable */
|
||||
int IPACM_Iface::handle_software_routing_disable(void)
|
||||
{
|
||||
int res = IPACM_SUCCESS;
|
||||
ipa_ip_type ip;
|
||||
uint32_t flt_hdl;
|
||||
|
||||
if (rx_prop == NULL)
|
||||
{
|
||||
IPACMDBG("No rx properties registered for iface %s\n", dev_name);
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
if (softwarerouting_act == false)
|
||||
{
|
||||
IPACMDBG("already delete software_routing rule for (%s)iface ip-family %d\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ip_type);
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
// if (ip_type == IPA_IP_MAX)
|
||||
// {
|
||||
/* ipv4 case */
|
||||
if (m_filtering.DeleteFilteringHdls(&software_routing_fl_rule_hdl[0],
|
||||
IPA_IP_v4, 1) == false)
|
||||
{
|
||||
IPACMERR("Error Adding Filtering rule, aborting...\n");
|
||||
res = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
|
||||
|
||||
/* ipv6 case */
|
||||
if (m_filtering.DeleteFilteringHdls(&software_routing_fl_rule_hdl[1],
|
||||
IPA_IP_v6, 1) == false)
|
||||
{
|
||||
IPACMERR("Error Adding Filtering rule, aborting...\n");
|
||||
res = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
|
||||
softwarerouting_act = false;
|
||||
#if 0
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ip_type == IPA_IP_v4)
|
||||
{
|
||||
ip = IPA_IP_v4;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip = IPA_IP_v6;
|
||||
}
|
||||
|
||||
|
||||
if (ip_type == IPA_IP_v4)
|
||||
{
|
||||
flt_hdl = software_routing_fl_rule_hdl[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
flt_hdl = software_routing_fl_rule_hdl[1];
|
||||
}
|
||||
|
||||
if (m_filtering.DeleteFilteringHdls(&flt_hdl, ip, 1) == false)
|
||||
{
|
||||
IPACMERR("Error Adding Filtering rule, aborting...\n");
|
||||
res = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, ip, 1);
|
||||
softwarerouting_act = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
fail:
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Query ipa_interface_index by given linux interface_index */
|
||||
int IPACM_Iface::iface_ipa_index_query
|
||||
(
|
||||
int interface_index
|
||||
)
|
||||
{
|
||||
int fd;
|
||||
int link = INVALID_IFACE;
|
||||
int i = 0;
|
||||
struct ifreq ifr;
|
||||
|
||||
|
||||
if(IPACM_Iface::ipacmcfg->iface_table == NULL)
|
||||
{
|
||||
IPACMERR("Iface table in IPACM_Config is not available.\n");
|
||||
return link;
|
||||
}
|
||||
|
||||
/* Search known linux interface-index and map to IPA interface-index*/
|
||||
for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_ipa_interfaces; i++)
|
||||
{
|
||||
if (interface_index == IPACM_Iface::ipacmcfg->iface_table[i].netlink_interface_index)
|
||||
{
|
||||
link = i;
|
||||
IPACMDBG("Interface (%s) found: linux(%d) ipa(%d) \n",
|
||||
IPACM_Iface::ipacmcfg->iface_table[i].iface_name,
|
||||
IPACM_Iface::ipacmcfg->iface_table[i].netlink_interface_index,
|
||||
link);
|
||||
return link;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Search/Configure linux interface-index and map it to IPA interface-index */
|
||||
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
{
|
||||
PERROR("get interface name socket create failed");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
|
||||
ifr.ifr_ifindex = interface_index;
|
||||
IPACMDBG_H("Interface index %d\n", interface_index);
|
||||
|
||||
if (ioctl(fd, SIOCGIFNAME, &ifr) < 0)
|
||||
{
|
||||
PERROR("call_ioctl_on_dev: ioctl failed:");
|
||||
close(fd);
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
IPACMDBG_H("Received interface name %s\n", ifr.ifr_name);
|
||||
for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_ipa_interfaces; i++)
|
||||
{
|
||||
if (strncmp(ifr.ifr_name,
|
||||
IPACM_Iface::ipacmcfg->iface_table[i].iface_name,
|
||||
sizeof(IPACM_Iface::ipacmcfg->iface_table[i].iface_name)) == 0)
|
||||
{
|
||||
IPACMDBG_H("Interface (%s) linux(%d) mapped to ipa(%d) \n", ifr.ifr_name,
|
||||
IPACM_Iface::ipacmcfg->iface_table[i].netlink_interface_index, i);
|
||||
|
||||
link = i;
|
||||
IPACM_Iface::ipacmcfg->iface_table[i].netlink_interface_index = interface_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
/* Query ipa_interface ipv4_addr by given linux interface_index */
|
||||
void IPACM_Iface::iface_addr_query
|
||||
(
|
||||
int interface_index
|
||||
)
|
||||
{
|
||||
int fd;
|
||||
struct ifreq ifr;
|
||||
struct ifaddrs *myaddrs, *ifa;
|
||||
ipacm_cmd_q_data evt_data;
|
||||
ipacm_event_data_addr *data_addr;
|
||||
struct in_addr iface_ipv4;
|
||||
|
||||
/* use linux interface-index to find interface name */
|
||||
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
{
|
||||
PERROR("get interface name socket create failed");
|
||||
return ;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
|
||||
ifr.ifr_ifindex = interface_index;
|
||||
IPACMDBG_H("Interface index %d\n", interface_index);
|
||||
|
||||
if (ioctl(fd, SIOCGIFNAME, &ifr) < 0)
|
||||
{
|
||||
PERROR("call_ioctl_on_dev: ioctl failed:");
|
||||
close(fd);
|
||||
return ;
|
||||
}
|
||||
IPACMDBG_H("Interface index %d name: %s\n", interface_index,ifr.ifr_name);
|
||||
close(fd);
|
||||
|
||||
/* query ipv4/v6 address */
|
||||
if(getifaddrs(&myaddrs) != 0)
|
||||
{
|
||||
IPACMERR("getifaddrs");
|
||||
return ;
|
||||
}
|
||||
|
||||
for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
|
||||
{
|
||||
if (ifa->ifa_addr == NULL)
|
||||
continue;
|
||||
if (!(ifa->ifa_flags & IFF_UP))
|
||||
continue;
|
||||
|
||||
if(strcmp(ifr.ifr_name,ifa->ifa_name) == 0) // find current iface
|
||||
{
|
||||
IPACMDBG_H("Internal post new_addr event for iface %s\n", ifa->ifa_name);
|
||||
switch (ifa->ifa_addr->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *s4 = (struct sockaddr_in *)ifa->ifa_addr;
|
||||
IPACMDBG_H("ipv4 address %s\n",inet_ntoa(s4->sin_addr));
|
||||
iface_ipv4 = s4->sin_addr;
|
||||
/* post new_addr event to command queue */
|
||||
data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
|
||||
if(data_addr == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event data_addr\n");
|
||||
freeifaddrs(myaddrs);
|
||||
return ;
|
||||
}
|
||||
data_addr->iptype = IPA_IP_v4;
|
||||
data_addr->if_index = interface_index;
|
||||
data_addr->ipv4_addr = iface_ipv4.s_addr;
|
||||
data_addr->ipv4_addr = ntohl(data_addr->ipv4_addr);
|
||||
IPACMDBG_H("Posting IPA_ADDR_ADD_EVENT with if index:%d, ipv4 addr:0x%x\n",
|
||||
data_addr->if_index,
|
||||
data_addr->ipv4_addr);
|
||||
|
||||
evt_data.event = IPA_ADDR_ADD_EVENT;
|
||||
evt_data.evt_data = data_addr;
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
break;
|
||||
}
|
||||
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)ifa->ifa_addr;
|
||||
/* post new_addr event to command queue */
|
||||
data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
|
||||
if(data_addr == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event data_addr\n");
|
||||
freeifaddrs(myaddrs);
|
||||
return ;
|
||||
}
|
||||
data_addr->iptype = IPA_IP_v6;
|
||||
data_addr->if_index = interface_index;
|
||||
memcpy(data_addr->ipv6_addr,
|
||||
&s6->sin6_addr,
|
||||
sizeof(data_addr->ipv6_addr));
|
||||
data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
|
||||
data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
|
||||
data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
|
||||
data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
|
||||
IPACMDBG_H("Posting IPA_ADDR_ADD_EVENT with if index:%d, ipv6 addr:0x%x:%x:%x:%x\n",
|
||||
data_addr->if_index,
|
||||
data_addr->ipv6_addr[0], data_addr->ipv6_addr[1], data_addr->ipv6_addr[2], data_addr->ipv6_addr[3]);
|
||||
|
||||
evt_data.event = IPA_ADDR_ADD_EVENT;
|
||||
evt_data.evt_data = data_addr;
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
freeifaddrs(myaddrs);
|
||||
return ;
|
||||
}
|
||||
|
||||
/*Query the IPA endpoint property */
|
||||
int IPACM_Iface::query_iface_property(void)
|
||||
{
|
||||
int res = IPACM_SUCCESS, fd = 0;
|
||||
uint32_t cnt=0;
|
||||
|
||||
fd = open(DEVICE_NAME, O_RDWR);
|
||||
IPACMDBG("iface query-property \n");
|
||||
if (0 == fd)
|
||||
{
|
||||
IPACMERR("Failed opening %s.\n", DEVICE_NAME);
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
iface_query = (struct ipa_ioc_query_intf *)
|
||||
calloc(1, sizeof(struct ipa_ioc_query_intf));
|
||||
if(iface_query == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate iface_query memory.\n");
|
||||
close(fd);
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
IPACMDBG_H("iface name %s\n", dev_name);
|
||||
memcpy(iface_query->name, dev_name, sizeof(dev_name));
|
||||
|
||||
if (ioctl(fd, IPA_IOC_QUERY_INTF, iface_query) < 0)
|
||||
{
|
||||
PERROR("ioctl IPA_IOC_QUERY_INTF failed\n");
|
||||
/* iface_query memory will free when iface-down*/
|
||||
res = IPACM_FAILURE;
|
||||
}
|
||||
|
||||
if(iface_query->num_tx_props > 0)
|
||||
{
|
||||
tx_prop = (struct ipa_ioc_query_intf_tx_props *)
|
||||
calloc(1, sizeof(struct ipa_ioc_query_intf_tx_props) +
|
||||
iface_query->num_tx_props * sizeof(struct ipa_ioc_tx_intf_prop));
|
||||
if(tx_prop == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate tx_prop memory.\n");
|
||||
close(fd);
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
memcpy(tx_prop->name, dev_name, sizeof(tx_prop->name));
|
||||
tx_prop->num_tx_props = iface_query->num_tx_props;
|
||||
|
||||
if (ioctl(fd, IPA_IOC_QUERY_INTF_TX_PROPS, tx_prop) < 0)
|
||||
{
|
||||
PERROR("ioctl IPA_IOC_QUERY_INTF_TX_PROPS failed\n");
|
||||
/* tx_prop memory will free when iface-down*/
|
||||
res = IPACM_FAILURE;
|
||||
}
|
||||
|
||||
if (res != IPACM_FAILURE)
|
||||
{
|
||||
for (cnt = 0; cnt < tx_prop->num_tx_props; cnt++)
|
||||
{
|
||||
IPACMDBG_H("Tx(%d):attrib-mask:0x%x, ip-type: %d, dst_pipe: %d, alt_dst_pipe: %d, header: %s\n",
|
||||
cnt, tx_prop->tx[cnt].attrib.attrib_mask,
|
||||
tx_prop->tx[cnt].ip, tx_prop->tx[cnt].dst_pipe,
|
||||
tx_prop->tx[cnt].alt_dst_pipe,
|
||||
tx_prop->tx[cnt].hdr_name);
|
||||
|
||||
if (tx_prop->tx[cnt].dst_pipe == 0)
|
||||
{
|
||||
IPACMERR("Tx(%d): wrong tx property: dst_pipe: 0.\n", cnt);
|
||||
close(fd);
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
if (tx_prop->tx[cnt].alt_dst_pipe == 0 &&
|
||||
((memcmp(dev_name, "wlan0", sizeof("wlan0")) == 0) ||
|
||||
(memcmp(dev_name, "wlan1", sizeof("wlan1")) == 0)))
|
||||
{
|
||||
IPACMERR("Tx(%d): wrong tx property: alt_dst_pipe: 0. \n", cnt);
|
||||
close(fd);
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (iface_query->num_rx_props > 0)
|
||||
{
|
||||
rx_prop = (struct ipa_ioc_query_intf_rx_props *)
|
||||
calloc(1, sizeof(struct ipa_ioc_query_intf_rx_props) +
|
||||
iface_query->num_rx_props * sizeof(struct ipa_ioc_rx_intf_prop));
|
||||
if(rx_prop == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate rx_prop memory.\n");
|
||||
close(fd);
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
memcpy(rx_prop->name, dev_name,
|
||||
sizeof(rx_prop->name));
|
||||
rx_prop->num_rx_props = iface_query->num_rx_props;
|
||||
|
||||
if (ioctl(fd, IPA_IOC_QUERY_INTF_RX_PROPS, rx_prop) < 0)
|
||||
{
|
||||
PERROR("ioctl IPA_IOC_QUERY_INTF_RX_PROPS failed\n");
|
||||
/* rx_prop memory will free when iface-down*/
|
||||
res = IPACM_FAILURE;
|
||||
}
|
||||
|
||||
if (res != IPACM_FAILURE)
|
||||
{
|
||||
for (cnt = 0; cnt < rx_prop->num_rx_props; cnt++)
|
||||
{
|
||||
IPACMDBG_H("Rx(%d):attrib-mask:0x%x, ip-type: %d, src_pipe: %d\n",
|
||||
cnt, rx_prop->rx[cnt].attrib.attrib_mask, rx_prop->rx[cnt].ip, rx_prop->rx[cnt].src_pipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*Configure the initial filter rules */
|
||||
int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
|
||||
{
|
||||
|
||||
int res = IPACM_SUCCESS, len = 0;
|
||||
struct ipa_flt_rule_add flt_rule_entry;
|
||||
ipa_ioc_add_flt_rule *m_pFilteringTable;
|
||||
|
||||
/* Adding this hack because WLAN may not registered for Rx-endpoint, other ifaces will always have*/
|
||||
const char *dev_wlan0="wlan0";
|
||||
const char *dev_wlan1="wlan1";
|
||||
const char *dev_ecm0="ecm0";
|
||||
|
||||
/* ADD corresponding ipa_rm_resource_name of RX-endpoint before adding all IPV4V6 FT-rules */
|
||||
if((IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat== WAN_IF) || (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat== EMBMS_IF))
|
||||
{
|
||||
IPACMDBG_H(" NOT add producer dependency on dev %s with registered rx-prop cat:%d \n", dev_name, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat);
|
||||
}
|
||||
else
|
||||
{
|
||||
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->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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rx_prop == NULL)
|
||||
{
|
||||
IPACMDBG_H("No rx properties registered for iface %s\n", dev_name);
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
/* construct ipa_ioc_add_flt_rule with default filter rules */
|
||||
if (iptype == IPA_IP_v4)
|
||||
{
|
||||
len = sizeof(struct ipa_ioc_add_flt_rule) +
|
||||
(IPV4_DEFAULT_FILTERTING_RULES * sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
|
||||
if (!m_pFilteringTable)
|
||||
{
|
||||
IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
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 = (uint8_t)IPV4_DEFAULT_FILTERTING_RULES;
|
||||
|
||||
/* Configuring Fragment Filtering Rule */
|
||||
memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
flt_rule_entry.rule.retain_hdr = 1;
|
||||
flt_rule_entry.at_rear = true;
|
||||
flt_rule_entry.flt_rule_hdl = -1;
|
||||
flt_rule_entry.status = -1;
|
||||
flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
|
||||
#ifdef FEATURE_IPA_V3
|
||||
flt_rule_entry.at_rear = false;
|
||||
flt_rule_entry.rule.hashable = false;
|
||||
#endif
|
||||
IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask);
|
||||
memcpy(&flt_rule_entry.rule.attrib,
|
||||
&rx_prop->rx[0].attrib,
|
||||
sizeof(flt_rule_entry.rule.attrib));
|
||||
|
||||
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT;
|
||||
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
/* Configuring Multicast Filtering Rule */
|
||||
memcpy(&flt_rule_entry.rule.attrib,
|
||||
&rx_prop->rx[0].attrib,
|
||||
sizeof(flt_rule_entry.rule.attrib));
|
||||
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
|
||||
flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xF0000000;
|
||||
flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xE0000000;
|
||||
#ifdef FEATURE_IPA_V3
|
||||
flt_rule_entry.at_rear = true;
|
||||
flt_rule_entry.rule.hashable = true;
|
||||
#endif
|
||||
memcpy(&(m_pFilteringTable->rules[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
/* Configuring Broadcast Filtering Rule */
|
||||
flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
|
||||
flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xFFFFFFFF;
|
||||
#ifdef FEATURE_IPA_V3
|
||||
flt_rule_entry.at_rear = true;
|
||||
flt_rule_entry.rule.hashable = true;
|
||||
#endif
|
||||
memcpy(&(m_pFilteringTable->rules[2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
|
||||
{
|
||||
IPACMERR("Error Adding Filtering rule, aborting...\n");
|
||||
res = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
|
||||
/* copy filter hdls */
|
||||
for (int i = 0; i < IPV4_DEFAULT_FILTERTING_RULES; i++)
|
||||
{
|
||||
if (m_pFilteringTable->rules[i].status == 0)
|
||||
{
|
||||
dft_v4fl_rule_hdl[i] = m_pFilteringTable->rules[i].flt_rule_hdl;
|
||||
IPACMDBG_H("Default v4 filter Rule %d HDL:0x%x\n", i, dft_v4fl_rule_hdl[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMERR("Failed adding default v4 Filtering rule %d\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = sizeof(struct ipa_ioc_add_flt_rule) +
|
||||
(IPV6_DEFAULT_FILTERTING_RULES * sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len);
|
||||
if (!m_pFilteringTable)
|
||||
{
|
||||
IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
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 = (uint8_t)IPV6_DEFAULT_FILTERTING_RULES;
|
||||
|
||||
memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
flt_rule_entry.rule.retain_hdr = 1;
|
||||
flt_rule_entry.at_rear = true;
|
||||
flt_rule_entry.flt_rule_hdl = -1;
|
||||
flt_rule_entry.status = -1;
|
||||
flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
|
||||
/* Configuring Multicast Filtering Rule */
|
||||
memcpy(&flt_rule_entry.rule.attrib,
|
||||
&rx_prop->rx[0].attrib,
|
||||
sizeof(flt_rule_entry.rule.attrib));
|
||||
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFF000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0XFF000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
|
||||
#ifdef FEATURE_IPA_V3
|
||||
flt_rule_entry.at_rear = true;
|
||||
flt_rule_entry.rule.hashable = true;
|
||||
#endif
|
||||
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
/* Configuring fe80::/10 Link-Scoped Unicast Filtering Rule */
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0XFFC00000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFE800000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
|
||||
#ifdef FEATURE_IPA_V3
|
||||
flt_rule_entry.at_rear = true;
|
||||
flt_rule_entry.rule.hashable = true;
|
||||
#endif
|
||||
memcpy(&(m_pFilteringTable->rules[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
/* Configuring fec0::/10 Reserved by IETF Filtering Rule */
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0XFFC00000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFEC00000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
|
||||
flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
|
||||
#ifdef FEATURE_IPA_V3
|
||||
flt_rule_entry.at_rear = true;
|
||||
flt_rule_entry.rule.hashable = true;
|
||||
#endif
|
||||
memcpy(&(m_pFilteringTable->rules[2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
#ifdef FEATURE_IPA_ANDROID
|
||||
IPACMDBG_H("Add TCP ctrl rules: total num %d\n", IPV6_DEFAULT_FILTERTING_RULES);
|
||||
memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
|
||||
|
||||
flt_rule_entry.at_rear = true;
|
||||
flt_rule_entry.flt_rule_hdl = -1;
|
||||
flt_rule_entry.status = -1;
|
||||
|
||||
flt_rule_entry.rule.retain_hdr = 1;
|
||||
flt_rule_entry.rule.to_uc = 0;
|
||||
flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
|
||||
flt_rule_entry.rule.eq_attrib_type = 1;
|
||||
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap = 0;
|
||||
|
||||
if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA)
|
||||
{
|
||||
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<14);
|
||||
flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1;
|
||||
flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0;
|
||||
flt_rule_entry.rule.eq_attrib.metadata_meq32.value = rx_prop->rx[0].attrib.meta_data;
|
||||
flt_rule_entry.rule.eq_attrib.metadata_meq32.mask = rx_prop->rx[0].attrib.meta_data_mask;
|
||||
}
|
||||
|
||||
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<1);
|
||||
flt_rule_entry.rule.eq_attrib.protocol_eq_present = 1;
|
||||
flt_rule_entry.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP;
|
||||
|
||||
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<8);
|
||||
flt_rule_entry.rule.eq_attrib.num_ihl_offset_meq_32 = 1;
|
||||
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12;
|
||||
|
||||
/* add TCP FIN rule*/
|
||||
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<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[3]), &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[4]), &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[5]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
|
||||
#endif
|
||||
if (m_filtering.AddFilteringRule(m_pFilteringTable) == false)
|
||||
{
|
||||
IPACMERR("Error Adding Filtering rule, aborting...\n");
|
||||
res = IPACM_FAILURE;
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
|
||||
/* copy filter hdls */
|
||||
for (int i = 0;
|
||||
i < IPV6_DEFAULT_FILTERTING_RULES;
|
||||
i++)
|
||||
{
|
||||
if (m_pFilteringTable->rules[i].status == 0)
|
||||
{
|
||||
dft_v6fl_rule_hdl[i] = m_pFilteringTable->rules[i].flt_rule_hdl;
|
||||
IPACMDBG_H("Default v6 Filter Rule %d HDL:0x%x\n", i, dft_v6fl_rule_hdl[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMERR("Failing adding v6 default IPV6 rule %d\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fail:
|
||||
free(m_pFilteringTable);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* get ipa interface name */
|
||||
int IPACM_Iface::ipa_get_if_index
|
||||
(
|
||||
char * if_name,
|
||||
int * if_index
|
||||
)
|
||||
{
|
||||
int fd;
|
||||
struct ifreq ifr;
|
||||
|
||||
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
{
|
||||
IPACMERR("get interface index socket create failed \n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
(void)strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
|
||||
IPACMDBG_H("interface name (%s)\n", if_name);
|
||||
|
||||
if (ioctl(fd,SIOCGIFINDEX , &ifr) < 0)
|
||||
{
|
||||
IPACMERR("call_ioctl_on_dev: ioctl failed, interface name (%s):\n", ifr.ifr_name);
|
||||
close(fd);
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
*if_index = ifr.ifr_ifindex;
|
||||
IPACMDBG_H("Interface index %d\n", *if_index);
|
||||
close(fd);
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
void IPACM_Iface::config_ip_type(ipa_ip_type iptype)
|
||||
{
|
||||
/* update the iface ip-type to be IPA_IP_v4, IPA_IP_v6 or both*/
|
||||
if (iptype == IPA_IP_v4)
|
||||
{
|
||||
if ((ip_type == IPA_IP_v4) || (ip_type == IPA_IP_MAX))
|
||||
{
|
||||
IPACMDBG_H(" interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ip_type == IPA_IP_v6)
|
||||
{
|
||||
ip_type = IPA_IP_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip_type = IPA_IP_v4;
|
||||
}
|
||||
IPACMDBG_H(" interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ip_type == IPA_IP_v6) || (ip_type == IPA_IP_MAX))
|
||||
{
|
||||
IPACMDBG_H(" interface(%s:%d) already in ip-type %d\n", dev_name, ipa_if_num, ip_type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ip_type == IPA_IP_v4)
|
||||
{
|
||||
ip_type = IPA_IP_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip_type = IPA_IP_v6;
|
||||
}
|
||||
|
||||
IPACMDBG_H(" interface(%s:%d) now ip-type is %d\n", dev_name, ipa_if_num, ip_type);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
565
data-ipa-cfg-mgr/ipacm/src/IPACM_IfaceManager.cpp
Normal file
565
data-ipa-cfg-mgr/ipacm/src/IPACM_IfaceManager.cpp
Normal file
@@ -0,0 +1,565 @@
|
||||
/*
|
||||
Copyright (c) 2013-2016, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.
|
||||
*/
|
||||
/*!
|
||||
@file
|
||||
IPACM_IfaceManager.cpp
|
||||
|
||||
@brief
|
||||
This file implements the IPAM iface_manager functionality.
|
||||
|
||||
@Author
|
||||
Skylar Chang
|
||||
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <IPACM_IfaceManager.h>
|
||||
#include <IPACM_EvtDispatcher.h>
|
||||
#include <IPACM_Defs.h>
|
||||
#include <IPACM_Wlan.h>
|
||||
#include <IPACM_Lan.h>
|
||||
#include <IPACM_Wan.h>
|
||||
#include <IPACM_Iface.h>
|
||||
#include <IPACM_Log.h>
|
||||
|
||||
iface_instances *IPACM_IfaceManager::head = NULL;
|
||||
|
||||
IPACM_IfaceManager::IPACM_IfaceManager()
|
||||
{
|
||||
IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, this); // register for IPA_CFG_CHANGE event
|
||||
IPACM_EvtDispatcher::registr(IPA_LINK_UP_EVENT, this);
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_AP_LINK_UP_EVENT, this); // register for wlan AP-iface
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_STA_LINK_UP_EVENT, this); // register for wlan STA-iface
|
||||
#ifndef FEATURE_IPA_ANDROID
|
||||
/* only MDM targets support device on bridge mode */
|
||||
IPACM_EvtDispatcher::registr(IPA_BRIDGE_LINK_UP_EVENT, this); // register for IPA_BRIDGE_LINK_UP_EVENT event
|
||||
#endif /* not defined(FEATURE_IPA_ANDROID)*/
|
||||
IPACM_EvtDispatcher::registr(IPA_USB_LINK_UP_EVENT, this); // register for USB-iface
|
||||
IPACM_EvtDispatcher::registr(IPA_WAN_EMBMS_LINK_UP_EVENT, this); // register for wan eMBMS-iface
|
||||
return;
|
||||
}
|
||||
|
||||
void IPACM_IfaceManager::event_callback(ipa_cm_event_id event, void *param)
|
||||
{
|
||||
int ipa_interface_index;
|
||||
ipacm_event_data_fid *evt_data = (ipacm_event_data_fid *)param;
|
||||
ipacm_event_data_mac *StaData = (ipacm_event_data_mac *)param;
|
||||
ipacm_event_data_all *data_all = (ipacm_event_data_all *)param;
|
||||
ipacm_ifacemgr_data ifmgr_data = {0};
|
||||
|
||||
switch(event)
|
||||
{
|
||||
case IPA_CFG_CHANGE_EVENT:
|
||||
IPACMDBG_H(" RESET IPACM_cfg \n");
|
||||
IPACM_Iface::ipacmcfg->Init();
|
||||
break;
|
||||
case IPA_BRIDGE_LINK_UP_EVENT:
|
||||
IPACMDBG_H(" Save the bridge0 mac info in IPACM_cfg \n");
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
|
||||
/* check for failure return */
|
||||
if (IPACM_FAILURE == ipa_interface_index) {
|
||||
IPACMERR("IPA_BRIDGE_LINK_UP_EVENT: not supported iface id: %d\n", data_all->if_index);
|
||||
break;
|
||||
}
|
||||
/* check if iface is bridge interface*/
|
||||
if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0)
|
||||
{
|
||||
IPACM_Iface::ipacmcfg->ipa_bridge_enable = true;
|
||||
memcpy(IPACM_Iface::ipacmcfg->bridge_mac,
|
||||
data_all->mac_addr,
|
||||
sizeof(IPACM_Iface::ipacmcfg->bridge_mac));
|
||||
IPACMDBG_H("cached bridge0 MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
IPACM_Iface::ipacmcfg->bridge_mac[0], IPACM_Iface::ipacmcfg->bridge_mac[1], IPACM_Iface::ipacmcfg->bridge_mac[2],
|
||||
IPACM_Iface::ipacmcfg->bridge_mac[3], IPACM_Iface::ipacmcfg->bridge_mac[4], IPACM_Iface::ipacmcfg->bridge_mac[5]);
|
||||
}
|
||||
break;
|
||||
case IPA_LINK_UP_EVENT:
|
||||
IPACMDBG_H("Recieved IPA_LINK_UP_EVENT event: link up %d: \n", evt_data->if_index);
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
|
||||
/* check for failure return */
|
||||
if (IPACM_FAILURE == ipa_interface_index) {
|
||||
IPACMERR("IPA_LINK_UP_EVENT: not supported iface id: %d\n", evt_data->if_index);
|
||||
break;
|
||||
}
|
||||
/* LTE-backhaul */
|
||||
if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == EMBMS_IF)
|
||||
{
|
||||
IPACMDBG("WAN-EMBMS (%s) link already up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
|
||||
}
|
||||
else if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
|
||||
{
|
||||
IPACMDBG_H("WAN-LTE (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
|
||||
ifmgr_data.if_index = evt_data->if_index;
|
||||
ifmgr_data.if_type = Q6_WAN;
|
||||
create_iface_instance(&ifmgr_data);
|
||||
}
|
||||
break;
|
||||
|
||||
case IPA_USB_LINK_UP_EVENT:
|
||||
IPACMDBG_H("Recieved IPA_USB_LINK_UP_EVENT event: link up %d: \n", evt_data->if_index);
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
|
||||
/* check for failure return */
|
||||
if (IPACM_FAILURE == ipa_interface_index) {
|
||||
IPACMERR("IPA_USB_LINK_UP_EVENT: not supported iface id: %d\n", evt_data->if_index);
|
||||
break;
|
||||
}
|
||||
/* check if it's WAN_IF */
|
||||
if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
|
||||
{
|
||||
/* usb-backhaul using sta_mode ECM_WAN*/
|
||||
IPACMDBG_H("WAN-usb (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, evt_data->if_index);
|
||||
ifmgr_data.if_index = evt_data->if_index;
|
||||
ifmgr_data.if_type = ECM_WAN;
|
||||
create_iface_instance(&ifmgr_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
ifmgr_data.if_index = evt_data->if_index;
|
||||
ifmgr_data.if_type = Q6_WAN;
|
||||
create_iface_instance(&ifmgr_data);
|
||||
}
|
||||
break;
|
||||
|
||||
case IPA_WLAN_AP_LINK_UP_EVENT:
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
|
||||
/* check for failure return */
|
||||
if (IPACM_FAILURE == ipa_interface_index) {
|
||||
IPACMERR("IPA_WLAN_AP_LINK_UP_EVENT: not supported iface id: %d\n", evt_data->if_index);
|
||||
break;
|
||||
}
|
||||
/* change iface category from unknown to WLAN_IF */
|
||||
if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == UNKNOWN_IF)
|
||||
{
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = WLAN_IF;
|
||||
IPACMDBG_H("WLAN AP (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
|
||||
ifmgr_data.if_index = evt_data->if_index;
|
||||
ifmgr_data.if_type = Q6_WAN;
|
||||
create_iface_instance(&ifmgr_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG_H("iface %s already up and act as %d mode: \n",IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
|
||||
}
|
||||
break;
|
||||
|
||||
case IPA_WLAN_STA_LINK_UP_EVENT:
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(StaData->if_index);
|
||||
/* check for failure return */
|
||||
if (IPACM_FAILURE == ipa_interface_index) {
|
||||
IPACMERR("IPA_WLAN_STA_LINK_UP_EVENT: not supported iface id: %d\n", StaData->if_index);
|
||||
break;
|
||||
}
|
||||
/* change iface category from unknown to WAN_IF */
|
||||
if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == UNKNOWN_IF)
|
||||
{
|
||||
/* wlan-backhaul using sta_mode WLAN_WAN */
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat = WAN_IF;
|
||||
IPACMDBG_H("WLAN STA (%s) link up, iface: %d: \n",
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name, StaData->if_index);
|
||||
|
||||
ifmgr_data.if_index = StaData->if_index;
|
||||
ifmgr_data.if_type = WLAN_WAN;
|
||||
memcpy(ifmgr_data.mac_addr, StaData->mac_addr, sizeof(ifmgr_data.mac_addr));
|
||||
create_iface_instance(&ifmgr_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG_H("iface %s already up and act as %d mode: \n",
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Add new instance open for eMBMS iface and wan iface */
|
||||
case IPA_WAN_EMBMS_LINK_UP_EVENT:
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(evt_data->if_index);
|
||||
/* check for failure return */
|
||||
if (IPACM_FAILURE == ipa_interface_index) {
|
||||
IPACMERR("IPA_WAN_EMBMS_LINK_UP_EVENT: not supported iface id: %d\n", evt_data->if_index);
|
||||
break;
|
||||
}
|
||||
/* change iface category from unknown to EMBMS_IF */
|
||||
if ((IPACM_Iface::ipacmcfg->ipacm_odu_enable == true) && (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true))
|
||||
{
|
||||
IPACMDBG(" ODU-mode enable or not (%d) \n",IPACM_Iface::ipacmcfg->ipacm_odu_enable);
|
||||
if(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat == WAN_IF)
|
||||
{
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat=EMBMS_IF;
|
||||
IPACMDBG("WAN eMBMS (%s) link up, iface: %d: \n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,evt_data->if_index);
|
||||
ifmgr_data.if_index = StaData->if_index;
|
||||
ifmgr_data.if_type = Q6_WAN;
|
||||
create_iface_instance(&ifmgr_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG("iface %s already up and act as %d mode: \n",IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param)
|
||||
{
|
||||
int if_index = param->if_index;
|
||||
ipacm_wan_iface_type is_sta_mode = param->if_type;
|
||||
|
||||
int ipa_interface_index;
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(if_index);
|
||||
|
||||
if(ipa_interface_index == INVALID_IFACE)
|
||||
{
|
||||
IPACMDBG_H("Unhandled interface received, fid: %d\n",if_index);
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
/* check if duplicate instance*/
|
||||
if(SearchInstance(ipa_interface_index) == IPA_INSTANCE_NOT_FOUND)
|
||||
{
|
||||
/* IPA_INSTANCE_NOT_FOUND */
|
||||
switch(IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat)
|
||||
{
|
||||
|
||||
case LAN_IF:
|
||||
{
|
||||
IPACMDBG_H("Creating Lan interface\n");
|
||||
IPACM_Lan *lan = new IPACM_Lan(ipa_interface_index);
|
||||
IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, lan);
|
||||
//IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, lan);
|
||||
//IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, lan);
|
||||
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, lan);
|
||||
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, lan);
|
||||
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, lan);
|
||||
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, lan);
|
||||
#ifdef FEATURE_IPA_ANDROID
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, lan);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, lan);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, lan);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, lan);
|
||||
#else
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, lan);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, lan);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, lan);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, lan);
|
||||
#endif
|
||||
IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, lan); // register for IPA_CFG_CHANGE event
|
||||
IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, lan); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
|
||||
#ifdef FEATURE_IPA_ANDROID
|
||||
IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, lan);
|
||||
#endif
|
||||
IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, lan);
|
||||
IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, lan);
|
||||
/* IPA_LAN_DELETE_SELF should be always last */
|
||||
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, lan);
|
||||
IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", lan->dev_name, lan->ipa_if_num);
|
||||
registr(ipa_interface_index, lan);
|
||||
/* solve the new_addr comes earlier issue */
|
||||
IPACM_Iface::iface_addr_query(if_index);
|
||||
}
|
||||
break;
|
||||
|
||||
case ETH_IF:
|
||||
{
|
||||
IPACMDBG_H("Creating ETH interface in router mode\n");
|
||||
IPACM_Lan *ETH = new IPACM_Lan(ipa_interface_index);
|
||||
IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, ETH);
|
||||
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, ETH);
|
||||
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, ETH);
|
||||
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, ETH);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, ETH);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, ETH);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, ETH);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, ETH);
|
||||
IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, ETH);
|
||||
IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, ETH);
|
||||
/* IPA_LAN_DELETE_SELF should be always last */
|
||||
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, ETH);
|
||||
IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", ETH->dev_name, ETH->ipa_if_num);
|
||||
registr(ipa_interface_index, ETH);
|
||||
/* solve the new_addr comes earlier issue */
|
||||
IPACM_Iface::iface_addr_query(if_index);
|
||||
}
|
||||
break;
|
||||
|
||||
case ODU_IF:
|
||||
{
|
||||
if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true)
|
||||
{
|
||||
IPACMDBG_H("Creating ODU interface in router mode\n");
|
||||
IPACM_Lan *odu = new IPACM_Lan(ipa_interface_index);
|
||||
IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, odu);
|
||||
/* IPA_LAN_DELETE_SELF should be always last */
|
||||
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu);
|
||||
IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", odu->dev_name, odu->ipa_if_num);
|
||||
registr(ipa_interface_index, odu);
|
||||
/* solve the new_addr comes earlier issue */
|
||||
IPACM_Iface::iface_addr_query(if_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG_H("Creating ODU interface in bridge mode\n");
|
||||
IPACM_Lan *odu = new IPACM_Lan(ipa_interface_index);
|
||||
IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, odu);
|
||||
IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, odu);
|
||||
/* IPA_LAN_DELETE_SELF should be always last */
|
||||
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu);
|
||||
IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance open/registr ok\n", odu->dev_name, odu->ipa_if_num);
|
||||
registr(ipa_interface_index, odu);
|
||||
/* solve the new_addr comes earlier issue */
|
||||
IPACM_Iface::iface_addr_query(if_index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WLAN_IF:
|
||||
{
|
||||
IPACMDBG_H("Creating WLan interface\n");
|
||||
IPACM_Wlan *wl = new IPACM_Wlan(ipa_interface_index);
|
||||
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);
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT_EX, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_DEL_EVENT, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_POWER_SAVE_EVENT, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_RECOVER_EVENT, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, wl);
|
||||
#ifdef FEATURE_IPA_ANDROID
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_TETHER, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6_TETHER, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_TETHER, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6_TETHER, wl);
|
||||
#else
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP_V6, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN_V6, wl);
|
||||
#endif
|
||||
IPACM_EvtDispatcher::registr(IPA_PRIVATE_SUBNET_CHANGE_EVENT, wl); // register for IPA_PRIVATE_SUBNET_CHANGE_EVENT event
|
||||
#ifdef FEATURE_ETH_BRIDGE_LE
|
||||
IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, wl);
|
||||
#endif
|
||||
IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, wl);
|
||||
#ifndef FEATURE_IPA_ANDROID
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_SCC, wl);
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_MCC, wl);
|
||||
#else
|
||||
IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, wl);
|
||||
#endif
|
||||
/* IPA_LAN_DELETE_SELF should be always last */
|
||||
IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, wl);
|
||||
IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance open/registr ok\n", wl->dev_name, wl->ipa_if_num);
|
||||
registr(ipa_interface_index, wl);
|
||||
/* solve the new_addr comes earlier issue */
|
||||
IPACM_Iface::iface_addr_query(if_index);
|
||||
}
|
||||
break;
|
||||
|
||||
case WAN_IF:
|
||||
{
|
||||
if((IPACM_Iface::ipacmcfg->ipacm_odu_enable == false) || (IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true))
|
||||
{
|
||||
IPACMDBG_H("Creating Wan interface\n");
|
||||
IPACM_Wan *w;
|
||||
if(is_sta_mode == WLAN_WAN)
|
||||
{
|
||||
w = new IPACM_Wan(ipa_interface_index, is_sta_mode, param->mac_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
w = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL);
|
||||
}
|
||||
IPACM_EvtDispatcher::registr(IPA_ADDR_ADD_EVENT, w);
|
||||
#ifdef FEATURE_IPA_ANDROID
|
||||
IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, w);
|
||||
IPACM_EvtDispatcher::registr(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, w);
|
||||
if(is_sta_mode == Q6_WAN)
|
||||
{
|
||||
IPACM_EvtDispatcher::registr(IPA_NETWORK_STATS_UPDATE_EVENT, w);
|
||||
};
|
||||
#else/* defined(FEATURE_IPA_ANDROID) */
|
||||
IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, w);
|
||||
IPACM_EvtDispatcher::registr(IPA_ROUTE_DEL_EVENT, w);
|
||||
#endif /* not defined(FEATURE_IPA_ANDROID)*/
|
||||
IPACM_EvtDispatcher::registr(IPA_FIREWALL_CHANGE_EVENT, w);
|
||||
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, w);
|
||||
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_ENABLE, w);
|
||||
IPACM_EvtDispatcher::registr(IPA_SW_ROUTING_DISABLE, w);
|
||||
IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, w); // register for IPA_CFG_CHANGE event
|
||||
IPACM_EvtDispatcher::registr(IPA_WAN_XLAT_CONNECT_EVENT, w);
|
||||
if(is_sta_mode == WLAN_WAN)
|
||||
{
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, w); // for STA mode
|
||||
#ifndef FEATURE_IPA_ANDROID
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_SCC, w);
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_MCC, w);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, w);
|
||||
}
|
||||
|
||||
IPACMDBG_H("ipa_WAN (%s):ipa_index (%d) instance open/registr ok\n", w->dev_name, w->ipa_if_num);
|
||||
registr(ipa_interface_index, w);
|
||||
/* solve the new_addr comes earlier issue */
|
||||
IPACM_Iface::iface_addr_query(if_index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* WAN-eMBMS instance */
|
||||
case EMBMS_IF:
|
||||
{
|
||||
IPACMDBG("Creating Wan-eMBSM interface\n");
|
||||
IPACM_Wan *embms = new IPACM_Wan(ipa_interface_index, is_sta_mode, NULL);
|
||||
IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, embms);
|
||||
IPACMDBG("ipa_WAN (%s):ipa_index (%d) instance open/registr ok\n", embms->dev_name, embms->ipa_if_num);
|
||||
registr(ipa_interface_index, embms);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
IPACMDBG_H("Unhandled interface category received iface name: %s, category: %d\n",
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].if_cat);
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
}
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int IPACM_IfaceManager::registr(int ipa_if_index, IPACM_Listener *obj)
|
||||
{
|
||||
iface_instances *tmp = head,*nw;
|
||||
|
||||
nw = (iface_instances *)malloc(sizeof(iface_instances));
|
||||
if(nw != NULL)
|
||||
{
|
||||
nw->ipa_if_index = ipa_if_index;
|
||||
nw->obj = obj;
|
||||
nw->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
if(head == NULL)
|
||||
{
|
||||
head = nw;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(tmp->next)
|
||||
{
|
||||
tmp = tmp->next;
|
||||
}
|
||||
tmp->next = nw;
|
||||
}
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
int IPACM_IfaceManager::deregistr(IPACM_Listener *param)
|
||||
{
|
||||
iface_instances *tmp = head,*tmp1,*prev = head;
|
||||
|
||||
while(tmp != NULL)
|
||||
{
|
||||
if(tmp->obj == param)
|
||||
{
|
||||
tmp1 = tmp;
|
||||
if(tmp == head)
|
||||
{
|
||||
head = head->next;
|
||||
}
|
||||
else if(tmp->next == NULL)
|
||||
{
|
||||
prev->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev->next = tmp->next;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
free(tmp1);
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int IPACM_IfaceManager::SearchInstance(int ipa_if_index)
|
||||
{
|
||||
|
||||
iface_instances *tmp = head;
|
||||
|
||||
while(tmp != NULL)
|
||||
{
|
||||
if(ipa_if_index == tmp->ipa_if_index)
|
||||
{
|
||||
IPACMDBG_H("Find existed iface-instance name: %s\n",
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_if_index].iface_name);
|
||||
return IPA_INSTANCE_FOUND;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
IPACMDBG_H("No existed iface-instance name: %s,\n",
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_if_index].iface_name);
|
||||
|
||||
return IPA_INSTANCE_NOT_FOUND;
|
||||
}
|
||||
4229
data-ipa-cfg-mgr/ipacm/src/IPACM_Lan.cpp
Normal file
4229
data-ipa-cfg-mgr/ipacm/src/IPACM_Lan.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1262
data-ipa-cfg-mgr/ipacm/src/IPACM_LanToLan.cpp
Normal file
1262
data-ipa-cfg-mgr/ipacm/src/IPACM_LanToLan.cpp
Normal file
File diff suppressed because it is too large
Load Diff
107
data-ipa-cfg-mgr/ipacm/src/IPACM_Log.cpp
Normal file
107
data-ipa-cfg-mgr/ipacm/src/IPACM_Log.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
Copyright (c) 2013, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.
|
||||
*/
|
||||
/*!
|
||||
@file
|
||||
IPACM_log.cpp
|
||||
|
||||
@brief
|
||||
This file implements the IPAM log functionality.
|
||||
|
||||
@Author
|
||||
Skylar Chang
|
||||
|
||||
*/
|
||||
#include "IPACM_Log.h"
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <asm/types.h>
|
||||
#include <linux/if.h>
|
||||
#include <sys/un.h>
|
||||
#include <errno.h>
|
||||
#include <IPACM_Defs.h>
|
||||
|
||||
void logmessage(int log_level)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* start IPACMDIAG socket*/
|
||||
int create_socket(unsigned int *sockfd)
|
||||
{
|
||||
|
||||
if ((*sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == IPACM_FAILURE)
|
||||
{
|
||||
perror("Error creating ipacm_log socket\n");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
if(fcntl(*sockfd, F_SETFD, FD_CLOEXEC) < 0)
|
||||
{
|
||||
perror("Couldn't set ipacm_log Close on Exec\n");
|
||||
}
|
||||
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
void ipacm_log_send( void * user_data)
|
||||
{
|
||||
ipacm_log_buffer_t ipacm_log_buffer;
|
||||
int numBytes=0, len;
|
||||
struct sockaddr_un ipacmlog_socket;
|
||||
static unsigned int ipacm_log_sockfd = 0;
|
||||
|
||||
if(ipacm_log_sockfd == 0)
|
||||
{
|
||||
/* start ipacm_log socket */
|
||||
if(create_socket(&ipacm_log_sockfd) < 0)
|
||||
{
|
||||
printf("unable to create ipacm_log socket\n");
|
||||
return;
|
||||
}
|
||||
printf("create ipacm_log socket successfully\n");
|
||||
}
|
||||
ipacmlog_socket.sun_family = AF_UNIX;
|
||||
strcpy(ipacmlog_socket.sun_path, IPACMLOG_FILE);
|
||||
len = strlen(ipacmlog_socket.sun_path) + sizeof(ipacmlog_socket.sun_family);
|
||||
|
||||
memcpy(ipacm_log_buffer.user_data, user_data, MAX_BUF_LEN);
|
||||
|
||||
//printf("send : %s\n", ipacm_log_buffer.user_data);
|
||||
if ((numBytes = sendto(ipacm_log_sockfd, (void *)&ipacm_log_buffer, sizeof(ipacm_log_buffer.user_data), 0,
|
||||
(struct sockaddr *)&ipacmlog_socket, len)) == -1)
|
||||
{
|
||||
printf("Send Failed(%d) %s \n",errno,strerror(errno));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
939
data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp
Normal file
939
data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp
Normal file
@@ -0,0 +1,939 @@
|
||||
/*
|
||||
Copyright (c) 2013-2016, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.
|
||||
*/
|
||||
/*!
|
||||
@file
|
||||
IPACM_Main.cpp
|
||||
|
||||
@brief
|
||||
This file implements the IPAM functionality.
|
||||
|
||||
@Author
|
||||
Skylar Chang
|
||||
|
||||
*/
|
||||
/******************************************************************************
|
||||
|
||||
IPCM_MAIN.C
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include "linux/ipa_qmi_service_v01.h"
|
||||
|
||||
#include "IPACM_CmdQueue.h"
|
||||
#include "IPACM_EvtDispatcher.h"
|
||||
#include "IPACM_Defs.h"
|
||||
#include "IPACM_Neighbor.h"
|
||||
#include "IPACM_IfaceManager.h"
|
||||
#include "IPACM_Log.h"
|
||||
|
||||
#include "IPACM_ConntrackListener.h"
|
||||
#include "IPACM_ConntrackClient.h"
|
||||
#include "IPACM_Netlink.h"
|
||||
|
||||
/* not defined(FEATURE_IPA_ANDROID)*/
|
||||
#ifndef FEATURE_IPA_ANDROID
|
||||
#include "IPACM_LanToLan.h"
|
||||
#endif
|
||||
|
||||
#define IPA_DRIVER "/dev/ipa"
|
||||
|
||||
#define IPACM_FIREWALL_FILE_NAME "mobileap_firewall.xml"
|
||||
#define IPACM_CFG_FILE_NAME "IPACM_cfg.xml"
|
||||
#ifdef FEATURE_IPA_ANDROID
|
||||
#define IPACM_PID_FILE "/data/misc/ipa/ipacm.pid"
|
||||
#define IPACM_DIR_NAME "/data"
|
||||
#else/* defined(FEATURE_IPA_ANDROID) */
|
||||
#define IPACM_PID_FILE "/etc/ipacm.pid"
|
||||
#define IPACM_DIR_NAME "/etc"
|
||||
#endif /* defined(NOT FEATURE_IPA_ANDROID)*/
|
||||
#define IPACM_NAME "ipacm"
|
||||
|
||||
#define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
|
||||
#define INOTIFY_BUF_LEN (INOTIFY_EVENT_SIZE + 2*sizeof(IPACM_FIREWALL_FILE_NAME))
|
||||
|
||||
#define IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS 3
|
||||
#define IPA_DRIVER_WLAN_EVENT_SIZE (sizeof(struct ipa_wlan_msg_ex)+ IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS*sizeof(ipa_wlan_hdr_attrib_val))
|
||||
#define IPA_DRIVER_PIPE_STATS_EVENT_SIZE (sizeof(struct ipa_get_data_stats_resp_msg_v01))
|
||||
#define IPA_DRIVER_WLAN_META_MSG (sizeof(struct ipa_msg_meta))
|
||||
#define IPA_DRIVER_WLAN_BUF_LEN (IPA_DRIVER_PIPE_STATS_EVENT_SIZE + IPA_DRIVER_WLAN_META_MSG)
|
||||
|
||||
uint32_t ipacm_event_stats[IPACM_EVENT_MAX];
|
||||
bool ipacm_logging = true;
|
||||
|
||||
void ipa_is_ipacm_running(void);
|
||||
int ipa_get_if_index(char *if_name, int *if_index);
|
||||
|
||||
/* start netlink socket monitor*/
|
||||
void* netlink_start(void *param)
|
||||
{
|
||||
ipa_nl_sk_fd_set_info_t sk_fdset;
|
||||
int ret_val = 0;
|
||||
memset(&sk_fdset, 0, sizeof(ipa_nl_sk_fd_set_info_t));
|
||||
IPACMDBG_H("netlink starter memset sk_fdset succeeds\n");
|
||||
ret_val = ipa_nl_listener_init(NETLINK_ROUTE, (RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_LINK |
|
||||
RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NEIGH |
|
||||
RTNLGRP_IPV6_PREFIX),
|
||||
&sk_fdset, ipa_nl_recv_msg);
|
||||
|
||||
if (ret_val != IPACM_SUCCESS)
|
||||
{
|
||||
IPACMERR("Failed to initialize IPA netlink event listener\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* start firewall-rule monitor*/
|
||||
void* firewall_monitor(void *param)
|
||||
{
|
||||
int length;
|
||||
int wd;
|
||||
char buffer[INOTIFY_BUF_LEN];
|
||||
int inotify_fd;
|
||||
ipacm_cmd_q_data evt_data;
|
||||
uint32_t mask = IN_MODIFY | IN_MOVE;
|
||||
|
||||
inotify_fd = inotify_init();
|
||||
if (inotify_fd < 0)
|
||||
{
|
||||
PERROR("inotify_init");
|
||||
}
|
||||
|
||||
IPACMDBG_H("Waiting for nofications in dir %s with mask: 0x%x\n", IPACM_DIR_NAME, mask);
|
||||
|
||||
wd = inotify_add_watch(inotify_fd,
|
||||
IPACM_DIR_NAME,
|
||||
mask);
|
||||
|
||||
while (1)
|
||||
{
|
||||
length = read(inotify_fd, buffer, INOTIFY_BUF_LEN);
|
||||
if (length < 0)
|
||||
{
|
||||
IPACMERR("inotify read() error return length: %d and mask: 0x%x\n", length, mask);
|
||||
continue;
|
||||
}
|
||||
|
||||
struct inotify_event* event;
|
||||
event = (struct inotify_event*)malloc(length);
|
||||
if(event == NULL)
|
||||
{
|
||||
IPACMERR("Failed to allocate memory.\n");
|
||||
return NULL;
|
||||
}
|
||||
memset(event, 0, length);
|
||||
memcpy(event, buffer, length);
|
||||
|
||||
if (event->len > 0)
|
||||
{
|
||||
if ( (event->mask & IN_MODIFY) || (event->mask & IN_MOVE))
|
||||
{
|
||||
if (event->mask & IN_ISDIR)
|
||||
{
|
||||
IPACMDBG_H("The directory %s was 0x%x\n", event->name, event->mask);
|
||||
}
|
||||
else if (!strncmp(event->name, IPACM_FIREWALL_FILE_NAME, event->len)) // firewall_rule change
|
||||
{
|
||||
IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask);
|
||||
IPACMDBG_H("The interested file %s .\n", IPACM_FIREWALL_FILE_NAME);
|
||||
|
||||
evt_data.event = IPA_FIREWALL_CHANGE_EVENT;
|
||||
evt_data.evt_data = NULL;
|
||||
|
||||
/* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
}
|
||||
else if (!strncmp(event->name, IPACM_CFG_FILE_NAME, event->len)) // IPACM_configuration change
|
||||
{
|
||||
IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask);
|
||||
IPACMDBG_H("The interested file %s .\n", IPACM_CFG_FILE_NAME);
|
||||
|
||||
evt_data.event = IPA_CFG_CHANGE_EVENT;
|
||||
evt_data.evt_data = NULL;
|
||||
|
||||
/* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
}
|
||||
}
|
||||
IPACMDBG_H("Received monitoring event %s.\n", event->name);
|
||||
}
|
||||
free(event);
|
||||
}
|
||||
|
||||
(void)inotify_rm_watch(inotify_fd, wd);
|
||||
(void)close(inotify_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* start IPACM wan-driver notifier */
|
||||
void* ipa_driver_msg_notifier(void *param)
|
||||
{
|
||||
int length, fd, cnt;
|
||||
char buffer[IPA_DRIVER_WLAN_BUF_LEN];
|
||||
struct ipa_msg_meta event_hdr;
|
||||
struct ipa_ecm_msg event_ecm;
|
||||
struct ipa_wan_msg event_wan;
|
||||
struct ipa_wlan_msg_ex event_ex_o;
|
||||
struct ipa_wlan_msg *event_wlan=NULL;
|
||||
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;
|
||||
|
||||
ipacm_cmd_q_data evt_data;
|
||||
ipacm_event_data_mac *data = NULL;
|
||||
ipacm_event_data_fid *data_fid = NULL;
|
||||
ipacm_event_data_iptype *data_iptype = NULL;
|
||||
ipacm_event_data_wlan_ex *data_ex;
|
||||
ipa_get_data_stats_resp_msg_v01 *data_tethering_stats = NULL;
|
||||
ipa_get_apn_data_stats_resp_msg_v01 *data_network_stats = NULL;
|
||||
|
||||
ipacm_cmd_q_data new_neigh_evt;
|
||||
ipacm_event_data_all* new_neigh_data;
|
||||
|
||||
fd = open(IPA_DRIVER, O_RDWR);
|
||||
if (fd < 0)
|
||||
{
|
||||
IPACMERR("Failed opening %s.\n", IPA_DRIVER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
IPACMDBG_H("Waiting for nofications from IPA driver \n");
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
memset(&evt_data, 0, sizeof(evt_data));
|
||||
memset(&new_neigh_evt, 0, sizeof(ipacm_cmd_q_data));
|
||||
new_neigh_data = NULL;
|
||||
data = NULL;
|
||||
data_fid = NULL;
|
||||
data_tethering_stats = NULL;
|
||||
data_network_stats = NULL;
|
||||
|
||||
length = read(fd, buffer, IPA_DRIVER_WLAN_BUF_LEN);
|
||||
if (length < 0)
|
||||
{
|
||||
PERROR("didn't read IPA_driver correctly");
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(&event_hdr, buffer,sizeof(struct ipa_msg_meta));
|
||||
IPACMDBG_H("Message type: %d\n", event_hdr.msg_type);
|
||||
IPACMDBG_H("Event header length received: %d\n",event_hdr.msg_len);
|
||||
|
||||
/* Insert WLAN_DRIVER_EVENT to command queue */
|
||||
switch (event_hdr.msg_type)
|
||||
{
|
||||
|
||||
case SW_ROUTING_ENABLE:
|
||||
IPACMDBG_H("Received SW_ROUTING_ENABLE\n");
|
||||
evt_data.event = IPA_SW_ROUTING_ENABLE;
|
||||
IPACMDBG_H("Not supported anymore\n");
|
||||
continue;
|
||||
|
||||
case SW_ROUTING_DISABLE:
|
||||
IPACMDBG_H("Received SW_ROUTING_DISABLE\n");
|
||||
evt_data.event = IPA_SW_ROUTING_DISABLE;
|
||||
IPACMDBG_H("Not supported anymore\n");
|
||||
continue;
|
||||
|
||||
case WLAN_AP_CONNECT:
|
||||
event_wlan = (struct ipa_wlan_msg *) (buffer + sizeof(struct ipa_msg_meta));
|
||||
IPACMDBG_H("Received WLAN_AP_CONNECT name: %s\n",event_wlan->name);
|
||||
IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
|
||||
event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
|
||||
data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
|
||||
if(data_fid == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event_wlan data_fid\n");
|
||||
return NULL;
|
||||
}
|
||||
ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
|
||||
evt_data.event = IPA_WLAN_AP_LINK_UP_EVENT;
|
||||
evt_data.evt_data = data_fid;
|
||||
break;
|
||||
|
||||
case WLAN_AP_DISCONNECT:
|
||||
event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
|
||||
IPACMDBG_H("Received WLAN_AP_DISCONNECT name: %s\n",event_wlan->name);
|
||||
IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
|
||||
event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
|
||||
data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
|
||||
if(data_fid == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event_wlan data_fid\n");
|
||||
return NULL;
|
||||
}
|
||||
ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
|
||||
evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
|
||||
evt_data.evt_data = data_fid;
|
||||
break;
|
||||
case WLAN_STA_CONNECT:
|
||||
event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
|
||||
IPACMDBG_H("Received WLAN_STA_CONNECT name: %s\n",event_wlan->name);
|
||||
IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
|
||||
event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
|
||||
data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
|
||||
if(data == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event_wlan data_fid\n");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(data->mac_addr,
|
||||
event_wlan->mac_addr,
|
||||
sizeof(event_wlan->mac_addr));
|
||||
ipa_get_if_index(event_wlan->name, &(data->if_index));
|
||||
evt_data.event = IPA_WLAN_STA_LINK_UP_EVENT;
|
||||
evt_data.evt_data = data;
|
||||
break;
|
||||
|
||||
case WLAN_STA_DISCONNECT:
|
||||
event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
|
||||
IPACMDBG_H("Received WLAN_STA_DISCONNECT name: %s\n",event_wlan->name);
|
||||
IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
|
||||
event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
|
||||
data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
|
||||
if(data_fid == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event_wlan data_fid\n");
|
||||
return NULL;
|
||||
}
|
||||
ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
|
||||
evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
|
||||
evt_data.evt_data = data_fid;
|
||||
break;
|
||||
|
||||
case WLAN_CLIENT_CONNECT:
|
||||
event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
|
||||
IPACMDBG_H("Received WLAN_CLIENT_CONNECT\n");
|
||||
IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
|
||||
event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
|
||||
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 NULL;
|
||||
}
|
||||
memcpy(data->mac_addr,
|
||||
event_wlan->mac_addr,
|
||||
sizeof(event_wlan->mac_addr));
|
||||
ipa_get_if_index(event_wlan->name, &(data->if_index));
|
||||
evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT;
|
||||
evt_data.evt_data = data;
|
||||
break;
|
||||
|
||||
case WLAN_CLIENT_CONNECT_EX:
|
||||
IPACMDBG_H("Received WLAN_CLIENT_CONNECT_EX\n");
|
||||
|
||||
memcpy(&event_ex_o, buffer + sizeof(struct ipa_msg_meta),sizeof(struct ipa_wlan_msg_ex));
|
||||
if(event_ex_o.num_of_attribs > IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS)
|
||||
{
|
||||
IPACMERR("buffer size overflow\n");
|
||||
return NULL;
|
||||
}
|
||||
length = sizeof(ipa_wlan_msg_ex)+ event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val);
|
||||
IPACMDBG_H("num_of_attribs %d, length %d\n", event_ex_o.num_of_attribs, length);
|
||||
event_ex = (ipa_wlan_msg_ex *)malloc(length);
|
||||
if(event_ex == NULL )
|
||||
{
|
||||
IPACMERR("Unable to allocate memory\n");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(event_ex, buffer + sizeof(struct ipa_msg_meta), length);
|
||||
data_ex = (ipacm_event_data_wlan_ex *)malloc(sizeof(ipacm_event_data_wlan_ex) + event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val));
|
||||
if (data_ex == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event data\n");
|
||||
return NULL;
|
||||
}
|
||||
data_ex->num_of_attribs = event_ex->num_of_attribs;
|
||||
|
||||
memcpy(data_ex->attribs,
|
||||
event_ex->attribs,
|
||||
event_ex->num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val));
|
||||
|
||||
ipa_get_if_index(event_ex->name, &(data_ex->if_index));
|
||||
evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT_EX;
|
||||
evt_data.evt_data = data_ex;
|
||||
|
||||
/* Construct new_neighbor msg with netdev device internally */
|
||||
new_neigh_data = (ipacm_event_data_all*)malloc(sizeof(ipacm_event_data_all));
|
||||
if(new_neigh_data == NULL)
|
||||
{
|
||||
IPACMERR("Failed to allocate memory.\n");
|
||||
return NULL;
|
||||
}
|
||||
memset(new_neigh_data, 0, sizeof(ipacm_event_data_all));
|
||||
new_neigh_data->iptype = IPA_IP_v6;
|
||||
for(cnt = 0; cnt < event_ex->num_of_attribs; cnt++)
|
||||
{
|
||||
if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
|
||||
{
|
||||
memcpy(new_neigh_data->mac_addr, event_ex->attribs[cnt].u.mac_addr, sizeof(new_neigh_data->mac_addr));
|
||||
IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
event_ex->attribs[cnt].u.mac_addr[0], event_ex->attribs[cnt].u.mac_addr[1], event_ex->attribs[cnt].u.mac_addr[2],
|
||||
event_ex->attribs[cnt].u.mac_addr[3], event_ex->attribs[cnt].u.mac_addr[4], event_ex->attribs[cnt].u.mac_addr[5]);
|
||||
}
|
||||
else if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
|
||||
{
|
||||
IPACMDBG_H("Wlan client id %d\n",event_ex->attribs[cnt].u.sta_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG_H("Wlan message has unexpected type!\n");
|
||||
}
|
||||
}
|
||||
new_neigh_data->if_index = data_ex->if_index;
|
||||
new_neigh_evt.evt_data = (void*)new_neigh_data;
|
||||
new_neigh_evt.event = IPA_NEW_NEIGH_EVENT;
|
||||
free(event_ex);
|
||||
break;
|
||||
|
||||
case WLAN_CLIENT_DISCONNECT:
|
||||
IPACMDBG_H("Received WLAN_CLIENT_DISCONNECT\n");
|
||||
event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
|
||||
IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
|
||||
event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
|
||||
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 NULL;
|
||||
}
|
||||
memcpy(data->mac_addr,
|
||||
event_wlan->mac_addr,
|
||||
sizeof(event_wlan->mac_addr));
|
||||
ipa_get_if_index(event_wlan->name, &(data->if_index));
|
||||
evt_data.event = IPA_WLAN_CLIENT_DEL_EVENT;
|
||||
evt_data.evt_data = data;
|
||||
break;
|
||||
|
||||
case WLAN_CLIENT_POWER_SAVE_MODE:
|
||||
IPACMDBG_H("Received WLAN_CLIENT_POWER_SAVE_MODE\n");
|
||||
event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
|
||||
IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
|
||||
event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
|
||||
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 NULL;
|
||||
}
|
||||
memcpy(data->mac_addr,
|
||||
event_wlan->mac_addr,
|
||||
sizeof(event_wlan->mac_addr));
|
||||
ipa_get_if_index(event_wlan->name, &(data->if_index));
|
||||
evt_data.event = IPA_WLAN_CLIENT_POWER_SAVE_EVENT;
|
||||
evt_data.evt_data = data;
|
||||
break;
|
||||
|
||||
case WLAN_CLIENT_NORMAL_MODE:
|
||||
IPACMDBG_H("Received WLAN_CLIENT_NORMAL_MODE\n");
|
||||
event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
|
||||
IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
|
||||
event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
|
||||
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 NULL;
|
||||
}
|
||||
memcpy(data->mac_addr,
|
||||
event_wlan->mac_addr,
|
||||
sizeof(event_wlan->mac_addr));
|
||||
ipa_get_if_index(event_wlan->name, &(data->if_index));
|
||||
evt_data.evt_data = data;
|
||||
evt_data.event = IPA_WLAN_CLIENT_RECOVER_EVENT;
|
||||
break;
|
||||
|
||||
case ECM_CONNECT:
|
||||
memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
|
||||
IPACMDBG_H("Received ECM_CONNECT name: %s\n",event_ecm.name);
|
||||
data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
|
||||
if(data_fid == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event_ecm data_fid\n");
|
||||
return NULL;
|
||||
}
|
||||
data_fid->if_index = event_ecm.ifindex;
|
||||
evt_data.event = IPA_USB_LINK_UP_EVENT;
|
||||
evt_data.evt_data = data_fid;
|
||||
break;
|
||||
|
||||
case ECM_DISCONNECT:
|
||||
memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
|
||||
IPACMDBG_H("Received ECM_DISCONNECT name: %s\n",event_ecm.name);
|
||||
data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
|
||||
if(data_fid == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event_ecm data_fid\n");
|
||||
return NULL;
|
||||
}
|
||||
data_fid->if_index = event_ecm.ifindex;
|
||||
evt_data.event = IPA_LINK_DOWN_EVENT;
|
||||
evt_data.evt_data = data_fid;
|
||||
break;
|
||||
/* Add for 8994 Android case */
|
||||
case WAN_UPSTREAM_ROUTE_ADD:
|
||||
memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
|
||||
IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
|
||||
data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
|
||||
if(data_iptype == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
|
||||
return NULL;
|
||||
}
|
||||
ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
|
||||
ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
|
||||
data_iptype->iptype = event_wan.ip;
|
||||
#ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
|
||||
data_iptype->ipv4_addr_gw = event_wan.ipv4_addr_gw;
|
||||
data_iptype->ipv6_addr_gw[0] = event_wan.ipv6_addr_gw[0];
|
||||
data_iptype->ipv6_addr_gw[1] = event_wan.ipv6_addr_gw[1];
|
||||
data_iptype->ipv6_addr_gw[2] = event_wan.ipv6_addr_gw[2];
|
||||
data_iptype->ipv6_addr_gw[3] = event_wan.ipv6_addr_gw[3];
|
||||
IPACMDBG_H("default gw ipv4 (%x)\n", data_iptype->ipv4_addr_gw);
|
||||
IPACMDBG_H("IPV6 gateway: %08x:%08x:%08x:%08x \n",
|
||||
data_iptype->ipv6_addr_gw[0], data_iptype->ipv6_addr_gw[1], data_iptype->ipv6_addr_gw[2], data_iptype->ipv6_addr_gw[3]);
|
||||
#endif
|
||||
IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) tether_fid(%d) ip-type(%d)\n", data_iptype->if_index,
|
||||
data_iptype->if_index_tether, data_iptype->iptype);
|
||||
evt_data.event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
|
||||
evt_data.evt_data = data_iptype;
|
||||
break;
|
||||
case WAN_UPSTREAM_ROUTE_DEL:
|
||||
memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
|
||||
IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
|
||||
data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
|
||||
if(data_iptype == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
|
||||
return NULL;
|
||||
}
|
||||
ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
|
||||
ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
|
||||
data_iptype->iptype = event_wan.ip;
|
||||
IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL: fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->iptype);
|
||||
evt_data.event = IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT;
|
||||
evt_data.evt_data = data_iptype;
|
||||
break;
|
||||
/* End of adding for 8994 Android case */
|
||||
|
||||
/* Add for embms case */
|
||||
case WAN_EMBMS_CONNECT:
|
||||
memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
|
||||
IPACMDBG("Received WAN_EMBMS_CONNECT name: %s\n",event_wan.upstream_ifname);
|
||||
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 NULL;
|
||||
}
|
||||
ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
|
||||
evt_data.event = IPA_WAN_EMBMS_LINK_UP_EVENT;
|
||||
evt_data.evt_data = data_fid;
|
||||
break;
|
||||
|
||||
case WLAN_SWITCH_TO_SCC:
|
||||
IPACMDBG_H("Received WLAN_SWITCH_TO_SCC\n");
|
||||
case WLAN_WDI_ENABLE:
|
||||
IPACMDBG_H("Received WLAN_WDI_ENABLE\n");
|
||||
if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
|
||||
{
|
||||
IPACM_Iface::ipacmcfg->isMCC_Mode = false;
|
||||
evt_data.event = IPA_WLAN_SWITCH_TO_SCC;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case WLAN_SWITCH_TO_MCC:
|
||||
IPACMDBG_H("Received WLAN_SWITCH_TO_MCC\n");
|
||||
case WLAN_WDI_DISABLE:
|
||||
IPACMDBG_H("Received WLAN_WDI_DISABLE\n");
|
||||
if (IPACM_Iface::ipacmcfg->isMCC_Mode == false)
|
||||
{
|
||||
IPACM_Iface::ipacmcfg->isMCC_Mode = true;
|
||||
evt_data.event = IPA_WLAN_SWITCH_TO_MCC;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
|
||||
case WAN_XLAT_CONNECT:
|
||||
memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta),
|
||||
sizeof(struct ipa_wan_msg));
|
||||
IPACMDBG_H("Received WAN_XLAT_CONNECT name: %s\n",
|
||||
event_wan.upstream_ifname);
|
||||
|
||||
/* post IPA_LINK_UP_EVENT event
|
||||
* may be WAN interface is not up
|
||||
*/
|
||||
data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
|
||||
if(data_fid == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for xlat event\n");
|
||||
return NULL;
|
||||
}
|
||||
ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
|
||||
evt_data.event = IPA_LINK_UP_EVENT;
|
||||
evt_data.evt_data = data_fid;
|
||||
IPACMDBG_H("Posting IPA_LINK_UP_EVENT event:%d\n", evt_data.event);
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
|
||||
/* post IPA_WAN_XLAT_CONNECT_EVENT event */
|
||||
memset(&evt_data, 0, sizeof(evt_data));
|
||||
data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
|
||||
if(data_fid == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for xlat event\n");
|
||||
return NULL;
|
||||
}
|
||||
ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
|
||||
evt_data.event = IPA_WAN_XLAT_CONNECT_EVENT;
|
||||
evt_data.evt_data = data_fid;
|
||||
IPACMDBG_H("Posting IPA_WAN_XLAT_CONNECT_EVENT event:%d\n", evt_data.event);
|
||||
break;
|
||||
|
||||
case IPA_TETHERING_STATS_UPDATE_STATS:
|
||||
memcpy(&event_data_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_data_stats_resp_msg_v01));
|
||||
data_tethering_stats = (ipa_get_data_stats_resp_msg_v01 *)malloc(sizeof(struct ipa_get_data_stats_resp_msg_v01));
|
||||
if(data_tethering_stats == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event data_tethering_stats\n");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(data_tethering_stats,
|
||||
&event_data_stats,
|
||||
sizeof(struct ipa_get_data_stats_resp_msg_v01));
|
||||
IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data_tethering_stats->ipa_stats_type);
|
||||
IPACMDBG("Received %d UL, %d DL pipe stats\n",data_tethering_stats->ul_src_pipe_stats_list_len, data_tethering_stats->dl_dst_pipe_stats_list_len);
|
||||
evt_data.event = IPA_TETHERING_STATS_UPDATE_EVENT;
|
||||
evt_data.evt_data = data_tethering_stats;
|
||||
break;
|
||||
|
||||
case IPA_TETHERING_STATS_UPDATE_NETWORK_STATS:
|
||||
memcpy(&event_network_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
|
||||
data_network_stats = (ipa_get_apn_data_stats_resp_msg_v01 *)malloc(sizeof(ipa_get_apn_data_stats_resp_msg_v01));
|
||||
if(data_network_stats == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for event data_network_stats\n");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(data_network_stats,
|
||||
&event_network_stats,
|
||||
sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
|
||||
IPACMDBG("Received %d apn network stats \n", data_network_stats->apn_data_stats_list_len);
|
||||
evt_data.event = IPA_NETWORK_STATS_UPDATE_EVENT;
|
||||
evt_data.evt_data = data_network_stats;
|
||||
break;
|
||||
|
||||
default:
|
||||
IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type);
|
||||
continue;
|
||||
|
||||
}
|
||||
/* finish command queue */
|
||||
IPACMDBG_H("Posting event:%d\n", evt_data.event);
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
/* push new_neighbor with netdev device internally */
|
||||
if(new_neigh_data != NULL)
|
||||
{
|
||||
IPACMDBG_H("Internally post event IPA_NEW_NEIGH_EVENT\n");
|
||||
IPACM_EvtDispatcher::PostEvt(&new_neigh_evt);
|
||||
}
|
||||
}
|
||||
|
||||
(void)close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void IPACM_Sig_Handler(int sig)
|
||||
{
|
||||
int cnt;
|
||||
ipacm_cmd_q_data evt_data;
|
||||
|
||||
printf("Received Signal: %d\n", sig);
|
||||
memset(&evt_data, 0, sizeof(evt_data));
|
||||
|
||||
switch(sig)
|
||||
{
|
||||
case SIGUSR1:
|
||||
IPACMDBG_H("Received SW_ROUTING_ENABLE request \n");
|
||||
evt_data.event = IPA_SW_ROUTING_ENABLE;
|
||||
IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = true;
|
||||
break;
|
||||
|
||||
case SIGUSR2:
|
||||
IPACMDBG_H("Received SW_ROUTING_DISABLE request \n");
|
||||
evt_data.event = IPA_SW_ROUTING_DISABLE;
|
||||
IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = false;
|
||||
break;
|
||||
}
|
||||
/* finish command queue */
|
||||
IPACMDBG_H("Posting event:%d\n", evt_data.event);
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
return;
|
||||
}
|
||||
|
||||
void RegisterForSignals(void)
|
||||
{
|
||||
|
||||
signal(SIGUSR1, IPACM_Sig_Handler);
|
||||
signal(SIGUSR2, IPACM_Sig_Handler);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
pthread_t netlink_thread = 0, monitor_thread = 0, ipa_driver_thread = 0;
|
||||
pthread_t cmd_queue_thread = 0;
|
||||
|
||||
/* check if ipacm is already running or not */
|
||||
ipa_is_ipacm_running();
|
||||
|
||||
IPACMDBG_H("In main()\n");
|
||||
IPACM_Neighbor *neigh = new IPACM_Neighbor();
|
||||
IPACM_IfaceManager *ifacemgr = new IPACM_IfaceManager();
|
||||
|
||||
#ifdef FEATURE_ETH_BRIDGE_LE
|
||||
IPACM_LanToLan* lan2lan = new IPACM_LanToLan();
|
||||
#endif
|
||||
|
||||
IPACM_ConntrackClient *cc = IPACM_ConntrackClient::GetInstance();
|
||||
CtList = new IPACM_ConntrackListener();
|
||||
|
||||
IPACMDBG_H("Staring IPA main\n");
|
||||
IPACMDBG_H("ipa_cmdq_successful\n");
|
||||
|
||||
|
||||
RegisterForSignals();
|
||||
|
||||
if (IPACM_SUCCESS == cmd_queue_thread)
|
||||
{
|
||||
ret = pthread_create(&cmd_queue_thread, NULL, MessageQueue::Process, NULL);
|
||||
if (IPACM_SUCCESS != ret)
|
||||
{
|
||||
IPACMERR("unable to command queue thread\n");
|
||||
return ret;
|
||||
}
|
||||
IPACMDBG_H("created command queue thread\n");
|
||||
if(pthread_setname_np(cmd_queue_thread, "cmd queue process") != 0)
|
||||
{
|
||||
IPACMERR("unable to set thread name\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (IPACM_SUCCESS == netlink_thread)
|
||||
{
|
||||
ret = pthread_create(&netlink_thread, NULL, netlink_start, NULL);
|
||||
if (IPACM_SUCCESS != ret)
|
||||
{
|
||||
IPACMERR("unable to create netlink thread\n");
|
||||
return ret;
|
||||
}
|
||||
IPACMDBG_H("created netlink thread\n");
|
||||
if(pthread_setname_np(netlink_thread, "netlink socket") != 0)
|
||||
{
|
||||
IPACMERR("unable to set thread name\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable Firewall support only on MDM targets */
|
||||
#ifndef FEATURE_IPA_ANDROID
|
||||
if (IPACM_SUCCESS == monitor_thread)
|
||||
{
|
||||
ret = pthread_create(&monitor_thread, NULL, firewall_monitor, NULL);
|
||||
if (IPACM_SUCCESS != ret)
|
||||
{
|
||||
IPACMERR("unable to create monitor thread\n");
|
||||
return ret;
|
||||
}
|
||||
IPACMDBG_H("created firewall monitor thread\n");
|
||||
if(pthread_setname_np(monitor_thread, "firewall cfg process") != 0)
|
||||
{
|
||||
IPACMERR("unable to set thread name\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IPACM_SUCCESS == ipa_driver_thread)
|
||||
{
|
||||
ret = pthread_create(&ipa_driver_thread, NULL, ipa_driver_msg_notifier, NULL);
|
||||
if (IPACM_SUCCESS != ret)
|
||||
{
|
||||
IPACMERR("unable to create ipa_driver_wlan thread\n");
|
||||
return ret;
|
||||
}
|
||||
IPACMDBG_H("created ipa_driver_wlan thread\n");
|
||||
if(pthread_setname_np(ipa_driver_thread, "ipa driver ntfy") != 0)
|
||||
{
|
||||
IPACMERR("unable to set thread name\n");
|
||||
}
|
||||
}
|
||||
|
||||
pthread_join(cmd_queue_thread, NULL);
|
||||
pthread_join(netlink_thread, NULL);
|
||||
pthread_join(monitor_thread, NULL);
|
||||
pthread_join(ipa_driver_thread, NULL);
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION ipa_is_ipacm_running
|
||||
===========================================================================*/
|
||||
/*!
|
||||
@brief
|
||||
Determine whether there's already an IPACM process running, if so, terminate
|
||||
the current one
|
||||
|
||||
@return
|
||||
None
|
||||
|
||||
@note
|
||||
|
||||
- Dependencies
|
||||
- None
|
||||
|
||||
- Side Effects
|
||||
- None
|
||||
*/
|
||||
/*=========================================================================*/
|
||||
|
||||
void ipa_is_ipacm_running(void) {
|
||||
|
||||
int fd;
|
||||
struct flock lock;
|
||||
int retval;
|
||||
|
||||
fd = open(IPACM_PID_FILE, O_RDWR | O_CREAT, 0600);
|
||||
if ( fd <= 0 )
|
||||
{
|
||||
IPACMERR("Failed to open %s, error is %d - %s\n",
|
||||
IPACM_PID_FILE, errno, strerror(errno));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Getting an exclusive Write lock on the file, if it fails,
|
||||
* it means that another instance of IPACM is running and it
|
||||
* got the lock before us.
|
||||
*/
|
||||
memset(&lock, 0, sizeof(lock));
|
||||
lock.l_type = F_WRLCK;
|
||||
retval = fcntl(fd, F_SETLK, &lock);
|
||||
|
||||
if (retval != 0)
|
||||
{
|
||||
retval = fcntl(fd, F_GETLK, &lock);
|
||||
if (retval == 0)
|
||||
{
|
||||
IPACMERR("Unable to get lock on file %s (my PID %d), PID %d already has it\n",
|
||||
IPACM_PID_FILE, getpid(), lock.l_pid);
|
||||
close(fd);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMERR("PID %d is IPACM main process\n", getpid());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
FUNCTION ipa_get_if_index
|
||||
===========================================================================*/
|
||||
/*!
|
||||
@brief
|
||||
get ipa interface index by given the interface name
|
||||
|
||||
@return
|
||||
IPACM_SUCCESS or IPA_FALUIRE
|
||||
|
||||
@note
|
||||
|
||||
- Dependencies
|
||||
- None
|
||||
|
||||
- Side Effects
|
||||
- None
|
||||
*/
|
||||
/*=========================================================================*/
|
||||
int ipa_get_if_index
|
||||
(
|
||||
char *if_name,
|
||||
int *if_index
|
||||
)
|
||||
{
|
||||
int fd;
|
||||
struct ifreq ifr;
|
||||
|
||||
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
{
|
||||
PERROR("get interface index socket create failed");
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
|
||||
(void)strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
|
||||
|
||||
if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
|
||||
{
|
||||
IPACMERR("call_ioctl_on_dev: ioctl failed: can't find device %s",if_name);
|
||||
*if_index = -1;
|
||||
close(fd);
|
||||
return IPACM_FAILURE;
|
||||
}
|
||||
|
||||
*if_index = ifr.ifr_ifindex;
|
||||
close(fd);
|
||||
return IPACM_SUCCESS;
|
||||
}
|
||||
570
data-ipa-cfg-mgr/ipacm/src/IPACM_Neighbor.cpp
Normal file
570
data-ipa-cfg-mgr/ipacm/src/IPACM_Neighbor.cpp
Normal file
@@ -0,0 +1,570 @@
|
||||
/*
|
||||
Copyright (c) 2013, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.
|
||||
*/
|
||||
/*!
|
||||
@file
|
||||
IPACM_Neighbor.cpp
|
||||
|
||||
@brief
|
||||
This file implements the functionality of handling IPACM Neighbor events.
|
||||
|
||||
@Author
|
||||
Skylar Chang
|
||||
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <IPACM_Neighbor.h>
|
||||
#include <IPACM_EvtDispatcher.h>
|
||||
#include "IPACM_Defs.h"
|
||||
#include "IPACM_Log.h"
|
||||
|
||||
|
||||
IPACM_Neighbor::IPACM_Neighbor()
|
||||
{
|
||||
num_neighbor_client = 0;
|
||||
circular_index = 0;
|
||||
memset(neighbor_client, 0, IPA_MAX_NUM_NEIGHBOR_CLIENTS * sizeof(ipa_neighbor_client));
|
||||
IPACM_EvtDispatcher::registr(IPA_WLAN_CLIENT_ADD_EVENT_EX, this);
|
||||
IPACM_EvtDispatcher::registr(IPA_NEW_NEIGH_EVENT, this);
|
||||
IPACM_EvtDispatcher::registr(IPA_DEL_NEIGH_EVENT, this);
|
||||
return;
|
||||
}
|
||||
|
||||
void IPACM_Neighbor::event_callback(ipa_cm_event_id event, void *param)
|
||||
{
|
||||
ipacm_event_data_all *data_all = NULL;
|
||||
int i, ipa_interface_index;
|
||||
ipacm_cmd_q_data evt_data;
|
||||
int num_neighbor_client_temp = num_neighbor_client;
|
||||
|
||||
IPACMDBG("Recieved event %d\n", event);
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case IPA_WLAN_CLIENT_ADD_EVENT_EX:
|
||||
{
|
||||
ipacm_event_data_wlan_ex *data = (ipacm_event_data_wlan_ex *)param;
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index);
|
||||
/* check for failure return */
|
||||
if (IPACM_FAILURE == ipa_interface_index) {
|
||||
IPACMERR("IPA_WLAN_CLIENT_ADD_EVENT_EX: not supported iface id: %d\n", data->if_index);
|
||||
break;
|
||||
}
|
||||
uint8_t client_mac_addr[6];
|
||||
|
||||
IPACMDBG_H("Received IPA_WLAN_CLIENT_ADD_EVENT\n");
|
||||
for(i = 0; i < data->num_of_attribs; i++)
|
||||
{
|
||||
if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
|
||||
{
|
||||
memcpy(client_mac_addr,
|
||||
data->attribs[i].u.mac_addr,
|
||||
sizeof(client_mac_addr));
|
||||
IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
client_mac_addr[0], client_mac_addr[1], client_mac_addr[2],
|
||||
client_mac_addr[3], client_mac_addr[4], client_mac_addr[5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG_H("The attribute type is not expected!\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_neighbor_client_temp; i++)
|
||||
{
|
||||
/* find the client */
|
||||
if (memcmp(neighbor_client[i].mac_addr, client_mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
|
||||
{
|
||||
/* check if iface is not bridge interface*/
|
||||
if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0)
|
||||
{
|
||||
/* use previous ipv4 first */
|
||||
if(data->if_index != neighbor_client[i].iface_index)
|
||||
{
|
||||
IPACMERR("update new kernel iface index \n");
|
||||
neighbor_client[i].iface_index = data->if_index;
|
||||
}
|
||||
|
||||
/* check if client associated with previous network interface */
|
||||
if(ipa_interface_index != neighbor_client[i].ipa_if_num)
|
||||
{
|
||||
IPACMERR("client associate to different AP \n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (neighbor_client[i].v4_addr != 0) /* not 0.0.0.0 */
|
||||
{
|
||||
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
|
||||
data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
|
||||
if (data_all == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate memory\n");
|
||||
return;
|
||||
}
|
||||
data_all->iptype = IPA_IP_v4;
|
||||
data_all->if_index = neighbor_client[i].iface_index;
|
||||
data_all->ipv4_addr = neighbor_client[i].v4_addr; //use previous ipv4 address
|
||||
memcpy(data_all->mac_addr,
|
||||
neighbor_client[i].mac_addr,
|
||||
sizeof(data_all->mac_addr));
|
||||
evt_data.evt_data = (void *)data_all;
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
/* ask for replaced iface name*/
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
|
||||
/* check for failure return */
|
||||
if (IPACM_FAILURE == ipa_interface_index) {
|
||||
IPACMERR("not supported iface id: %d\n", data_all->if_index);
|
||||
} else {
|
||||
IPACMDBG_H("Posted event %d, with %s for ipv4 client re-connect\n",
|
||||
evt_data.event,
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if (event == IPA_NEW_NEIGH_EVENT)
|
||||
{
|
||||
IPACMDBG_H("Received IPA_NEW_NEIGH_EVENT\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG_H("Received IPA_DEL_NEIGH_EVENT\n");
|
||||
}
|
||||
|
||||
ipacm_event_data_all *data = (ipacm_event_data_all *)param;
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index);
|
||||
/* check for failure return */
|
||||
if (IPACM_FAILURE == ipa_interface_index) {
|
||||
IPACMERR("not supported iface id: %d\n", data->if_index);
|
||||
break;
|
||||
}
|
||||
if (data->iptype == IPA_IP_v4)
|
||||
{
|
||||
if (data->ipv4_addr != 0) /* not 0.0.0.0 */
|
||||
{
|
||||
IPACMDBG("Got Neighbor event with ipv4 address: 0x%x \n", data->ipv4_addr);
|
||||
/* check if ipv4 address is link local(169.254.xxx.xxx) */
|
||||
if ((data->ipv4_addr & IPV4_ADDR_LINKLOCAL_MASK) == IPV4_ADDR_LINKLOCAL)
|
||||
{
|
||||
IPACMDBG_H("This is link local ipv4 address: 0x%x : ignore this NEIGH_EVENT\n", data->ipv4_addr);
|
||||
return;
|
||||
}
|
||||
/* check if iface is bridge interface*/
|
||||
if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0)
|
||||
{
|
||||
/* searh if seen this client or not*/
|
||||
for (i = 0; i < num_neighbor_client_temp; i++)
|
||||
{
|
||||
if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
|
||||
{
|
||||
data->if_index = neighbor_client[i].iface_index;
|
||||
neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address
|
||||
/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
|
||||
if (event == IPA_NEW_NEIGH_EVENT)
|
||||
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
|
||||
else
|
||||
/* not to clean-up the client mac cache on bridge0 delneigh */
|
||||
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
|
||||
data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
|
||||
if (data_all == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate memory\n");
|
||||
return;
|
||||
}
|
||||
memcpy(data_all, data, sizeof(ipacm_event_data_all));
|
||||
evt_data.evt_data = (void *)data_all;
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
|
||||
/* ask for replaced iface name*/
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
|
||||
/* check for failure return */
|
||||
if (IPACM_FAILURE == ipa_interface_index) {
|
||||
IPACMERR("not supported iface id: %d\n", data_all->if_index);
|
||||
} else {
|
||||
IPACMDBG_H("Posted event %d,\
|
||||
with %s for ipv4\n",
|
||||
evt_data.event,
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
|
||||
if (event == IPA_NEW_NEIGH_EVENT)
|
||||
{
|
||||
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
|
||||
/* Also save to cache for ipv4 */
|
||||
/*searh if seen this client or not*/
|
||||
for (i = 0; i < num_neighbor_client_temp; i++)
|
||||
{
|
||||
/* find the client */
|
||||
if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
|
||||
{
|
||||
/* update the network interface client associated */
|
||||
neighbor_client[i].iface_index = data->if_index;
|
||||
neighbor_client[i].ipa_if_num = ipa_interface_index;
|
||||
neighbor_client[i].v4_addr = data->ipv4_addr; // cache client's previous ipv4 address
|
||||
IPACMDBG_H("update cache %d-entry, with %s iface, ipv4 address: 0x%x\n",
|
||||
i,
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,
|
||||
data->ipv4_addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* not find client */
|
||||
if (i == num_neighbor_client_temp)
|
||||
{
|
||||
if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS)
|
||||
{
|
||||
memcpy(neighbor_client[num_neighbor_client_temp].mac_addr,
|
||||
data->mac_addr,
|
||||
sizeof(data->mac_addr));
|
||||
neighbor_client[num_neighbor_client_temp].iface_index = data->if_index;
|
||||
/* cache the network interface client associated */
|
||||
neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index;
|
||||
neighbor_client[num_neighbor_client_temp].v4_addr = data->ipv4_addr;
|
||||
num_neighbor_client++;
|
||||
IPACMDBG_H("Cache client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
|
||||
neighbor_client[num_neighbor_client_temp].mac_addr[0],
|
||||
neighbor_client[num_neighbor_client_temp].mac_addr[1],
|
||||
neighbor_client[num_neighbor_client_temp].mac_addr[2],
|
||||
neighbor_client[num_neighbor_client_temp].mac_addr[3],
|
||||
neighbor_client[num_neighbor_client_temp].mac_addr[4],
|
||||
neighbor_client[num_neighbor_client_temp].mac_addr[5],
|
||||
num_neighbor_client);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
IPACMERR("error: neighbor client oversize! recycle %d-st entry ! \n", circular_index);
|
||||
memcpy(neighbor_client[circular_index].mac_addr,
|
||||
data->mac_addr,
|
||||
sizeof(data->mac_addr));
|
||||
neighbor_client[circular_index].iface_index = data->if_index;
|
||||
/* cache the network interface client associated */
|
||||
neighbor_client[circular_index].ipa_if_num = ipa_interface_index;
|
||||
neighbor_client[circular_index].v4_addr = 0;
|
||||
IPACMDBG_H("Copy wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d, circular %d\n",
|
||||
neighbor_client[circular_index].mac_addr[0],
|
||||
neighbor_client[circular_index].mac_addr[1],
|
||||
neighbor_client[circular_index].mac_addr[2],
|
||||
neighbor_client[circular_index].mac_addr[3],
|
||||
neighbor_client[circular_index].mac_addr[4],
|
||||
neighbor_client[circular_index].mac_addr[5],
|
||||
num_neighbor_client,
|
||||
circular_index);
|
||||
circular_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
|
||||
/*searh if seen this client or not*/
|
||||
for (i = 0; i < num_neighbor_client_temp; i++)
|
||||
{
|
||||
/* find the client */
|
||||
if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
|
||||
{
|
||||
IPACMDBG_H("Clean %d-st Cached client-MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
|
||||
i,
|
||||
neighbor_client[i].mac_addr[0],
|
||||
neighbor_client[i].mac_addr[1],
|
||||
neighbor_client[i].mac_addr[2],
|
||||
neighbor_client[i].mac_addr[3],
|
||||
neighbor_client[i].mac_addr[4],
|
||||
neighbor_client[i].mac_addr[5],
|
||||
num_neighbor_client);
|
||||
|
||||
memset(neighbor_client[i].mac_addr, 0, sizeof(neighbor_client[i].mac_addr));
|
||||
neighbor_client[i].iface_index = 0;
|
||||
neighbor_client[i].v4_addr = 0;
|
||||
neighbor_client[i].ipa_if_num = 0;
|
||||
for (; i < num_neighbor_client_temp - 1; i++)
|
||||
{
|
||||
memcpy(neighbor_client[i].mac_addr,
|
||||
neighbor_client[i+1].mac_addr,
|
||||
sizeof(neighbor_client[i].mac_addr));
|
||||
neighbor_client[i].iface_index = neighbor_client[i+1].iface_index;
|
||||
neighbor_client[i].v4_addr = neighbor_client[i+1].v4_addr;
|
||||
neighbor_client[i].ipa_if_num = neighbor_client[i+1].ipa_if_num;
|
||||
}
|
||||
num_neighbor_client--;
|
||||
IPACMDBG_H(" total number of left cased clients: %d\n", num_neighbor_client);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* not find client, no need clean-up */
|
||||
}
|
||||
|
||||
data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
|
||||
if (data_all == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate memory\n");
|
||||
return;
|
||||
}
|
||||
memcpy(data_all, data, sizeof(ipacm_event_data_all));
|
||||
evt_data.evt_data = (void *)data_all;
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
IPACMDBG_H("Posted event %d with %s for ipv4\n",
|
||||
evt_data.event,
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //ipv6 starts
|
||||
|
||||
if ((data->ipv6_addr[0]) || (data->ipv6_addr[1]) || (data->ipv6_addr[2]) || (data->ipv6_addr[3]))
|
||||
{
|
||||
IPACMDBG("Got New_Neighbor event with ipv6 address \n");
|
||||
/* check if iface is bridge interface*/
|
||||
if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) == 0)
|
||||
{
|
||||
/* searh if seen this client or not*/
|
||||
for (i = 0; i < num_neighbor_client_temp; i++)
|
||||
{
|
||||
if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
|
||||
{
|
||||
data->if_index = neighbor_client[i].iface_index;
|
||||
/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
|
||||
if (event == IPA_NEW_NEIGH_EVENT) evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
|
||||
else evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
|
||||
data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
|
||||
if (data_all == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate memory\n");
|
||||
return;
|
||||
}
|
||||
memcpy(data_all, data, sizeof(ipacm_event_data_all));
|
||||
evt_data.evt_data = (void *)data_all;
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
/* ask for replaced iface name*/
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
|
||||
/* check for failure return */
|
||||
if (IPACM_FAILURE == ipa_interface_index) {
|
||||
IPACMERR("not supported iface id: %d\n", data_all->if_index);
|
||||
} else {
|
||||
IPACMDBG_H("Posted event %d,\
|
||||
with %s for ipv6\n",
|
||||
evt_data.event,
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
|
||||
if (event == IPA_NEW_NEIGH_EVENT)
|
||||
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
|
||||
else
|
||||
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
|
||||
data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
|
||||
if (data_all == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate memory\n");
|
||||
return;
|
||||
}
|
||||
memcpy(data_all, data, sizeof(ipacm_event_data_all));
|
||||
evt_data.evt_data = (void *)data_all;
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
IPACMDBG_H("Posted event %d with %s for ipv6\n",
|
||||
evt_data.event,
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMDBG(" Got Neighbor event with no ipv6/ipv4 address \n");
|
||||
/*no ipv6 in data searh if seen this client or not*/
|
||||
for (i = 0; i < num_neighbor_client_temp; i++)
|
||||
{
|
||||
/* find the client */
|
||||
if (memcmp(neighbor_client[i].mac_addr, data->mac_addr, sizeof(neighbor_client[i].mac_addr)) == 0)
|
||||
{
|
||||
IPACMDBG_H(" find %d-st client, MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
|
||||
i,
|
||||
neighbor_client[i].mac_addr[0],
|
||||
neighbor_client[i].mac_addr[1],
|
||||
neighbor_client[i].mac_addr[2],
|
||||
neighbor_client[i].mac_addr[3],
|
||||
neighbor_client[i].mac_addr[4],
|
||||
neighbor_client[i].mac_addr[5],
|
||||
num_neighbor_client);
|
||||
/* check if iface is not bridge interface*/
|
||||
if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0)
|
||||
{
|
||||
/* use previous ipv4 first */
|
||||
if(data->if_index != neighbor_client[i].iface_index)
|
||||
{
|
||||
IPACMDBG_H("update new kernel iface index \n");
|
||||
neighbor_client[i].iface_index = data->if_index;
|
||||
}
|
||||
|
||||
/* check if client associated with previous network interface */
|
||||
if(ipa_interface_index != neighbor_client[i].ipa_if_num)
|
||||
{
|
||||
IPACMDBG_H("client associate to different AP \n");
|
||||
}
|
||||
|
||||
if (neighbor_client[i].v4_addr != 0) /* not 0.0.0.0 */
|
||||
{
|
||||
/* construct IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT command and insert to command-queue */
|
||||
if (event == IPA_NEW_NEIGH_EVENT)
|
||||
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT;
|
||||
else
|
||||
evt_data.event = IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT;
|
||||
data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
|
||||
if (data_all == NULL)
|
||||
{
|
||||
IPACMERR("Unable to allocate memory\n");
|
||||
return;
|
||||
}
|
||||
data_all->iptype = IPA_IP_v4;
|
||||
data_all->if_index = neighbor_client[i].iface_index;
|
||||
data_all->ipv4_addr = neighbor_client[i].v4_addr; //use previous ipv4 address
|
||||
memcpy(data_all->mac_addr,
|
||||
neighbor_client[i].mac_addr,
|
||||
sizeof(data_all->mac_addr));
|
||||
evt_data.evt_data = (void *)data_all;
|
||||
IPACM_EvtDispatcher::PostEvt(&evt_data);
|
||||
/* ask for replaced iface name*/
|
||||
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data_all->if_index);
|
||||
/* check for failure return */
|
||||
if (IPACM_FAILURE == ipa_interface_index) {
|
||||
IPACMERR("not supported iface id: %d\n", data_all->if_index);
|
||||
} else {
|
||||
IPACMDBG_H("Posted event %d,\
|
||||
with %s for ipv4 client re-connect\n",
|
||||
evt_data.event,
|
||||
IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* delete cache neighbor entry */
|
||||
if (event == IPA_DEL_NEIGH_EVENT)
|
||||
{
|
||||
IPACMDBG_H("Clean %d-st Cached client-MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
|
||||
i,
|
||||
neighbor_client[i].mac_addr[0],
|
||||
neighbor_client[i].mac_addr[1],
|
||||
neighbor_client[i].mac_addr[2],
|
||||
neighbor_client[i].mac_addr[3],
|
||||
neighbor_client[i].mac_addr[4],
|
||||
neighbor_client[i].mac_addr[5],
|
||||
num_neighbor_client);
|
||||
|
||||
memset(neighbor_client[i].mac_addr, 0, sizeof(neighbor_client[i].mac_addr));
|
||||
neighbor_client[i].iface_index = 0;
|
||||
neighbor_client[i].v4_addr = 0;
|
||||
neighbor_client[i].ipa_if_num = 0;
|
||||
for (; i < num_neighbor_client_temp - 1; i++)
|
||||
{
|
||||
memcpy(neighbor_client[i].mac_addr,
|
||||
neighbor_client[i+1].mac_addr,
|
||||
sizeof(neighbor_client[i].mac_addr));
|
||||
neighbor_client[i].iface_index = neighbor_client[i+1].iface_index;
|
||||
neighbor_client[i].v4_addr = neighbor_client[i+1].v4_addr;
|
||||
neighbor_client[i].ipa_if_num = neighbor_client[i+1].ipa_if_num;
|
||||
}
|
||||
num_neighbor_client--;
|
||||
IPACMDBG_H(" total number of left cased clients: %d\n", num_neighbor_client);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* not find client */
|
||||
if ((i == num_neighbor_client_temp) && (event == IPA_NEW_NEIGH_EVENT))
|
||||
{
|
||||
/* check if iface is not bridge interface*/
|
||||
if (strcmp(IPACM_Iface::ipacmcfg->ipa_virtual_iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name) != 0)
|
||||
{
|
||||
if (num_neighbor_client_temp < IPA_MAX_NUM_NEIGHBOR_CLIENTS)
|
||||
{
|
||||
memcpy(neighbor_client[num_neighbor_client_temp].mac_addr,
|
||||
data->mac_addr,
|
||||
sizeof(data->mac_addr));
|
||||
neighbor_client[num_neighbor_client_temp].iface_index = data->if_index;
|
||||
/* cache the network interface client associated */
|
||||
neighbor_client[num_neighbor_client_temp].ipa_if_num = ipa_interface_index;
|
||||
neighbor_client[num_neighbor_client_temp].v4_addr = 0;
|
||||
num_neighbor_client++;
|
||||
IPACMDBG_H("Copy client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d\n",
|
||||
neighbor_client[num_neighbor_client_temp].mac_addr[0],
|
||||
neighbor_client[num_neighbor_client_temp].mac_addr[1],
|
||||
neighbor_client[num_neighbor_client_temp].mac_addr[2],
|
||||
neighbor_client[num_neighbor_client_temp].mac_addr[3],
|
||||
neighbor_client[num_neighbor_client_temp].mac_addr[4],
|
||||
neighbor_client[num_neighbor_client_temp].mac_addr[5],
|
||||
num_neighbor_client);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPACMERR("error: neighbor client oversize! recycle %d-st entry ! \n", circular_index);
|
||||
memcpy(neighbor_client[circular_index].mac_addr,
|
||||
data->mac_addr,
|
||||
sizeof(data->mac_addr));
|
||||
neighbor_client[circular_index].iface_index = data->if_index;
|
||||
/* cache the network interface client associated */
|
||||
neighbor_client[circular_index].ipa_if_num = ipa_interface_index;
|
||||
neighbor_client[circular_index].v4_addr = 0;
|
||||
IPACMDBG_H("Copy wlan-iface client MAC %02x:%02x:%02x:%02x:%02x:%02x\n, total client: %d, circular %d\n",
|
||||
neighbor_client[circular_index].mac_addr[0],
|
||||
neighbor_client[circular_index].mac_addr[1],
|
||||
neighbor_client[circular_index].mac_addr[2],
|
||||
neighbor_client[circular_index].mac_addr[3],
|
||||
neighbor_client[circular_index].mac_addr[4],
|
||||
neighbor_client[circular_index].mac_addr[5],
|
||||
num_neighbor_client,
|
||||
circular_index);
|
||||
circular_index++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} //ipv6 ends
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
1773
data-ipa-cfg-mgr/ipacm/src/IPACM_Netlink.cpp
Normal file
1773
data-ipa-cfg-mgr/ipacm/src/IPACM_Netlink.cpp
Normal file
File diff suppressed because it is too large
Load Diff
276
data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp
Normal file
276
data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
Copyright (c) 2013, 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
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
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.
|
||||
*/
|
||||
/*!
|
||||
@file
|
||||
IPACM_Routing.cpp
|
||||
|
||||
@brief
|
||||
This file implements the IPACM routing functionality.
|
||||
|
||||
@Author
|
||||
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "IPACM_Routing.h"
|
||||
#include <IPACM_Log.h>
|
||||
|
||||
const char *IPACM_Routing::DEVICE_NAME = "/dev/ipa";
|
||||
|
||||
IPACM_Routing::IPACM_Routing()
|
||||
{
|
||||
m_fd = open(DEVICE_NAME, O_RDWR);
|
||||
if (0 == m_fd)
|
||||
{
|
||||
IPACMERR("Failed opening %s.\n", DEVICE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
IPACM_Routing::~IPACM_Routing()
|
||||
{
|
||||
close(m_fd);
|
||||
}
|
||||
|
||||
bool IPACM_Routing::DeviceNodeIsOpened()
|
||||
{
|
||||
int res = fcntl(m_fd, F_GETFL);
|
||||
|
||||
if (m_fd > 0 && res >= 0) return true;
|
||||
else return false;
|
||||
|
||||
}
|
||||
|
||||
bool IPACM_Routing::AddRoutingRule(struct ipa_ioc_add_rt_rule *ruleTable)
|
||||
{
|
||||
int retval = 0, cnt=0;
|
||||
bool isInvalid = false;
|
||||
|
||||
if (!DeviceNodeIsOpened())
|
||||
{
|
||||
IPACMERR("Device is not opened\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for(cnt=0; cnt<ruleTable->num_rules; cnt++)
|
||||
{
|
||||
if(ruleTable->rules[cnt].rule.dst > IPA_CLIENT_MAX)
|
||||
{
|
||||
IPACMERR("Invalid dst pipe, Rule:%d dst_pipe:%d\n", cnt, ruleTable->rules[cnt].rule.dst);
|
||||
isInvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(isInvalid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
retval = ioctl(m_fd, IPA_IOC_ADD_RT_RULE, ruleTable);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed adding routing rule %p\n", ruleTable);
|
||||
return false;
|
||||
}
|
||||
|
||||
for(cnt=0; cnt<ruleTable->num_rules; cnt++)
|
||||
{
|
||||
IPACMDBG("Rule:%d dst_pipe:%d\n", cnt, ruleTable->rules[cnt].rule.dst);
|
||||
}
|
||||
|
||||
IPACMDBG_H("Added routing rule %p\n", ruleTable);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPACM_Routing::DeleteRoutingRule(struct ipa_ioc_del_rt_rule *ruleTable)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (!DeviceNodeIsOpened()) return false;
|
||||
|
||||
retval = ioctl(m_fd, IPA_IOC_DEL_RT_RULE, ruleTable);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed deleting routing rule table %p\n", ruleTable);
|
||||
return false;
|
||||
}
|
||||
|
||||
IPACMDBG_H("Deleted routing rule %p\n", ruleTable);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPACM_Routing::Commit(enum ipa_ip_type ip)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (!DeviceNodeIsOpened()) return false;
|
||||
|
||||
retval = ioctl(m_fd, IPA_IOC_COMMIT_RT, ip);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed commiting routing rules.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
IPACMDBG_H("Commited routing rules to IPA HW.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPACM_Routing::Reset(enum ipa_ip_type ip)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (!DeviceNodeIsOpened()) return false;
|
||||
|
||||
retval = ioctl(m_fd, IPA_IOC_RESET_RT, ip);
|
||||
retval |= ioctl(m_fd, IPA_IOC_COMMIT_RT, ip);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed resetting routing block.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
IPACMDBG_H("Reset command issued to IPA routing block.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPACM_Routing::GetRoutingTable(struct ipa_ioc_get_rt_tbl *routingTable)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (!DeviceNodeIsOpened()) return false;
|
||||
|
||||
retval = ioctl(m_fd, IPA_IOC_GET_RT_TBL, routingTable);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("IPA_IOCTL_GET_RT_TBL ioctl failed, routingTable =0x%p, retval=0x%x.\n", routingTable, retval);
|
||||
return false;
|
||||
}
|
||||
IPACMDBG_H("IPA_IOCTL_GET_RT_TBL ioctl issued to IPA routing block.\n");
|
||||
/* put routing table right after successfully get routing table */
|
||||
PutRoutingTable(routingTable->hdl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPACM_Routing::PutRoutingTable(uint32_t routingTableHandle)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (!DeviceNodeIsOpened()) return false;
|
||||
|
||||
retval = ioctl(m_fd, IPA_IOC_PUT_RT_TBL, routingTableHandle);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("IPA_IOCTL_PUT_RT_TBL ioctl failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
IPACMDBG_H("IPA_IOCTL_PUT_RT_TBL ioctl issued to IPA routing block.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IPACM_Routing::DeleteRoutingHdl(uint32_t rt_rule_hdl, ipa_ip_type ip)
|
||||
{
|
||||
const uint8_t NUM_RULES = 1;
|
||||
struct ipa_ioc_del_rt_rule *rt_rule;
|
||||
struct ipa_rt_rule_del *rt_rule_entry;
|
||||
bool res = true;
|
||||
int len = 0;
|
||||
|
||||
if (rt_rule_hdl == 0)
|
||||
{
|
||||
IPACMERR(" No route handle passed. Ignoring it\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
len = (sizeof(struct ipa_ioc_del_rt_rule)) + (NUM_RULES * sizeof(struct ipa_rt_rule_del));
|
||||
rt_rule = (struct ipa_ioc_del_rt_rule *)malloc(len);
|
||||
if (rt_rule == NULL)
|
||||
{
|
||||
IPACMERR("unable to allocate memory for del route rule\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(rt_rule, 0, len);
|
||||
rt_rule->commit = 1;
|
||||
rt_rule->num_hdls = NUM_RULES;
|
||||
rt_rule->ip = ip;
|
||||
|
||||
rt_rule_entry = &rt_rule->hdl[0];
|
||||
rt_rule_entry->status = -1;
|
||||
rt_rule_entry->hdl = rt_rule_hdl;
|
||||
|
||||
IPACMDBG_H("Deleting Route hdl:(0x%x) with ip type: %d\n", rt_rule_entry->hdl, ip);
|
||||
if ((false == DeleteRoutingRule(rt_rule)) ||
|
||||
(rt_rule_entry->status))
|
||||
{
|
||||
PERROR("Routing rule deletion failed!\n");
|
||||
goto fail;
|
||||
res = false;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(rt_rule);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool IPACM_Routing::ModifyRoutingRule(struct ipa_ioc_mdfy_rt_rule *mdfyRules)
|
||||
{
|
||||
int retval = 0, cnt;
|
||||
|
||||
if (!DeviceNodeIsOpened())
|
||||
{
|
||||
IPACMERR("Device is not opened\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
retval = ioctl(m_fd, IPA_IOC_MDFY_RT_RULE, mdfyRules);
|
||||
if (retval)
|
||||
{
|
||||
IPACMERR("Failed modifying routing rules %p\n", mdfyRules);
|
||||
return false;
|
||||
}
|
||||
|
||||
for(cnt=0; cnt<mdfyRules->num_rules; cnt++)
|
||||
{
|
||||
if(mdfyRules->rules[cnt].status != 0)
|
||||
{
|
||||
IPACMERR("Unable to modify rule: %d\n", cnt);
|
||||
}
|
||||
}
|
||||
|
||||
IPACMDBG_H("Modified routing rules %p\n", mdfyRules);
|
||||
return true;
|
||||
}
|
||||
6139
data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp
Normal file
6139
data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2036
data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp
Normal file
2036
data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1176
data-ipa-cfg-mgr/ipacm/src/IPACM_Xml.cpp
Normal file
1176
data-ipa-cfg-mgr/ipacm/src/IPACM_Xml.cpp
Normal file
File diff suppressed because it is too large
Load Diff
175
data-ipa-cfg-mgr/ipacm/src/IPACM_cfg.xml
Normal file
175
data-ipa-cfg-mgr/ipacm/src/IPACM_cfg.xml
Normal file
@@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<system xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ipacm_cfg.xsd">
|
||||
<ODUCFG>
|
||||
<OduMode>router</OduMode>
|
||||
<eMBMS_offload>0</eMBMS_offload>
|
||||
</ODUCFG>
|
||||
<IPACM>
|
||||
<IPACMIface>
|
||||
<Iface>
|
||||
<Name>rndis0</Name>
|
||||
<Category>LAN</Category>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>ecm0</Name>
|
||||
<Category>LAN</Category>
|
||||
<Mode>ROUTER</Mode>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>rmnet_data0</Name>
|
||||
<Category>WAN</Category>
|
||||
<Mode>ROUTER</Mode>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>rmnet_data1</Name>
|
||||
<Category>WAN</Category>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>rmnet_data2</Name>
|
||||
<Category>WAN</Category>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>rmnet_data3</Name>
|
||||
<Category>WAN</Category>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>rmnet_data4</Name>
|
||||
<Category>WAN</Category>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>rmnet_data5</Name>
|
||||
<Category>WAN</Category>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>rmnet_data6</Name>
|
||||
<Category>WAN</Category>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>rmnet_data7</Name>
|
||||
<Category>WAN</Category>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>softap0</Name>
|
||||
<Category>UNKNOWN</Category>
|
||||
<WlanMode>full</WlanMode>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>wlan0</Name>
|
||||
<Category>UNKNOWN</Category>
|
||||
<WlanMode>full</WlanMode>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>wlan1</Name>
|
||||
<Category>UNKNOWN</Category>
|
||||
<WlanMode>full</WlanMode>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>wlan2</Name>
|
||||
<Category>UNKNOWN</Category>
|
||||
<WlanMode>full</WlanMode>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>wlan3</Name>
|
||||
<Category>UNKNOWN</Category>
|
||||
<WlanMode>full</WlanMode>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>eth0</Name>
|
||||
<Category>ODU</Category>
|
||||
</Iface>
|
||||
<Iface>
|
||||
<Name>bridge0</Name>
|
||||
<Category>VIRTUAL</Category>
|
||||
</Iface>
|
||||
</IPACMIface>
|
||||
<IPPassthroughFlag>
|
||||
<IPPassthroughMode>0</IPPassthroughMode>
|
||||
</IPPassthroughFlag>
|
||||
<IPACMPrivateSubnet>
|
||||
<Subnet>
|
||||
<SubnetAddress>192.168.225.0</SubnetAddress>
|
||||
<SubnetMask>255.255.255.0</SubnetMask>
|
||||
</Subnet>
|
||||
</IPACMPrivateSubnet>
|
||||
<IPACMALG>
|
||||
<ALG>
|
||||
<Protocol>TCP</Protocol>
|
||||
<Port>21</Port>
|
||||
<Description>FTP</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>TCP</Protocol>
|
||||
<Port>554</Port>
|
||||
<Description>RTSP</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>TCP</Protocol>
|
||||
<Port>5060</Port>
|
||||
<Description>SIP</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>UDP</Protocol>
|
||||
<Port>5060</Port>
|
||||
<Description>SIP</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>TCP</Protocol>
|
||||
<Port>1723</Port>
|
||||
<Description>PPTP</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>UDP</Protocol>
|
||||
<Port>69</Port>
|
||||
<Description>TFTP</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>UDP</Protocol>
|
||||
<Port>53</Port>
|
||||
<Description>DNS</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>TCP</Protocol>
|
||||
<Port>53</Port>
|
||||
<Description>DNS</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>UDP</Protocol>
|
||||
<Port>10080</Port>
|
||||
<Description>AMANDA</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>UDP</Protocol>
|
||||
<Port>1719</Port>
|
||||
<Description>H323</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>TCP</Protocol>
|
||||
<Port>1720</Port>
|
||||
<Description>H323</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>TCP</Protocol>
|
||||
<Port>6667</Port>
|
||||
<Description>IRC</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>UDP</Protocol>
|
||||
<Port>137</Port>
|
||||
<Description>NETBIOS_NS</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>UDP</Protocol>
|
||||
<Port>138</Port>
|
||||
<Description>NETBIOS_NS</Description>
|
||||
</ALG>
|
||||
<ALG>
|
||||
<Protocol>TCP</Protocol>
|
||||
<Port>6566</Port>
|
||||
<Description>SANE</Description>
|
||||
</ALG>
|
||||
</IPACMALG>
|
||||
<IPACMNAT>
|
||||
<MaxNatEntries>500</MaxNatEntries>
|
||||
</IPACMNAT>
|
||||
</IPACM>
|
||||
</system>
|
||||
55
data-ipa-cfg-mgr/ipacm/src/Makefile.am
Normal file
55
data-ipa-cfg-mgr/ipacm/src/Makefile.am
Normal file
@@ -0,0 +1,55 @@
|
||||
AM_CPPFLAGS = -I./../inc \
|
||||
-I$(top_srcdir)/ipanat/inc \
|
||||
${LIBXML_CFLAGS}
|
||||
AM_CPPFLAGS += -Wall -Wundef -Wno-trigraphs
|
||||
AM_CPPFLAGS += -DDEBUG -g -DFEATURE_ETH_BRIDGE_LE
|
||||
AM_CPPFLAGS += -DFEATURE_IPA_V3
|
||||
|
||||
ipacm_SOURCES = IPACM_Main.cpp \
|
||||
IPACM_Conntrack_NATApp.cpp\
|
||||
IPACM_ConntrackClient.cpp \
|
||||
IPACM_ConntrackListener.cpp \
|
||||
IPACM_EvtDispatcher.cpp \
|
||||
IPACM_Config.cpp \
|
||||
IPACM_CmdQueue.cpp \
|
||||
IPACM_Log.cpp \
|
||||
IPACM_Filtering.cpp \
|
||||
IPACM_Routing.cpp \
|
||||
IPACM_Header.cpp \
|
||||
IPACM_Lan.cpp \
|
||||
IPACM_Iface.cpp \
|
||||
IPACM_Wlan.cpp \
|
||||
IPACM_Wan.cpp \
|
||||
IPACM_IfaceManager.cpp \
|
||||
IPACM_Neighbor.cpp \
|
||||
IPACM_Netlink.cpp \
|
||||
IPACM_Xml.cpp \
|
||||
IPACM_LanToLan.cpp
|
||||
|
||||
bin_PROGRAMS = ipacm
|
||||
|
||||
requiredlibs = ${LIBXML_LIB} -lxml2 -lpthread -lnetfilter_conntrack -lnfnetlink\
|
||||
../../ipanat/src/libipanat.la
|
||||
|
||||
AM_CPPFLAGS += "-std=c++0x"
|
||||
|
||||
if USE_GLIB
|
||||
ipacm_CFLAGS = $(AM_CFLAGS) -DUSE_GLIB @GLIB_CFLAGS@
|
||||
ipacm_LDFLAGS = -lpthread @GLIB_LIBS@
|
||||
ipacm_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@
|
||||
else
|
||||
ipacm_CFLAGS = $(AM_CFLAGS)
|
||||
ipacm_LDFLAGS = -lpthread
|
||||
ipacm_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
endif
|
||||
ipacm_LDADD = $(requiredlibs)
|
||||
|
||||
LOCAL_MODULE := libipanat
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
etcdir = ${sysconfdir}
|
||||
etc_SCRIPTS = IPACM_cfg.xml
|
||||
|
||||
init_ddir = ${sysconfdir}/init.d
|
||||
init_d_SCRIPTS = start_ipacm_le
|
||||
7
data-ipa-cfg-mgr/ipacm/src/mobileap_firewall.xml
Normal file
7
data-ipa-cfg-mgr/ipacm/src/mobileap_firewall.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<system xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="mobileap_firewall_cfg.xsd">
|
||||
<MobileAPFirewallCfg>
|
||||
<FirewallEnabled>1</FirewallEnabled>
|
||||
<FirewallPktsAllowed>0</FirewallPktsAllowed>
|
||||
</MobileAPFirewallCfg>
|
||||
</system>
|
||||
57
data-ipa-cfg-mgr/ipacm/src/start_ipacm_le
Normal file
57
data-ipa-cfg-mgr/ipacm/src/start_ipacm_le
Normal file
@@ -0,0 +1,57 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
################################
|
||||
# Copyright (c) 2013, 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
|
||||
# met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of The Linux Foundation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# 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.
|
||||
################################
|
||||
|
||||
# ipacm init.d script to start the data-ipa Software's ipacm daemon
|
||||
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Starting ipacm: "
|
||||
start-stop-daemon -S -b -a ipacm
|
||||
echo "done"
|
||||
;;
|
||||
stop)
|
||||
echo -n "Stopping ipacm: "
|
||||
start-stop-daemon -K -n ipacm
|
||||
echo "done"
|
||||
;;
|
||||
restart)
|
||||
$0 stop
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage ipacm { start | stop | restart}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user