diff options
39 files changed, 2827 insertions, 9393 deletions
diff --git a/data-ipa-cfg-mgr/Android.mk b/data-ipa-cfg-mgr/Android.mk index 5053e7d..39de891 100644 --- a/data-ipa-cfg-mgr/Android.mk +++ b/data-ipa-cfg-mgr/Android.mk @@ -1 +1,18 @@ -include $(call all-subdir-makefiles) +# +# Copyright (C) 2015 The CyanogenMod Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) + +include $(call first-makefiles-under,$(LOCAL_PATH)) diff --git a/data-ipa-cfg-mgr/ipacm/Android.mk b/data-ipa-cfg-mgr/ipacm/Android.mk deleted file mode 100644 index 5053e7d..0000000 --- a/data-ipa-cfg-mgr/ipacm/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(call all-subdir-makefiles) diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_CmdQueue.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_CmdQueue.h index 2f7709a..27d7c8b 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_CmdQueue.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_CmdQueue.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -85,7 +85,8 @@ private: Message *Head; Message *Tail; Message* dequeue(void); - static MessageQueue *inst; + static MessageQueue *inst_internal; + static MessageQueue *inst_external; MessageQueue() { @@ -99,7 +100,8 @@ public: void enqueue(Message *item); static void* Process(void *); - static MessageQueue* getInstance(); + static MessageQueue* getInstanceInternal(); + static MessageQueue* getInstanceExternal(); }; diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Config.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Config.h index 665b844..5bcb4eb 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Config.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Config.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -62,7 +62,7 @@ typedef struct _ipa_rm_client bool rx_bypass_ipa; /* support WLAN may not register RX-property, should not add dependency */ }ipa_rm_client; -#define MAX_NUM_EXT_PROPS 15 +#define MAX_NUM_EXT_PROPS 25 /* used to hold extended properties */ typedef struct @@ -115,6 +115,8 @@ public: bool ipacm_odu_embms_enable; + bool ipacm_ip_passthrough_mode; + int ipa_nat_iface_entries; /* Store the total number of wlan guest ap configured */ @@ -139,16 +141,15 @@ public: /* IPACM routing table name for v4/v6 */ struct ipa_ioc_get_rt_tbl rt_tbl_lan_v4, rt_tbl_wan_v4, rt_tbl_default_v4, rt_tbl_v6, rt_tbl_wan_v6; struct ipa_ioc_get_rt_tbl rt_tbl_wan_dl; - struct ipa_ioc_get_rt_tbl rt_tbl_lan2lan_v4, rt_tbl_lan2lan_v6; struct ipa_ioc_get_rt_tbl rt_tbl_odu_v4, rt_tbl_odu_v6; - struct ipa_ioc_get_rt_tbl rt_tbl_eth_bridge_lan_lan_v4, rt_tbl_eth_bridge_lan_wlan_v4, rt_tbl_eth_bridge_wlan_wlan_v4; - struct ipa_ioc_get_rt_tbl rt_tbl_eth_bridge_lan_lan_v6, rt_tbl_eth_bridge_lan_wlan_v6, rt_tbl_eth_bridge_wlan_wlan_v6; bool isMCC_Mode; /* To return the instance */ static IPACM_Config* GetInstance(); + const char* getEventName(ipa_cm_event_id event_id); + inline void increaseFltRuleCount(int index, ipa_ip_type iptype, int increment) { if((index >= IPA_CLIENT_CONS - IPA_CLIENT_PROD) || (index < 0)) diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_ConntrackListener.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_ConntrackListener.h index db83598..cdf3ef5 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_ConntrackListener.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_ConntrackListener.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -46,11 +46,21 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "IPACM_LanToLan.h" #endif -#define MAX_NAT_IFACES 50 +#define MAX_IFACE_ADDRESS 50 #define MAX_STA_CLNT_IFACES 10 +#define STA_CLNT_SUBNET_MASK 0xFFFFFF00 using namespace std; +typedef struct _nat_entry_bundle +{ + struct nf_conntrack *ct; + enum nf_conntrack_msg_type type; + nat_table_entry *rule; + bool isTempEntry; + +}nat_entry_bundle; + class IPACM_ConntrackListener : public IPACM_Listener { @@ -63,8 +73,8 @@ private: int NatIfaceCnt; int StaClntCnt; NatIfaces *pNatIfaces; - uint32_t nat_iface_ipv4_addr[MAX_NAT_IFACES]; - uint32_t nonnat_iface_ipv4_addr[MAX_NAT_IFACES]; + uint32_t nat_iface_ipv4_addr[MAX_IFACE_ADDRESS]; + uint32_t nonnat_iface_ipv4_addr[MAX_IFACE_ADDRESS]; uint32_t sta_clnt_ipv4_addr[MAX_STA_CLNT_IFACES]; IPACM_Config *pConfig; #ifdef CT_OPT @@ -78,9 +88,17 @@ private: void TriggerWANDown(uint32_t); int CreateNatThreads(void); int CreateConnTrackThreads(void); + bool AddIface(nat_table_entry *, bool *); + void AddORDeleteNatEntry(const nat_entry_bundle *); + void PopulateTCPorUDPEntry(struct nf_conntrack *, uint32_t, nat_table_entry *); + void CheckSTAClient(const nat_table_entry *, bool *); + int CheckNatIface(ipacm_event_data_all *, bool *); + void HandleNonNatIPAddr(void *, bool); #ifdef CT_OPT void ProcessCTV6Message(void *); + void HandleLan2Lan(struct nf_conntrack *, + enum nf_conntrack_msg_type, nat_table_entry* ); #endif public: diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Conntrack_NATApp.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Conntrack_NATApp.h index e6c27af..e50b316 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Conntrack_NATApp.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Conntrack_NATApp.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +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 @@ -125,7 +125,7 @@ public: void AddTempEntry(const nat_table_entry *); void CacheEntry(const nat_table_entry *); void DeleteTempEntry(const nat_table_entry *); - void FlushTempEntries(uint32_t, bool); + void FlushTempEntries(uint32_t, bool, bool isDummy = false); }; diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h index 677b122..a6e76d1 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -45,6 +45,12 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <linux/msm_ipa.h> #include "IPACM_Log.h" +#ifdef USE_GLIB +#include <glib.h> +#define strlcpy g_strlcpy +#define strlcat g_strlcat +#endif + extern "C" { #include <libnetfilter_conntrack/libnetfilter_conntrack.h> @@ -57,10 +63,10 @@ extern "C" #define IPA_ALG_PROTOCOL_NAME_LEN 10 #define IPA_WLAN_PARTIAL_HDR_OFFSET 0 // dst mac first then src mac -//#define IPA_ETH_PARTIAL_HDR_OFFSET 8 // dst mac first then src mac #define IPA_ODU_PARTIAL_HDR_OFFSET 8 // dst mac first then src mac #define IPA_WLAN_PARTIAL_HDR_NAME_v4 "IEEE802_3_v4" #define IPA_WLAN_PARTIAL_HDR_NAME_v6 "IEEE802_3_v6" +#define IPA_DUMMY_ETH_HDR_NAME_v6 "ETH_dummy_v6" #define IPA_WAN_PARTIAL_HDR_NAME_v4 "IEEE802_3_STA_v4" #define IPA_WAN_PARTIAL_HDR_NAME_v6 "IEEE802_3_STA_v6" #define IPA_ETH_HDR_NAME_v4 "IPACM_ETH_v4" @@ -83,36 +89,16 @@ extern "C" #define WAN_DL_ROUTE_TABLE_NAME "ipa_dflt_wan_rt" #define V6_COMMON_ROUTE_TABLE_NAME "COMRTBLv6" #define V6_WAN_ROUTE_TABLE_NAME "WANRTBLv6" -#define V4_LAN_TO_LAN_ROUTE_TABLE_NAME "LANTOLANRTBLv4" -#define V6_LAN_TO_LAN_ROUTE_TABLE_NAME "LANTOLANRTBLv6" #define V4_ODU_ROUTE_TABLE_NAME "ODURTBLv4" #define V6_ODU_ROUTE_TABLE_NAME "ODURTBLv6" -#define ETH_BRIDGE_USB_CPE_ROUTE_TABLE_NAME_V4 "ETH_BRIDGE_LAN_LAN_RTBLv4" -#define ETH_BRIDGE_USB_WLAN_ROUTE_TABLE_NAME_V4 "ETH_BRIDGE_LAN_WLAN_RTBLv4" -#define ETH_BRIDGE_WLAN_WLAN_ROUTE_TABLE_NAME_V4 "ETH_BRIDGE_WLAN_WLAN_RTBLv4" -#define ETH_BRIDGE_USB_CPE_ROUTE_TABLE_NAME_V6 "ETH_BRIDGE_LAN_LAN_RTBLv6" -#define ETH_BRIDGE_USB_WLAN_ROUTE_TABLE_NAME_V6 "ETH_BRIDGE_LAN_WLAN_RTBLv6" -#define ETH_BRIDGE_WLAN_WLAN_ROUTE_TABLE_NAME_V6 "ETH_BRIDGE_WLAN_WLAN_RTBLv6" - #define WWAN_QMI_IOCTL_DEVICE_NAME "/dev/wwan_ioctl" #define IPA_DEVICE_NAME "/dev/ipa" +#define MAX_NUM_PROP 2 #define IPA_MAX_FLT_RULE 50 - -#define MAX_OFFLOAD_PAIR 3 -#define MAX_NUM_PROP 8 -#define IPA_LAN_TO_LAN_USB_HDR_NAME_V4 "Lan2Lan_USB_v4" -#define IPA_LAN_TO_LAN_USB_HDR_NAME_V6 "Lan2Lan_USB_v6" -#define IPA_LAN_TO_LAN_WLAN_HDR_NAME_V4 "Lan2Lan_Wlan_v4" -#define IPA_LAN_TO_LAN_WLAN_HDR_NAME_V6 "Lan2Lan_Wlan_v6" -#define IPA_LAN_TO_LAN_MAX_WLAN_CLIENT 16 -#define IPA_LAN_TO_LAN_MAX_USB_CLIENT 1 -#define IPA_LAN_TO_LAN_MAX_CPE_CLIENT 15 -#define IPA_LAN_TO_LAN_MAX_LAN_CLIENT (IPA_LAN_TO_LAN_MAX_USB_CLIENT + IPA_LAN_TO_LAN_MAX_CPE_CLIENT) #define TCP_FIN_SHIFT 16 #define TCP_SYN_SHIFT 17 #define TCP_RST_SHIFT 18 -#define NUM_TCP_CTL_FLT_RULE 3 #define NUM_IPV6_PREFIX_FLT_RULE 1 /*--------------------------------------------------------------------------- @@ -136,66 +122,63 @@ extern "C" ===========================================================================*/ typedef enum { - IPA_CFG_CHANGE_EVENT = 1, /* 1 NULL */ - IPA_LINK_UP_EVENT, /* 2 ipacm_event_data_fid */ - IPA_LINK_DOWN_EVENT, /* 3 ipacm_event_data_fid */ - IPA_ADDR_ADD_EVENT, /* 4 ipacm_event_data_addr */ - IPA_ADDR_DEL_EVENT, /* 5 no use */ - IPA_ROUTE_ADD_EVENT, /* 6 ipacm_event_data_addr */ - IPA_ROUTE_DEL_EVENT, /* 7 ipacm_event_data_addr */ - IPA_FIREWALL_CHANGE_EVENT, /* 8 NULL */ - IPA_WLAN_AP_LINK_UP_EVENT, /* 9 ipacm_event_data_mac */ - IPA_WLAN_STA_LINK_UP_EVENT, /* 10 ipacm_event_data_mac */ - IPA_WLAN_CLIENT_ADD_EVENT, /* 11 ipacm_event_data_mac */ - IPA_WLAN_CLIENT_DEL_EVENT, /* 12 ipacm_event_data_mac */ - IPA_WLAN_CLIENT_POWER_SAVE_EVENT, /* 13 ipacm_event_data_mac */ - IPA_WLAN_CLIENT_RECOVER_EVENT, /* 14 ipacm_event_data_mac */ - IPA_NEW_NEIGH_EVENT, /* 15 ipacm_event_data_all */ - IPA_DEL_NEIGH_EVENT, /* 16 ipacm_event_data_all */ - IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, /* 17 ipacm_event_data_all */ - IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, /* 18 ipacm_event_data_all */ - IPA_SW_ROUTING_ENABLE, /* 19 NULL */ - IPA_SW_ROUTING_DISABLE, /* 20 NULL */ - IPA_PROCESS_CT_MESSAGE, /* 21 ipacm_ct_evt_data */ - IPA_HANDLE_WAN_UP, /* 22 ipacm_event_iface_up */ - IPA_HANDLE_WAN_DOWN, /* 23 ipacm_event_iface_up */ - IPA_HANDLE_WLAN_UP, /* 24 ipacm_event_iface_up */ - IPA_HANDLE_LAN_UP, /* 25 ipacm_event_iface_up */ - IPA_WLAN_CLIENT_ADD_EVENT_EX, /* 26 ipacm_event_data_wlan_ex */ - IPA_HANDLE_WAN_UP_V6, /* 27 NULL */ - IPA_HANDLE_WAN_DOWN_V6, /* 28 NULL */ - IPA_LAN_CLIENT_ACTIVE, /* 29 ipacm_event_lan_client*/ - IPA_LAN_CLIENT_INACTIVE, /* 30 ipacm_event_lan_client*/ - IPA_LAN_CLIENT_DISCONNECT, /* 31 ipacm_event_lan_client*/ - IPA_LAN_CLIENT_POWER_SAVE, /* 32 ipacm_event_lan_client*/ - IPA_LAN_CLIENT_POWER_RECOVER, /* 33 ipacm_event_lan_client*/ - IPA_LAN_TO_LAN_NEW_CONNECTION, /* 34 ipacm_event_connection */ - IPA_LAN_TO_LAN_DEL_CONNECTION, /* 35 ipacm_event_connection */ - IPA_LAN_DELETE_SELF, /* 36 ipacm_event_data_fid */ - IPA_WLAN_LINK_DOWN_EVENT, /* 37 ipacm_event_data_mac */ - IPA_USB_LINK_UP_EVENT, /* 38 ipacm_event_data_fid */ - IPA_PROCESS_CT_MESSAGE_V6, /* 39 ipacm_ct_evt_data */ - IPA_PRIVATE_SUBNET_CHANGE_EVENT, /* 40 ipacm_event_data_fid */ - IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, /* 41 ipacm_event_data_fid */ - IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, /* 42 ipacm_event_data_fid */ - IPA_WAN_EMBMS_LINK_UP_EVENT, /* 43 ipacm_event_data_mac */ - IPA_ETH_BRIDGE_LAN_CLIENT_ADD_EVENT, /* 44 ipacm_event_data_mac */ - IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT, /* 45 ipacm_event_data_mac */ - IPA_ETH_BRIDGE_LAN_CLIENT_DEL_EVENT, /* 46 ipacm_event_data_mac */ - IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT, /* 47 ipacm_event_data_mac */ - IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT, /* 48 ipacm_event_data_if_cat */ - IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT, /* 49 ipacm_event_data_if_cat */ - IPA_WLAN_SWITCH_TO_SCC, /* 50 No Data */ - IPA_WLAN_SWITCH_TO_MCC, /* 51 No Data */ - IPA_CRADLE_WAN_MODE_SWITCH, /* 52 ipacm_event_cradle_wan_mode */ - IPA_WAN_XLAT_CONNECT_EVENT, /* 53 ipacm_event_data_fid */ - IPA_TETHERING_STATS_UPDATE_EVENT, /* 54 ipacm_event_data_fid */ - IPA_NETWORK_STATS_UPDATE_EVENT, /* 55 ipacm_event_data_fid */ - IPA_HANDLE_WAN_UP_TETHER, /* 56 ipacm_event_iface_up_tehter */ - IPA_HANDLE_WAN_DOWN_TETHER, /* 57 ipacm_event_iface_up_tehter */ - IPA_HANDLE_WAN_UP_V6_TETHER, /* 58 ipacm_event_iface_up_tehter */ - IPA_HANDLE_WAN_DOWN_V6_TETHER, /* 59 ipacm_event_iface_up_tehter */ - IPA_BRIDGE_LINK_UP_EVENT, /* 60 ipacm_event_data_all */ + IPA_CFG_CHANGE_EVENT, /* NULL */ + IPA_PRIVATE_SUBNET_CHANGE_EVENT, /* ipacm_event_data_fid */ + IPA_FIREWALL_CHANGE_EVENT, /* NULL */ + IPA_LINK_UP_EVENT, /* ipacm_event_data_fid */ + IPA_LINK_DOWN_EVENT, /* ipacm_event_data_fid */ + IPA_USB_LINK_UP_EVENT, /* ipacm_event_data_fid */ + IPA_BRIDGE_LINK_UP_EVENT, /* ipacm_event_data_all */ + IPA_WAN_EMBMS_LINK_UP_EVENT, /* ipacm_event_data_mac */ + IPA_ADDR_ADD_EVENT, /* ipacm_event_data_addr */ + IPA_ADDR_DEL_EVENT, /* no use */ + IPA_ROUTE_ADD_EVENT, /* ipacm_event_data_addr */ + IPA_ROUTE_DEL_EVENT, /* ipacm_event_data_addr */ + IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT, /* ipacm_event_data_fid */ + IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT, /* ipacm_event_data_fid */ + IPA_WLAN_AP_LINK_UP_EVENT, /* ipacm_event_data_mac */ + IPA_WLAN_STA_LINK_UP_EVENT, /* ipacm_event_data_mac */ + IPA_WLAN_LINK_DOWN_EVENT, /* ipacm_event_data_mac */ + IPA_WLAN_CLIENT_ADD_EVENT, /* ipacm_event_data_mac */ + IPA_WLAN_CLIENT_ADD_EVENT_EX, /* ipacm_event_data_wlan_ex */ + IPA_WLAN_CLIENT_DEL_EVENT, /* ipacm_event_data_mac */ + IPA_WLAN_CLIENT_POWER_SAVE_EVENT, /* ipacm_event_data_mac */ + IPA_WLAN_CLIENT_RECOVER_EVENT, /* ipacm_event_data_mac */ + IPA_NEW_NEIGH_EVENT, /* ipacm_event_data_all */ + IPA_DEL_NEIGH_EVENT, /* ipacm_event_data_all */ + IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, /* ipacm_event_data_all */ + IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, /* ipacm_event_data_all */ + IPA_SW_ROUTING_ENABLE, /* NULL */ + IPA_SW_ROUTING_DISABLE, /* NULL */ + IPA_PROCESS_CT_MESSAGE, /* ipacm_ct_evt_data */ + IPA_PROCESS_CT_MESSAGE_V6, /* ipacm_ct_evt_data */ + IPA_LAN_TO_LAN_NEW_CONNECTION, /* ipacm_event_connection */ + IPA_LAN_TO_LAN_DEL_CONNECTION, /* ipacm_event_connection */ + IPA_WLAN_SWITCH_TO_SCC, /* No Data */ + IPA_WLAN_SWITCH_TO_MCC, /* No Data */ + IPA_CRADLE_WAN_MODE_SWITCH, /* ipacm_event_cradle_wan_mode */ + IPA_WAN_XLAT_CONNECT_EVENT, /* ipacm_event_data_fid */ + IPA_TETHERING_STATS_UPDATE_EVENT, /* ipacm_event_data_fid */ + IPA_NETWORK_STATS_UPDATE_EVENT, /* ipacm_event_data_fid */ + + IPA_EXTERNAL_EVENT_MAX, + + IPA_HANDLE_WAN_UP, /* ipacm_event_iface_up */ + IPA_HANDLE_WAN_DOWN, /* ipacm_event_iface_up */ + IPA_HANDLE_WAN_UP_V6, /* NULL */ + IPA_HANDLE_WAN_DOWN_V6, /* NULL */ + IPA_HANDLE_WAN_UP_TETHER, /* ipacm_event_iface_up_tehter */ + IPA_HANDLE_WAN_DOWN_TETHER, /* ipacm_event_iface_up_tehter */ + IPA_HANDLE_WAN_UP_V6_TETHER, /* ipacm_event_iface_up_tehter */ + IPA_HANDLE_WAN_DOWN_V6_TETHER, /* ipacm_event_iface_up_tehter */ + IPA_HANDLE_WLAN_UP, /* ipacm_event_iface_up */ + IPA_HANDLE_LAN_UP, /* ipacm_event_iface_up */ + IPA_ETH_BRIDGE_IFACE_UP, /* ipacm_event_eth_bridge*/ + IPA_ETH_BRIDGE_IFACE_DOWN, /* ipacm_event_eth_bridge*/ + IPA_ETH_BRIDGE_CLIENT_ADD, /* ipacm_event_eth_bridge */ + IPA_ETH_BRIDGE_CLIENT_DEL, /* ipacm_event_eth_bridge*/ + IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, /* ipacm_event_eth_bridge*/ + IPA_LAN_DELETE_SELF, /* ipacm_event_data_fid */ IPACM_EVENT_MAX } ipa_cm_event_id; @@ -269,12 +252,10 @@ typedef struct typedef struct { - enum ipa_ip_type iptype; - uint32_t ipv4_addr; - uint32_t ipv6_addr[4]; + IPACM_Lan *p_iface; + ipa_ip_type iptype; uint8_t mac_addr[6]; - IPACM_Lan* p_iface; -} ipacm_event_lan_client; +} ipacm_event_eth_bridge; typedef struct { @@ -318,6 +299,7 @@ typedef struct _ipacm_event_data_addr typedef struct _ipacm_event_data_mac { int if_index; + int ipa_if_cate; uint8_t mac_addr[IPA_MAC_ADDR_SIZE]; } ipacm_event_data_mac; diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Filtering.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Filtering.h index 7554ba9..9bb8247 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Filtering.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Filtering.h @@ -1,5 +1,5 @@ -/* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +/* +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 @@ -53,6 +53,7 @@ public: IPACM_Filtering(); ~IPACM_Filtering(); bool AddFilteringRule(struct ipa_ioc_add_flt_rule const *ruleTable); + bool AddFilteringRuleAfter(struct ipa_ioc_add_flt_rule_after const *ruleTable); bool DeleteFilteringRule(struct ipa_ioc_del_flt_rule *ruleTable); bool Commit(enum ipa_ip_type ip); bool Reset(enum ipa_ip_type ip); diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Iface.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Iface.h index efcaa63..89bb26f 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Iface.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Iface.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -81,7 +81,7 @@ public: int ipa_if_num; /* IPACM interface category */ - int ipa_if_cate; + ipacm_iface_type ipa_if_cate; /* IPACM interface name */ char dev_name[IF_NAME_LEN]; @@ -92,8 +92,6 @@ public: /* IPACM interface v6 ip-address*/ uint32_t ipv6_addr[MAX_DEFAULT_v6_ROUTE_RULES][4]; - uint32_t header_hdl; - uint32_t software_routing_fl_rule_hdl[MAX_SOFTWAREROUTING_FILTERTING_RULES]; bool softwarerouting_act; @@ -128,12 +126,6 @@ public: /*Query the IPA endpoint property */ int query_iface_property(void); - /*implement IPACM strlcpy */ - size_t strlcpy(char *dest, const char *src, size_t size); - - /*implement IPACM strlcat */ - size_t strlcat(char *dest, const char *src, size_t n); - /*Configure the initial filter rules */ virtual int init_fl_rule(ipa_ip_type iptype); diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_IfaceManager.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_IfaceManager.h index e65c5d5..c7184f2 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_IfaceManager.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_IfaceManager.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -48,7 +48,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "IPACM_Listener.h" #include "IPACM_Iface.h" -#define IPA_MAX_NUM_NEIGHBOR_CLIENTS 17 #define IPA_INSTANCE_NOT_FOUND 0 #define IPA_INSTANCE_FOUND 1 diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Lan.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Lan.h index a210255..6c54f5e 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Lan.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Lan.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -73,18 +73,6 @@ struct ipa_lan_rt_rule uint32_t rt_rule_hdl[0]; }; -typedef enum -{ - SRC_WLAN, - SRC_LAN -} eth_bridge_src_iface; - -typedef enum -{ - DST_WLAN, - DST_LAN -} eth_bridge_dst_iface; - /* Support multiple eth client */ typedef struct _eth_client_rt_hdl { @@ -109,44 +97,6 @@ typedef struct _ipa_eth_client eth_client_rt_hdl eth_rt_hdl[0]; /* depends on number of tx properties */ }ipa_eth_client; -struct lan2lan_flt_rule_hdl -{ - uint32_t rule_hdl; - bool valid; -}; - -struct lan2lan_hdr_hdl -{ - uint32_t hdr_hdl; - bool valid; -}; - -struct eth_bridge_client_flt_info -{ - uint8_t mac[IPA_MAC_ADDR_SIZE]; - uint32_t flt_rule_hdl_v4; - bool flt_rule_set_v4; - uint32_t flt_rule_hdl_v6; - bool flt_rule_set_v6; -}; - -struct eth_bridge_client_rt_info -{ - uint8_t mac[IPA_MAC_ADDR_SIZE]; - uint32_t rt_rule_hdl[0]; -}; - -struct hdr_proc_ctx_info -{ - uint32_t proc_ctx_hdl; - bool valid; -}; - -struct eth_bridge_subnet_client_info -{ - uint8_t mac[IPA_MAC_ADDR_SIZE]; - int ipa_if_num; -}; /* lan iface */ class IPACM_Lan : public IPACM_Iface @@ -191,110 +141,46 @@ public: /* install UL filter rule from Q6 */ virtual int handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype, uint8_t xlat_mux_id); - int add_lan2lan_flt_rule(ipa_ip_type iptype, uint32_t src_v4_addr, uint32_t dst_v4_addr, uint32_t* src_v6_addr, uint32_t* dst_v6_addr, uint32_t* rule_hdl); - - int del_lan2lan_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl); - - virtual int add_lan2lan_hdr(ipa_ip_type iptype, uint8_t* src_mac, uint8_t* dst_mac, uint32_t* hdr_hdl); - - int add_lan2lan_rt_rule(ipa_ip_type iptype, uint32_t src_v4_addr, uint32_t dst_v4_addr, - uint32_t* src_v6_addr, uint32_t* dst_v6_addr, uint32_t hdr_hdl, lan_to_lan_rt_rule_hdl* rule_hdl); - - int del_lan2lan_rt_rule(ipa_ip_type iptype, lan_to_lan_rt_rule_hdl); - - int del_lan2lan_hdr(ipa_ip_type iptype, uint32_t hdr_hdl); - int handle_cradle_wan_mode_switch(bool is_wan_bridge_mode); int install_ipv4_icmp_flt_rule(); - static ipa_hdr_l2_type lan_hdr_type; - static ipa_hdr_l2_type wlan_hdr_type; - static uint32_t usb_hdr_template_hdl; - static uint32_t wlan_hdr_template_hdl; - static uint32_t cpe_hdr_template_hdl; + /* add header processing context and return handle to lan2lan controller */ + int eth_bridge_add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_hdr_type, uint32_t *hdl); - static hdr_proc_ctx_info lan_to_wlan_hdr_proc_ctx, wlan_to_usb_hdr_proc_ctx, wlan_to_cpe_hdr_proc_ctx; - static hdr_proc_ctx_info wlan_to_wlan_hdr_proc_ctx; - static hdr_proc_ctx_info cpe_to_usb_hdr_proc_ctx, usb_to_cpe_hdr_proc_ctx; + /* add routing rule and return handle to lan2lan controller */ + int eth_bridge_add_rt_rule(uint8_t *mac, char *rt_tbl_name, uint32_t hdr_proc_ctx_hdl, + ipa_hdr_l2_type peer_l2_hdr_type, ipa_ip_type iptype, uint32_t *rt_rule_hdl, int *rt_rule_count); - static eth_bridge_subnet_client_info eth_bridge_wlan_client[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; - static eth_bridge_subnet_client_info eth_bridge_lan_client[IPA_LAN_TO_LAN_MAX_LAN_CLIENT]; + /* modify routing rule*/ + int eth_bridge_modify_rt_rule(uint8_t *mac, uint32_t hdr_proc_ctx_hdl, + ipa_hdr_l2_type peer_l2_hdr_type, ipa_ip_type iptype, uint32_t *rt_rule_hdl, int rt_rule_count); - static int num_wlan_client; - static int num_lan_client; + /* add filtering rule and return handle to lan2lan controller */ + int eth_bridge_add_flt_rule(uint8_t *mac, uint32_t rt_tbl_hdl, ipa_ip_type iptype, uint32_t *flt_rule_hdl); - static bool is_usb_up; - static bool is_cpe_up; + /* delete filtering rule */ + int eth_bridge_del_flt_rule(uint32_t flt_rule_hdl, ipa_ip_type iptype); -protected: - - lan2lan_flt_rule_hdl wlan_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; - lan2lan_flt_rule_hdl wlan_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; - lan2lan_flt_rule_hdl lan_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_LAN_CLIENT]; - lan2lan_flt_rule_hdl lan_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_LAN_CLIENT]; - - eth_bridge_client_flt_info eth_bridge_wlan_client_flt_info[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; - eth_bridge_client_flt_info eth_bridge_lan_client_flt_info[IPA_LAN_TO_LAN_MAX_LAN_CLIENT]; - - int wlan_client_flt_info_count; - int lan_client_flt_info_count; - - int client_rt_info_size_v4; - int client_rt_info_size_v6; - - eth_bridge_client_rt_info* eth_bridge_lan_client_rt_from_lan_info_v4; - int lan_client_rt_from_lan_info_count_v4; - eth_bridge_client_rt_info* eth_bridge_lan_client_rt_from_lan_info_v6; - int lan_client_rt_from_lan_info_count_v6; - eth_bridge_client_rt_info* eth_bridge_lan_client_rt_from_wlan_info_v4; - int lan_client_rt_from_wlan_info_count_v4; - eth_bridge_client_rt_info* eth_bridge_lan_client_rt_from_wlan_info_v6; - int lan_client_rt_from_wlan_info_count_v6; - - int each_client_rt_rule_count_v4; - int each_client_rt_rule_count_v6; - - virtual int eth_bridge_handle_dummy_wlan_client_flt_rule(ipa_ip_type iptype); - - virtual int eth_bridge_handle_dummy_lan_client_flt_rule(ipa_ip_type iptype); - - int eth_bridge_add_lan_client_flt_rule(uint8_t* mac, ipa_ip_type iptype); - - int eth_bridge_del_lan_client_flt_rule(uint8_t* mac); - - int eth_bridge_add_wlan_client_flt_rule(uint8_t* mac, ipa_ip_type iptype); - - int eth_bridge_del_wlan_client_flt_rule(uint8_t* mac); - - int eth_bridge_post_lan_client_event(uint8_t* mac_addr, ipa_cm_event_id evt); - - int add_hdr_proc_ctx(); - - int del_hdr_proc_ctx(); + /* delete routing rule */ + int eth_bridge_del_rt_rule(uint32_t rt_rule_hdl, ipa_ip_type iptype); - ipa_hdr_proc_type get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2); + /* delete header processing context */ + int eth_bridge_del_hdr_proc_ctx(uint32_t hdr_proc_ctx_hdl); - virtual int eth_bridge_install_cache_wlan_client_flt_rule(ipa_ip_type iptype); - virtual int eth_bridge_install_cache_lan_client_flt_rule(ipa_ip_type iptype); - int eth_bridge_add_lan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src, ipa_ip_type iptype); - - int eth_bridge_del_lan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src); - - eth_bridge_client_rt_info* eth_bridge_get_client_rt_info_ptr(uint8_t index, eth_bridge_src_iface src, ipa_ip_type iptype); - - void eth_bridge_add_lan_client(uint8_t* mac); +protected: - void eth_bridge_del_lan_client(uint8_t* mac); + int each_client_rt_rule_count[IPA_IP_MAX]; - int eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl); + uint32_t eth_bridge_flt_rule_offset[IPA_IP_MAX]; + /* mac address has to be provided for client related events */ + void eth_bridge_post_event(ipa_cm_event_id evt, ipa_ip_type iptype, uint8_t *mac); - virtual int add_dummy_lan2lan_flt_rule(ipa_ip_type iptype); virtual int add_dummy_private_subnet_flt_rule(ipa_ip_type iptype); @@ -302,9 +188,6 @@ protected: int reset_to_dummy_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl); - /*handle lan2lan client active*/ - int handle_lan2lan_client_active(ipacm_event_data_all *data, ipa_cm_event_id event); - virtual int install_ipv6_prefix_flt_rule(uint32_t* prefix); virtual void delete_ipv6_prefix_flt_rule(); @@ -319,26 +202,13 @@ protected: /* handle tethering client */ int handle_tethering_client(bool reset, ipacm_client_enum ipa_client); - lan2lan_flt_rule_hdl lan2lan_flt_rule_hdl_v4[MAX_OFFLOAD_PAIR]; - lan2lan_flt_rule_hdl lan2lan_flt_rule_hdl_v6[MAX_OFFLOAD_PAIR]; - - uint8_t num_lan2lan_flt_rule_v4; - uint8_t num_lan2lan_flt_rule_v6; - - lan2lan_hdr_hdl lan2lan_hdr_hdl_v4[MAX_OFFLOAD_PAIR]; - lan2lan_hdr_hdl lan2lan_hdr_hdl_v6[MAX_OFFLOAD_PAIR]; - /* store ipv4 UL filter rule handlers from Q6*/ uint32_t wan_ul_fl_rule_hdl_v4[MAX_WAN_UL_FILTER_RULES]; /* store ipv6 UL filter rule handlers from Q6*/ uint32_t wan_ul_fl_rule_hdl_v6[MAX_WAN_UL_FILTER_RULES]; - virtual void install_tcp_ctl_flt_rule(ipa_ip_type iptype); - uint32_t ipv4_icmp_flt_rule_hdl[NUM_IPV4_ICMP_FLT_RULE]; - uint32_t tcp_ctl_flt_rule_hdl_v4[NUM_TCP_CTL_FLT_RULE]; - uint32_t tcp_ctl_flt_rule_hdl_v6[NUM_TCP_CTL_FLT_RULE]; uint32_t ipv6_prefix_flt_rule_hdl[NUM_IPV6_PREFIX_FLT_RULE]; uint32_t ipv6_icmp_flt_rule_hdl[NUM_IPV6_ICMP_FLT_RULE]; @@ -352,12 +222,17 @@ protected: uint32_t if_ipv4_subnet; - /* expected modem UL rules starting index */ - int exp_index_v4; - int exp_index_v6; + uint32_t ipv6_prefix[2]; private: + /* get hdr proc ctx type given source and destination l2 hdr type */ + ipa_hdr_proc_type eth_bridge_get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2); + + /* get partial header (header template of hdr proc ctx) */ + int eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl); + + /* dynamically allocate lan iface's unicast routing rule structure */ bool is_mode_switch; /* indicate mode switch, need post internal up event */ @@ -508,9 +383,6 @@ private: /*handle lan iface down event*/ int handle_down_evt(); - /*handle lan2lan internal mesg posting*/ - int post_lan2lan_client_disconnect_msg(ipa_ip_type iptype); - /*handle reset usb-client rt-rules */ int handle_lan_client_reset_rt(ipa_ip_type iptype); }; diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_LanToLan.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_LanToLan.h index 06d5832..a28631e 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_LanToLan.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_LanToLan.h @@ -42,7 +42,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "IPACM_Iface.h" #include "IPACM_Defs.h" #include "IPACM_Lan.h" -#include <unordered_map> #ifdef FEATURE_IPA_ANDROID #include <libxml/list.h> @@ -50,125 +49,153 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <list> #endif /* ndefined(FEATURE_IPA_ANDROID)*/ -struct client_info; +#define MAX_NUM_CACHED_CLIENT_ADD_EVENT 10 +#define MAX_NUM_IFACE 10 +#define MAX_NUM_CLIENT 16 -struct peer_info +struct rt_rule_info { - struct client_info* peer_pointer; - int num_connection; + int num_hdl[IPA_IP_MAX]; /* one client may need more than one routing rules on the same routing table depending on tx_prop */ + uint32_t rule_hdl[IPA_IP_MAX][MAX_NUM_PROP]; }; -//used to store rule handles for offload link (one direction) -struct offload_link_info +struct client_info { - struct client_info* peer_pointer; - uint32_t flt_rule_hdl; - lan_to_lan_rt_rule_hdl rt_rule_hdl; - uint32_t hdr_hdl; + uint8_t mac_addr[6]; + rt_rule_info inter_iface_rt_rule_hdl[IPA_HDR_L2_MAX]; /* routing rule handles of inter interface communication based on source l2 header type */ + rt_rule_info intra_iface_rt_rule_hdl; /* routing rule handles of inter interface communication */ }; -typedef list<peer_info> peer_info_list; -typedef list<offload_link_info> offload_link_info_list; -typedef list<ipacm_event_connection> connection_list; - -struct client_info +struct flt_rule_info { - union - { - uint32_t ipv4_addr; - uint32_t ipv6_addr[4]; - } ip; - uint8_t mac_addr[6]; - bool is_active; - bool is_powersave; - IPACM_Lan* p_iface; - peer_info_list peer; - offload_link_info_list link; + client_info *p_client; + uint32_t flt_rule_hdl[IPA_IP_MAX]; }; -struct v6_addr +struct peer_iface_info { - uint32_t ipv6_addr[4]; + class IPACM_LanToLan_Iface *peer; + char rt_tbl_name_for_rt[IPA_IP_MAX][IPA_RESOURCE_NAME_MAX]; + char rt_tbl_name_for_flt[IPA_IP_MAX][IPA_RESOURCE_NAME_MAX]; + list<flt_rule_info> flt_rule; }; -typedef unordered_map<uint32_t, client_info> client_table_v4; -typedef unordered_map<uint64_t, client_info> client_table_v6; +class IPACM_LanToLan_Iface +{ +public: + IPACM_LanToLan_Iface(IPACM_Lan *p_iface); + ~IPACM_LanToLan_Iface(); + void add_client_rt_rule_for_new_iface(); -class IPACM_LanToLan : public IPACM_Listener -{ + void add_all_inter_interface_client_flt_rule(ipa_ip_type iptype); -public: + void add_all_intra_interface_client_flt_rule(ipa_ip_type iptype); + + void handle_down_event(); + + void handle_wlan_scc_mcc_switch(); + + void handle_intra_interface_info(); + + void handle_new_iface_up(char rt_tbl_name_for_flt[][IPA_RESOURCE_NAME_MAX], char rt_tbl_name_for_rt[][IPA_RESOURCE_NAME_MAX], + IPACM_LanToLan_Iface *peer_iface); + + void handle_client_add(uint8_t *mac); + + void handle_client_del(uint8_t *mac); - IPACM_LanToLan(); - ~IPACM_LanToLan(); + void print_data_structure_info(); - void handle_new_connection(ipacm_event_connection* new_conn); - void handle_del_connection(ipacm_event_connection* del_conn); + IPACM_Lan* get_iface_pointer(); - static IPACM_LanToLan* getLan2LanInstance(); + bool get_m_is_ip_addr_assigned(ipa_ip_type iptype); + + void set_m_is_ip_addr_assigned(ipa_ip_type iptype, bool value); + + bool get_m_support_inter_iface_offload(); + + bool get_m_support_intra_iface_offload(); + + void increment_ref_cnt_peer_l2_hdr_type(ipa_hdr_l2_type peer_l2_type); + + void decrement_ref_cnt_peer_l2_hdr_type(ipa_hdr_l2_type peer_l2_type); private: - uint8_t num_offload_pair_v4_; - uint8_t num_offload_pair_v6_; - client_table_v4 client_info_v4_; - client_table_v6 client_info_v6_; + IPACM_Lan *m_p_iface; + bool m_is_ip_addr_assigned[IPA_IP_MAX]; + bool m_support_inter_iface_offload; + bool m_support_intra_iface_offload; + + int ref_cnt_peer_l2_hdr_type[IPA_HDR_L2_MAX]; /* reference count of l2 header type of peer interfaces */ + uint32_t hdr_proc_ctx_for_inter_interface[IPA_HDR_L2_MAX]; + uint32_t hdr_proc_ctx_for_intra_interface; - connection_list connection_v4_; - connection_list connection_v6_; + list<client_info> m_client_info; /* client list */ + list<peer_iface_info> m_peer_iface_info; /* peer information list */ - static IPACM_LanToLan* p_instance; + /* The following members are for intra-interface communication*/ + peer_iface_info m_intra_interface_info; - void event_callback(ipa_cm_event_id event, void* param); + void add_one_client_flt_rule(IPACM_LanToLan_Iface *peer_iface, client_info *client); - void handle_client_active(ipacm_event_lan_client* data); + void add_client_flt_rule(peer_iface_info *peer, client_info *client, ipa_ip_type iptype); - void check_potential_link(ipa_ip_type iptype, client_info* client); + void del_one_client_flt_rule(IPACM_LanToLan_Iface *peer_iface, client_info *client); - int add_offload_link(ipa_ip_type iptype, client_info* client, client_info* peer); + void del_client_flt_rule(peer_iface_info *peer, client_info *client); - void handle_client_inactive(ipacm_event_lan_client* data); + void add_client_rt_rule(peer_iface_info *peer, client_info *client); - int turnoff_offload_links(ipa_ip_type iptype, client_info* client); + void del_client_rt_rule(peer_iface_info *peer, client_info *client); - int del_offload_link(ipa_ip_type iptype, IPACM_Lan* client, IPACM_Lan* peer, offload_link_info* link); + void clear_all_flt_rule_for_one_peer_iface(peer_iface_info *peer); - void handle_client_disconnect(ipacm_event_lan_client* data); + void clear_all_rt_rule_for_one_peer_iface(peer_iface_info *peer); - int clear_peer_list(client_info* client); + void add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_type); - void handle_client_power_save(ipacm_event_lan_client* data); + void del_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_type); - void handle_client_power_recover(ipacm_event_lan_client* data); + void print_peer_info(peer_iface_info *peer_info); + +}; - int remove_flt_rules(ipa_ip_type iptype, client_info* client); +class IPACM_LanToLan : public IPACM_Listener +{ + +public: + + IPACM_LanToLan(); + +private: - int add_flt_rules(ipa_ip_type iptype, client_info* client); + ~IPACM_LanToLan(); -//the following are for connections + list<class IPACM_LanToLan_Iface> m_iface; - void handle_new_lan2lan_connection(ipacm_event_connection* data); + list<ipacm_event_eth_bridge> m_cached_client_add_event; - bool add_connection(client_info* src_client, client_info* dst_client); + void handle_iface_up(ipacm_event_eth_bridge *data); - void handle_del_lan2lan_connection(ipacm_event_connection* data); + void handle_iface_down(ipacm_event_eth_bridge *data); - bool remove_connection(client_info* src_client, client_info* dst_client); + void handle_client_add(ipacm_event_eth_bridge *data); - void erase_offload_link(ipa_ip_type iptype, client_info* src_client, client_info* dst_client); + void handle_client_del(ipacm_event_eth_bridge *data); - void generate_new_connection(ipa_ip_type iptype, client_info* client); + void handle_wlan_scc_mcc_switch(ipacm_event_eth_bridge *data); - bool is_lan2lan_connection(ipacm_event_connection* data); + void handle_new_iface_up(IPACM_LanToLan_Iface *new_iface, IPACM_LanToLan_Iface *exist_iface); - bool is_potential_lan2lan_connection(ipacm_event_connection* new_conn); + void event_callback(ipa_cm_event_id event, void* param); - void cache_new_connection(ipacm_event_connection* new_conn); + void handle_cached_client_add_event(IPACM_Lan *p_iface); - void remove_cache_connection(ipacm_event_connection* del_conn); + void clear_cached_client_add_event(IPACM_Lan *p_iface); - void check_cache_connection(ipa_ip_type iptype, client_info* client); + void print_data_structure_info(); }; diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Log.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Log.h index 8fce44e..dab0280 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Log.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Log.h @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -68,7 +68,9 @@ static char buffer_send[MAX_BUF_LEN]; static char dmesg_cmd[MAX_BUF_LEN]; #define IPACMDBG_DMESG(fmt, ...) memset(buffer_send, 0, MAX_BUF_LEN);\ - snprintf(buffer_send,MAX_BUF_LEN,"%s:%d %s: " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\ + snprintf(buffer_send,MAX_BUF_LEN,"%s:%d %s: " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\ + ipacm_log_send (buffer_send);\ + printf("%s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \ memset(dmesg_cmd, 0, MAX_BUF_LEN);\ snprintf(dmesg_cmd, MAX_BUF_LEN, "echo %s > /dev/kmsg", buffer_send);\ system(dmesg_cmd); @@ -78,9 +80,9 @@ static char dmesg_cmd[MAX_BUF_LEN]; ipacm_log_send (buffer_send); \ perror(fmt); #define IPACMERR(fmt, ...) memset(buffer_send, 0, MAX_BUF_LEN);\ - snprintf(buffer_send,MAX_BUF_LEN,"ERR: %s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\ + snprintf(buffer_send,MAX_BUF_LEN,"ERROR: %s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\ ipacm_log_send (buffer_send);\ - printf("ERR: %s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); + printf("ERROR: %s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); #define IPACMDBG_H(fmt, ...) memset(buffer_send, 0, MAX_BUF_LEN);\ snprintf(buffer_send,MAX_BUF_LEN,"%s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\ ipacm_log_send (buffer_send);\ diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Routing.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Routing.h index 4f5488f..b5ffabc 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Routing.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Routing.h @@ -61,7 +61,6 @@ public: bool Reset(enum ipa_ip_type ip); bool GetRoutingTable(struct ipa_ioc_get_rt_tbl *routingTable); - bool PutRoutingTable(uint32_t routingTableHandle); bool DeviceNodeIsOpened(); bool DeleteRoutingHdl(uint32_t rt_rule_hdl, ipa_ip_type ip); @@ -71,6 +70,8 @@ public: private: static const char *DEVICE_NAME; int m_fd; /* File descriptor of the IPA device node /dev/ipa */ + + bool PutRoutingTable(uint32_t routingTableHandle); }; #endif //IPACM_ROUTING_H diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Wan.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Wan.h index 711f276..e42358f 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Wan.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Wan.h @@ -97,6 +97,7 @@ public: static uint8_t xlat_mux_id; /* IPACM interface name */ static char wan_up_dev_name[IF_NAME_LEN]; + static uint32_t curr_wan_ip; IPACM_Wan(int, ipacm_wan_iface_type, uint8_t *); virtual ~IPACM_Wan(); @@ -140,6 +141,11 @@ public: #endif } + static uint32_t getWANIP() + { + return curr_wan_ip; + } + static bool getXlat_Mux_Id() { return xlat_mux_id; @@ -202,6 +208,7 @@ private: bool header_partial_default_wan_v4; bool header_partial_default_wan_v6; uint8_t ext_router_mac_addr[IPA_MAC_ADDR_SIZE]; + uint8_t netdev_mac[IPA_MAC_ADDR_SIZE]; static int num_ipv4_modem_pdn; @@ -228,6 +235,8 @@ private: /* update network stats for CNE */ int ipa_network_stats_fd; + uint32_t hdr_hdl_dummy_v6; + uint32_t hdr_proc_hdl_dummy_v6; inline ipa_wan_client* get_client_memptr(ipa_wan_client *param, int cnt) { @@ -476,6 +485,7 @@ private: bool is_global_ipv6_addr(uint32_t* ipv6_addr); void handle_wlan_SCC_MCC_switch(bool, ipa_ip_type); + void handle_wan_client_SCC_MCC_switch(bool, ipa_ip_type); int handle_network_stats_evt(); @@ -483,6 +493,9 @@ private: int m_fd_ipa; int handle_network_stats_update(ipa_get_apn_data_stats_resp_msg_v01 *data); + + /* construct dummy ethernet header */ + int add_dummy_rx_hdr(); }; #endif /* IPACM_WAN_H */ diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Wlan.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Wlan.h index 6a2d53a..eb911ac 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Wlan.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Wlan.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -85,61 +85,16 @@ public: static int total_num_wifi_clients; - void event_callback(ipa_cm_event_id event, - void *data); + void event_callback(ipa_cm_event_id event, void *data); - virtual int add_lan2lan_hdr(ipa_ip_type iptype, uint8_t* src_mac, uint8_t* dst_mac, uint32_t* hdr_hdl); + bool is_guest_ap(); private: - eth_bridge_client_flt_info eth_bridge_lan_client_flt_info[IPA_LAN_TO_LAN_MAX_LAN_CLIENT]; - int lan_client_flt_info_count; + bool m_is_guest_ap; - static lan2lan_flt_rule_hdl self_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; - static lan2lan_flt_rule_hdl self_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; - - static lan2lan_flt_rule_hdl lan_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_LAN_CLIENT]; - static lan2lan_flt_rule_hdl lan_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_LAN_CLIENT]; - - bool is_guest_ap; - - eth_bridge_client_rt_info* eth_bridge_wlan_client_rt_from_lan_info_v4; - int wlan_client_rt_from_lan_info_count_v4; - eth_bridge_client_rt_info* eth_bridge_wlan_client_rt_from_lan_info_v6; - int wlan_client_rt_from_lan_info_count_v6; - - eth_bridge_client_rt_info* eth_bridge_wlan_client_rt_from_wlan_info_v4; - int wlan_client_rt_from_wlan_info_count_v4; - eth_bridge_client_rt_info* eth_bridge_wlan_client_rt_from_wlan_info_v6; - int wlan_client_rt_from_wlan_info_count_v6; - - int eth_bridge_install_wlan_guest_ap_ipv6_flt_rule(); - - virtual int eth_bridge_handle_dummy_wlan_client_flt_rule(ipa_ip_type iptype); - - virtual int eth_bridge_handle_dummy_lan_client_flt_rule(ipa_ip_type iptype); - - int eth_bridge_add_lan_client_flt_rule(uint8_t* mac, ipa_ip_type iptype); - - int eth_bridge_del_lan_client_flt_rule(uint8_t* mac); - - int eth_bridge_add_self_client_flt_rule(uint8_t* mac, ipa_ip_type iptype); - - int eth_bridge_del_self_client_flt_rule(uint8_t* mac); - - virtual int eth_bridge_install_cache_wlan_client_flt_rule(ipa_ip_type iptype); - - virtual int eth_bridge_install_cache_lan_client_flt_rule(ipa_ip_type iptype); - - int eth_bridge_add_wlan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src, ipa_ip_type iptype); - - int eth_bridge_del_wlan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src); - - eth_bridge_client_rt_info* eth_bridge_get_client_rt_info_ptr(uint8_t index, eth_bridge_src_iface src, ipa_ip_type iptype); - - void eth_bridge_add_wlan_client(uint8_t* mac, int if_num); - - void eth_bridge_del_wlan_client(uint8_t* mac); + /* handle wlan access mode switch in ethernet bridging*/ + void eth_bridge_handle_wlan_mode_switch(); int wlan_client_len; @@ -150,9 +105,6 @@ private: int wlan_ap_index; - static uint32_t* dummy_flt_rule_hdl_v4; - static uint32_t* dummy_flt_rule_hdl_v6; - static int num_wlan_ap_iface; NatApp *Nat_App; @@ -262,9 +214,6 @@ private: /* for handle wifi client initial,copy all partial headers (tx property) */ int handle_wlan_client_init_ex(ipacm_event_data_wlan_ex *data); - /*handle lan2lan internal mesg posting*/ - int handle_lan2lan_msg_post(uint8_t *mac_addr, ipa_cm_event_id event, ipa_ip_type iptype); - /*handle wifi client */ int handle_wlan_client_ipaddr(ipacm_event_data_all *data); @@ -280,49 +229,11 @@ private: /*handle wlan iface down event*/ int handle_down_evt(); - /* add dummy filtering rules for WLAN AP-AP mode support */ - void add_dummy_flt_rule(); - - /* install dummy filtering rules for WLAN AP-AP mode support */ - int install_dummy_flt_rule(ipa_ip_type iptype, int num_rule); - - /* delete dummy flt rule for WLAN AP-AP mode support*/ - void del_dummy_flt_rule(); - - /*Configure the initial filter rules */ - virtual int init_fl_rule(ipa_ip_type iptype); - - virtual int add_dummy_lan2lan_flt_rule(ipa_ip_type iptype); - - virtual int add_dummy_private_subnet_flt_rule(ipa_ip_type iptype); - - /*configure private subnet filter rules*/ - virtual int handle_private_subnet(ipa_ip_type iptype); - - /* install UL filter rule from Q6 */ - virtual int handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype, uint8_t xlat_mux_id); - - /* install TCP control filter rules */ - virtual void install_tcp_ctl_flt_rule(ipa_ip_type iptype); - /*handle reset wifi-client rt-rules */ int handle_wlan_client_reset_rt(ipa_ip_type iptype); void handle_SCC_MCC_switch(ipa_ip_type); - void eth_bridge_handle_wlan_SCC_MCC_switch(ipa_ip_type iptype); - - int eth_bridge_modify_wlan_client_flt_rule(uint8_t* mac, eth_bridge_dst_iface dst_iface, ipa_ip_type iptype); - - int eth_bridge_modify_wlan_rt_rule(uint8_t* mac, eth_bridge_src_iface src_iface, ipa_ip_type iptyp); - - /*handle wlan access mode switch */ - void eth_bridge_handle_wlan_mode_switch(); - - virtual int install_ipv6_prefix_flt_rule(uint32_t* prefix); - - virtual void delete_ipv6_prefix_flt_rule(); - }; diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Xml.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Xml.h index f645ae1..64c00ed 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Xml.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Xml.h @@ -178,6 +178,9 @@ if (!(a)) { \ #define IPACMNat_TAG "IPACMNAT" #define NAT_MaxEntries_TAG "MaxNatEntries" +#define IP_PassthroughFlag_TAG "IPPassthroughFlag" +#define IP_PassthroughMode_TAG "IPPassthroughMode" + /*--------------------------------------------------------------------------- IP protocol numbers - use in dss_socket() to identify protocols. Also contains the extension header types for IPv6. @@ -276,6 +279,7 @@ typedef struct _IPACM_conf_t bool router_mode_enable; bool odu_embms_enable; int num_wlan_guest_ap; + bool ip_passthrough_mode; } IPACM_conf_t; /* This function read IPACM XML configuration*/ diff --git a/data-ipa-cfg-mgr/ipacm/src/Android.mk b/data-ipa-cfg-mgr/ipacm/src/Android.mk index b1536ed..c7c879b 100644 --- a/data-ipa-cfg-mgr/ipacm/src/Android.mk +++ b/data-ipa-cfg-mgr/ipacm/src/Android.mk @@ -1,3 +1,10 @@ +BOARD_PLATFORM_LIST := msm8916 +BOARD_PLATFORM_LIST += msm8909 +BOARD_PLATFORM_LIST += msm8937 +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) @@ -25,6 +32,10 @@ ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT))) LOCAL_CFLAGS += -DDEBUG endif +ifeq ($(TARGET_BOARD_PLATFORM),msm8998) +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 @@ -83,3 +94,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(LOCAL_MODULE) LOCAL_MODULE_OWNER := ipacm include $(BUILD_PREBUILT) + +endif # $(TARGET_ARCH) +endif +endif diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_CmdQueue.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_CmdQueue.cpp index 7e48546..a17fb08 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_CmdQueue.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_CmdQueue.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -40,24 +40,42 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #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 = NULL; -MessageQueue* MessageQueue::getInstance() +MessageQueue* MessageQueue::inst_internal = NULL; +MessageQueue* MessageQueue::inst_external = NULL; + +MessageQueue* MessageQueue::getInstanceInternal() { - if(inst == NULL) + if(inst_internal == NULL) { - inst = new MessageQueue(); - if(inst == NULL) + inst_internal = new MessageQueue(); + if(inst_internal == NULL) { - IPACMERR("unable to create Message Queue instance\n"); + IPACMERR("unable to create internal Message Queue instance\n"); return NULL; } } - return inst; + 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) @@ -101,14 +119,22 @@ Message* MessageQueue::dequeue(void) void* MessageQueue::Process(void *param) { - MessageQueue *MsgQueue = NULL; + MessageQueue *MsgQueueInternal = NULL; + MessageQueue *MsgQueueExternal = NULL; Message *item = NULL; IPACMDBG("MessageQueue::Process()\n"); - MsgQueue = MessageQueue::getInstance(); - if(MsgQueue == NULL) + 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 cmd queue process\n"); + IPACMERR("unable to start external cmd queue process\n"); return NULL; } @@ -120,7 +146,21 @@ void* MessageQueue::Process(void *param) return NULL; } - item = MsgQueue->dequeue(); + 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) { diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp index c718603..df6c888 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -47,6 +47,67 @@ 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; @@ -80,11 +141,6 @@ IPACM_Config::IPACM_Config() memset(&ext_prop_v4, 0, sizeof(ext_prop_v4)); memset(&ext_prop_v6, 0, sizeof(ext_prop_v6)); - memset(&rt_tbl_eth_bridge_lan_wlan_v4, 0, sizeof(rt_tbl_eth_bridge_lan_wlan_v4)); - memset(&rt_tbl_eth_bridge_wlan_wlan_v4, 0, sizeof(rt_tbl_eth_bridge_wlan_wlan_v4)); - memset(&rt_tbl_eth_bridge_lan_wlan_v6, 0, sizeof(rt_tbl_eth_bridge_lan_wlan_v6)); - memset(&rt_tbl_eth_bridge_wlan_wlan_v6, 0, sizeof(rt_tbl_eth_bridge_wlan_wlan_v6)); - qmap_id = ~0; memset(flt_rule_count_v4, 0, (IPA_CLIENT_CONS - IPA_CLIENT_PROD)*sizeof(int)); @@ -230,6 +286,10 @@ int IPACM_Config::Init(void) 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); @@ -276,30 +336,6 @@ int IPACM_Config::Init(void) 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)); - rt_tbl_lan2lan_v4.ip = IPA_IP_v4; - strncpy(rt_tbl_lan2lan_v4.name, V4_LAN_TO_LAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_lan2lan_v4.name)); - - rt_tbl_lan2lan_v6.ip = IPA_IP_v6; - strncpy(rt_tbl_lan2lan_v6.name, V6_LAN_TO_LAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_lan2lan_v6.name)); - - rt_tbl_eth_bridge_lan_lan_v4.ip = IPA_IP_v4; - strncpy(rt_tbl_eth_bridge_lan_lan_v4.name, ETH_BRIDGE_USB_CPE_ROUTE_TABLE_NAME_V4, sizeof(rt_tbl_eth_bridge_lan_lan_v4.name)); - - rt_tbl_eth_bridge_lan_wlan_v4.ip = IPA_IP_v4; - strncpy(rt_tbl_eth_bridge_lan_wlan_v4.name, ETH_BRIDGE_USB_WLAN_ROUTE_TABLE_NAME_V4, sizeof(rt_tbl_eth_bridge_lan_wlan_v4.name)); - - rt_tbl_eth_bridge_wlan_wlan_v4.ip = IPA_IP_v4; - strncpy(rt_tbl_eth_bridge_wlan_wlan_v4.name, ETH_BRIDGE_WLAN_WLAN_ROUTE_TABLE_NAME_V4, sizeof(rt_tbl_eth_bridge_wlan_wlan_v4.name)); - - rt_tbl_eth_bridge_lan_lan_v6.ip = IPA_IP_v6; - strncpy(rt_tbl_eth_bridge_lan_lan_v6.name, ETH_BRIDGE_USB_CPE_ROUTE_TABLE_NAME_V6, sizeof(rt_tbl_eth_bridge_lan_lan_v6.name)); - - rt_tbl_eth_bridge_lan_wlan_v6.ip = IPA_IP_v6; - strncpy(rt_tbl_eth_bridge_lan_wlan_v6.name, ETH_BRIDGE_USB_WLAN_ROUTE_TABLE_NAME_V6, sizeof(rt_tbl_eth_bridge_lan_wlan_v6.name)); - - rt_tbl_eth_bridge_wlan_wlan_v6.ip = IPA_IP_v6; - strncpy(rt_tbl_eth_bridge_wlan_wlan_v6.name, ETH_BRIDGE_WLAN_WLAN_ROUTE_TABLE_NAME_V6, sizeof(rt_tbl_eth_bridge_wlan_wlan_v6.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; @@ -719,7 +755,7 @@ int IPACM_Config::SetExtProp(ipa_ioc_query_intf_ext_props *prop) { if(ext_prop_v4.num_ext_props >= MAX_NUM_EXT_PROPS) { - IPACMDBG_H("IPv4 extended property table is full!\n"); + 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)); @@ -729,7 +765,7 @@ int IPACM_Config::SetExtProp(ipa_ioc_query_intf_ext_props *prop) { if(ext_prop_v6.num_ext_props >= MAX_NUM_EXT_PROPS) { - IPACMDBG_H("IPv6 extended property table is full!\n"); + 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)); @@ -774,3 +810,14 @@ int IPACM_Config::DelExtProp(ipa_ip_type ip_type) 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]; +} diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackClient.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackClient.cpp index 2a670c8..146cedb 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackClient.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackClient.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -524,9 +524,9 @@ void* IPACM_ConntrackClient::UDPRegisterWithConnTrack(void *) /* 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); + (nf_conntrack_msg_type)(NFCT_T_NEW | NFCT_T_DESTROY), + IPAConntrackEventCB, + NULL); /* Block to catch events from net filter connection track */ ctcatch: diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp index ab25bde..5e8fb22 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +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 @@ -33,6 +33,8 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "IPACM_ConntrackListener.h" #include "IPACM_ConntrackClient.h" #include "IPACM_EvtDispatcher.h" +#include "IPACM_Iface.h" +#include "IPACM_Wan.h" IPACM_ConntrackListener::IPACM_ConntrackListener() { @@ -46,7 +48,7 @@ IPACM_ConntrackListener::IPACM_ConntrackListener() NatIfaceCnt = 0; StaClntCnt = 0; pNatIfaces = NULL; - pConfig = NULL; + pConfig = IPACM_Config::GetInstance();; memset(nat_iface_ipv4_addr, 0, sizeof(nat_iface_ipv4_addr)); memset(nonnat_iface_ipv4_addr, 0, sizeof(nonnat_iface_ipv4_addr)); @@ -58,6 +60,8 @@ IPACM_ConntrackListener::IPACM_ConntrackListener() IPACM_EvtDispatcher::registr(IPA_PROCESS_CT_MESSAGE_V6, this); IPACM_EvtDispatcher::registr(IPA_HANDLE_WLAN_UP, this); IPACM_EvtDispatcher::registr(IPA_HANDLE_LAN_UP, this); + IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, this); + IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, this); #ifdef CT_OPT p_lan2lan = IPACM_LanToLan::getLan2LanInstance(); @@ -65,7 +69,7 @@ IPACM_ConntrackListener::IPACM_ConntrackListener() } void IPACM_ConntrackListener::event_callback(ipa_cm_event_id evt, - void *data) + void *data) { ipacm_event_iface_up *wan_down = NULL; @@ -119,168 +123,232 @@ void IPACM_ConntrackListener::event_callback(ipa_cm_event_id evt, IPACM_ConntrackClient::UpdateTCPFilters(data, false); break; + case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT: + IPACMDBG("Received IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT event\n"); + HandleNonNatIPAddr(data, true); + break; + + case IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT: + IPACMDBG("Received IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT event\n"); + HandleNonNatIPAddr(data, false); + break; + default: IPACMDBG("Ignore cmd %d\n", evt); break; } } -void IPACM_ConntrackListener::HandleNeighIpAddrAddEvt(ipacm_event_data_all *data) + +int IPACM_ConntrackListener::CheckNatIface( + ipacm_event_data_all *data, bool *NatIface) { int fd = 0, len = 0, cnt, i, j; struct ifreq ifr; - bool isNatIface = false; + *NatIface = false; - if(data->ipv4_addr == 0 || data->iptype != IPA_IP_v4) + if (data->ipv4_addr == 0 || data->iptype != IPA_IP_v4) { - IPACMDBG("Ignoring IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT EVENT\n"); - return; + IPACMDBG("Ignoring\n"); + return IPACM_FAILURE; } - IPACMDBG("\n"); IPACMDBG("Received interface index %d with ip type: %d", data->if_index, data->iptype); iptodot(" and ipv4 address", data->ipv4_addr); - if(pConfig == NULL) + if (pConfig == NULL) { pConfig = IPACM_Config::GetInstance(); - if(pConfig == NULL) + if (pConfig == NULL) { IPACMERR("Unable to get Config instance\n"); - return; + return IPACM_FAILURE; } } - cnt = pConfig->GetNatIfacesCnt(); NatIfaceCnt = cnt; - if (pNatIfaces != NULL) { + IPACMDBG("Total Nat ifaces: %d\n", NatIfaceCnt); + if (pNatIfaces != NULL) + { free(pNatIfaces); pNatIfaces = NULL; } len = (sizeof(NatIfaces) * NatIfaceCnt); pNatIfaces = (NatIfaces *)malloc(len); - if (pNatIfaces == NULL) { + if (pNatIfaces == NULL) + { IPACMERR("Unable to allocate memory for non nat ifaces\n"); - return; + return IPACM_FAILURE; } - memset(pNatIfaces, 0, len); - if (pConfig->GetNatIfaces(NatIfaceCnt, pNatIfaces) != 0) { + memset(pNatIfaces, 0, len); + if (pConfig->GetNatIfaces(NatIfaceCnt, pNatIfaces) != 0) + { IPACMERR("Unable to retrieve non nat ifaces\n"); - return; + return IPACM_FAILURE; } - IPACMDBG("Update %d Nat ifaces\n", NatIfaceCnt); - /* Search/Configure linux interface-index and map it to IPA interface-index */ - if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { PERROR("get interface name socket create failed"); - return; + return IPACM_FAILURE; } memset(&ifr, 0, sizeof(struct ifreq)); ifr.ifr_ifindex = data->if_index; - - if(ioctl(fd, SIOCGIFNAME, &ifr) < 0) + if (ioctl(fd, SIOCGIFNAME, &ifr) < 0) { PERROR("call_ioctl_on_dev: ioctl failed:"); close(fd); - return; + return IPACM_FAILURE; } close(fd); - for(i = 0; i < NatIfaceCnt; i++) + for (i = 0; i < NatIfaceCnt; i++) { - if(strncmp(ifr.ifr_name, - pNatIfaces[i].iface_name, - sizeof(pNatIfaces[i].iface_name)) == 0) + if (strncmp(ifr.ifr_name, + pNatIfaces[i].iface_name, + sizeof(pNatIfaces[i].iface_name)) == 0) { /* copy the ipv4 address to filter out downlink connections ignore downlink after listening connection event from conntrack as it is not destinated to private ip address */ IPACMDBG("Interface (%s) is nat\n", ifr.ifr_name); - for(j = 0; j < MAX_NAT_IFACES; j++) + for (j = 0; j < MAX_IFACE_ADDRESS; j++) { /* check if duplicate NAT ip */ - if(nat_iface_ipv4_addr[j] == data->ipv4_addr) - break; + if (nat_iface_ipv4_addr[j] == data->ipv4_addr) + { + *NatIface = true; + return IPACM_SUCCESS; + } - if(nat_iface_ipv4_addr[j] == 0) + if (nat_iface_ipv4_addr[j] == 0) { nat_iface_ipv4_addr[j] = data->ipv4_addr; - nat_inst->ResetPwrSaveIf(data->ipv4_addr); - nat_inst->FlushTempEntries(data->ipv4_addr, true); - break; + IPACMDBG_H("Nating connections of Interface (%s), entry (%d) ", + pNatIfaces[i].iface_name, j); + iptodot("with ipv4 address: ", nat_iface_ipv4_addr[j]); + + *NatIface = true; + return IPACM_SUCCESS; } } + } + } + + return IPACM_SUCCESS; +} - if(j == MAX_NAT_IFACES) +void IPACM_ConntrackListener::HandleNonNatIPAddr( + void *inParam, bool AddOp) +{ + ipacm_event_data_all *data = (ipacm_event_data_all *)inParam; + bool NatIface = false; + int cnt, ret; + + /* Handle only non nat ifaces, NAT iface should be handle + separately to avoid race conditions between route/nat + rules add/delete operations */ + if (AddOp) + { + ret = CheckNatIface(data, &NatIface); + if (!NatIface && ret == IPACM_SUCCESS) + { + /* Cache the non nat iface ip address */ + for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++) { - IPACMERR("Nat ifaces(%d) exceed maximum\n", j); - break; + if (nonnat_iface_ipv4_addr[cnt] == 0) + { + nonnat_iface_ipv4_addr[cnt] = data->ipv4_addr; + /* Add dummy nat rule for non nat ifaces */ + nat_inst->FlushTempEntries(data->ipv4_addr, true, true); + return; + } } - - - isNatIface = true; - IPACMDBG_H("Nating connections of Interface (%s), entry (%d) ", pNatIfaces[i].iface_name, j); - IPACMDBG_H(" with ipv4 address(0x%x): %d.%d.%d.%d\n", nat_iface_ipv4_addr[j], - ((nat_iface_ipv4_addr[j]>>24) & 0xFF), ((nat_iface_ipv4_addr[j]>>16) & 0xFF), - ((nat_iface_ipv4_addr[j]>>8) & 0xFF), (nat_iface_ipv4_addr[j] & 0xFF)); - break; } } - - /* Cache the non nat iface ip address */ - if(isNatIface != true) + else { - for(i = 0; i < MAX_NAT_IFACES; i++) + /* for delete operation */ + for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++) { - if(nonnat_iface_ipv4_addr[i] == 0) + if (nonnat_iface_ipv4_addr[cnt] == data->ipv4_addr) { - nonnat_iface_ipv4_addr[i] = data->ipv4_addr; + IPACMDBG("Reseting ct filters, entry (%d) ", cnt); + iptodot("with ipv4 address", nonnat_iface_ipv4_addr[cnt]); + nonnat_iface_ipv4_addr[cnt] = 0; nat_inst->FlushTempEntries(data->ipv4_addr, false); - break; + nat_inst->DelEntriesOnClntDiscon(data->ipv4_addr); + return; } } + } + return; +} + +void IPACM_ConntrackListener::HandleNeighIpAddrAddEvt( + ipacm_event_data_all *data) +{ + bool NatIface = false; + int j, ret; + + ret = CheckNatIface(data, &NatIface); + if (NatIface && ret == IPACM_SUCCESS) + { + for (j = 0; j < MAX_IFACE_ADDRESS; j++) + { + /* check if duplicate NAT ip */ + if (nat_iface_ipv4_addr[j] == data->ipv4_addr) + break; + + /* Cache the new nat iface address */ + if (nat_iface_ipv4_addr[j] == 0) + { + nat_iface_ipv4_addr[j] = data->ipv4_addr; + iptodot("Nating connections of addr: ", nat_iface_ipv4_addr[j]); + break; + } + } + + /* Add the cached temp entries to NAT table */ + if (j != MAX_IFACE_ADDRESS) + { + nat_inst->ResetPwrSaveIf(data->ipv4_addr); + nat_inst->FlushTempEntries(data->ipv4_addr, true); + } + } + return; } -void IPACM_ConntrackListener::HandleNeighIpAddrDelEvt(uint32_t ipv4_addr) +void IPACM_ConntrackListener::HandleNeighIpAddrDelEvt( + uint32_t ipv4_addr) { int cnt; if(ipv4_addr == 0) { - IPACMDBG("Ignoring IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT EVENT\n"); + IPACMDBG("Ignoring\n"); return; } - IPACMDBG("\n"); - iptodot("Received ip addr", ipv4_addr); - IPACMDBG("Entering NAT entry deletion checking\n"); - - for(cnt = 0; cnt<MAX_NAT_IFACES; cnt++) + iptodot("HandleNeighIpAddrDelEvt(): Received ip addr", ipv4_addr); + for(cnt = 0; cnt<MAX_IFACE_ADDRESS; cnt++) { - if(nat_iface_ipv4_addr[cnt] == ipv4_addr) + if (nat_iface_ipv4_addr[cnt] == ipv4_addr) { IPACMDBG("Reseting ct nat iface, entry (%d) ", cnt); iptodot("with ipv4 address", nat_iface_ipv4_addr[cnt]); nat_iface_ipv4_addr[cnt] = 0; - } - - if(nonnat_iface_ipv4_addr[cnt] == ipv4_addr) - { - IPACMDBG("Reseting ct filters, entry (%d) ", cnt); - iptodot("with ipv4 address", nonnat_iface_ipv4_addr[cnt]); - nonnat_iface_ipv4_addr[cnt] = 0; + nat_inst->FlushTempEntries(ipv4_addr, false); + nat_inst->DelEntriesOnClntDiscon(ipv4_addr); } } - nat_inst->FlushTempEntries(ipv4_addr, false); - nat_inst->DelEntriesOnClntDiscon(ipv4_addr); return; } @@ -467,7 +535,7 @@ void ParseCTMessage(struct nf_conntrack *ct) void ParseCTV6Message(struct nf_conntrack *ct) { - uint32_t status, timeout, secmark; + uint32_t status, timeout; struct nfct_attr_grp_ipv6 orig_params; uint8_t l4proto, tcp_flags, tcp_state; @@ -628,6 +696,332 @@ void IPACM_ConntrackListener::ProcessCTMessage(void *param) return; } +bool IPACM_ConntrackListener::AddIface( + nat_table_entry *rule, bool *isTempEntry) +{ + int cnt; + + *isTempEntry = false; + + /* Special handling for Passthrough IP. */ + if (IPACM_Iface::ipacmcfg->ipacm_ip_passthrough_mode) + { + if (rule->private_ip == IPACM_Wan::getWANIP()) + { + IPACMDBG("In Passthrough mode and entry matched with Wan IP (0x%x)\n", + rule->private_ip); + return true; + } + } + + /* check whether nat iface or not */ + for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++) + { + if (nat_iface_ipv4_addr[cnt] != 0) + { + if (rule->private_ip == nat_iface_ipv4_addr[cnt] || + rule->target_ip == nat_iface_ipv4_addr[cnt]) + { + IPACMDBG("matched nat_iface_ipv4_addr entry(%d)\n", cnt); + iptodot("AddIface(): Nat entry match with ip addr", + nat_iface_ipv4_addr[cnt]); + return true; + } + } + } + + /* check whether non nat iface or not, on Nat iface + add dummy rule by copying public ip to private ip */ + for (cnt = 0; cnt < MAX_IFACE_ADDRESS; cnt++) + { + if (nonnat_iface_ipv4_addr[cnt] != 0) + { + if (rule->private_ip == nonnat_iface_ipv4_addr[cnt] || + rule->target_ip == nonnat_iface_ipv4_addr[cnt]) + { + IPACMDBG("matched non_nat_iface_ipv4_addr entry(%d)\n", cnt); + iptodot("AddIface(): Non Nat entry match with ip addr", + nat_iface_ipv4_addr[cnt]); + + rule->private_ip = rule->public_ip; + rule->private_port = rule->public_port; + return true; + } + } + } + + IPACMDBG_H("Not mtaching with non-nat ifaces\n"); + if(pConfig == NULL) + { + pConfig = IPACM_Config::GetInstance(); + if(pConfig == NULL) + { + IPACMERR("Unable to get Config instance\n"); + return false; + } + } + + if (pConfig->isPrivateSubnet(rule->private_ip) || + pConfig->isPrivateSubnet(rule->target_ip)) + { + IPACMDBG("Matching with Private subnet\n"); + *isTempEntry = true; + return true; + } + + return false; +} + +void IPACM_ConntrackListener::AddORDeleteNatEntry(const nat_entry_bundle *input) +{ + u_int8_t tcp_state; + + if (nat_inst == NULL) + { + IPACMERR("Nat instance is NULL, unable to add or delete\n"); + return; + } + + IPACMDBG_H("Below Nat Entry will either be added or deleted\n"); + iptodot("AddORDeleteNatEntry(): target ip or dst ip", + input->rule->target_ip); + IPACMDBG("target port or dst port: 0x%x Decimal:%d\n", + input->rule->target_port, input->rule->target_port); + iptodot("AddORDeleteNatEntry(): private ip or src ip", + input->rule->private_ip); + IPACMDBG("private port or src port: 0x%x, Decimal:%d\n", + input->rule->private_port, input->rule->private_port); + IPACMDBG("public port or reply dst port: 0x%x, Decimal:%d\n", + input->rule->public_port, input->rule->public_port); + IPACMDBG("Protocol: %d, destination nat flag: %d\n", + input->rule->protocol, input->rule->dst_nat); + + if (IPPROTO_TCP == input->rule->protocol) + { + tcp_state = nfct_get_attr_u8(input->ct, ATTR_TCP_STATE); + if (TCP_CONNTRACK_ESTABLISHED == tcp_state) + { + IPACMDBG("TCP state TCP_CONNTRACK_ESTABLISHED(%d)\n", tcp_state); + if (!CtList->isWanUp()) + { + IPACMDBG("Wan is not up, cache connections\n"); + nat_inst->CacheEntry(input->rule); + } + else if (input->isTempEntry) + { + nat_inst->AddTempEntry(input->rule); + } + else + { + nat_inst->AddEntry(input->rule); + } + } + else if (TCP_CONNTRACK_FIN_WAIT == tcp_state || + input->type == NFCT_T_DESTROY) + { + IPACMDBG("TCP state TCP_CONNTRACK_FIN_WAIT(%d) " + "or type NFCT_T_DESTROY(%d)\n", tcp_state, input->type); + + nat_inst->DeleteEntry(input->rule); + nat_inst->DeleteTempEntry(input->rule); + } + else + { + IPACMDBG("Ignore tcp state: %d and type: %d\n", + tcp_state, input->type); + } + + } + else if (IPPROTO_UDP == input->rule->protocol) + { + if (NFCT_T_NEW == input->type) + { + IPACMDBG("New UDP connection at time %ld\n", time(NULL)); + if (!CtList->isWanUp()) + { + IPACMDBG("Wan is not up, cache connections\n"); + nat_inst->CacheEntry(input->rule); + } + else if (input->isTempEntry) + { + nat_inst->AddTempEntry(input->rule); + } + else + { + nat_inst->AddEntry(input->rule); + } + } + else if (NFCT_T_DESTROY == input->type) + { + IPACMDBG("UDP connection close at time %ld\n", time(NULL)); + nat_inst->DeleteEntry(input->rule); + nat_inst->DeleteTempEntry(input->rule); + } + } + + return; +} + +void IPACM_ConntrackListener::PopulateTCPorUDPEntry( + struct nf_conntrack *ct, + uint32_t status, + nat_table_entry *rule) +{ + if (IPS_DST_NAT == status) + { + IPACMDBG("Destination NAT\n"); + rule->dst_nat = true; + + IPACMDBG("Parse reply tuple\n"); + rule->target_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC); + rule->target_ip = ntohl(rule->target_ip); + iptodot("PopulateTCPorUDPEntry(): target ip", rule->target_ip); + + /* Retriev target/dst port */ + rule->target_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC); + rule->target_port = ntohs(rule->target_port); + if (0 == rule->target_port) + { + IPACMDBG("unable to retrieve target port\n"); + } + + rule->public_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST); + rule->public_port = ntohs(rule->public_port); + + /* Retriev src/private ip address */ + rule->private_ip = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC); + rule->private_ip = ntohl(rule->private_ip); + iptodot("PopulateTCPorUDPEntry(): private ip", rule->private_ip); + if (0 == rule->private_ip) + { + IPACMDBG("unable to retrieve private ip address\n"); + } + + /* Retriev src/private port */ + rule->private_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC); + rule->private_port = ntohs(rule->private_port); + if (0 == rule->private_port) + { + IPACMDBG("unable to retrieve private port\n"); + } + } + else if (IPS_SRC_NAT == status) + { + IPACMDBG("Source NAT\n"); + rule->dst_nat = false; + + /* Retriev target/dst ip address */ + IPACMDBG("Parse source tuple\n"); + rule->target_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST); + rule->target_ip = ntohl(rule->target_ip); + iptodot("PopulateTCPorUDPEntry(): target ip", rule->target_ip); + if (0 == rule->target_ip) + { + IPACMDBG("unable to retrieve target ip address\n"); + } + /* Retriev target/dst port */ + rule->target_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST); + rule->target_port = ntohs(rule->target_port); + if (0 == rule->target_port) + { + IPACMDBG("unable to retrieve target port\n"); + } + + /* Retriev public port */ + rule->public_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST); + rule->public_port = ntohs(rule->public_port); + if (0 == rule->public_port) + { + IPACMDBG("unable to retrieve public port\n"); + } + + /* Retriev src/private ip address */ + rule->private_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC); + rule->private_ip = ntohl(rule->private_ip); + iptodot("PopulateTCPorUDPEntry(): private ip", rule->private_ip); + if (0 == rule->private_ip) + { + IPACMDBG("unable to retrieve private ip address\n"); + } + + /* Retriev src/private port */ + rule->private_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC); + rule->private_port = ntohs(rule->private_port); + if (0 == rule->private_port) + { + IPACMDBG("unable to retrieve private port\n"); + } + } + + return; +} + +#ifdef CT_OPT +void IPACM_ConntrackListener::HandleLan2Lan(struct nf_conntrack *ct, + enum nf_conntrack_msg_type type, + nat_table_entry *rule) +{ + ipacm_event_connection lan2lan_conn = { 0 }; + + if (p_lan2lan == NULL) + { + IPACMERR("Lan2Lan Instance is null\n"); + return; + } + + lan2lan_conn.iptype = IPA_IP_v4; + lan2lan_conn.src_ipv4_addr = orig_src_ip; + lan2lan_conn.dst_ipv4_addr = orig_dst_ip; + + if (((IPPROTO_UDP == rule->protocol) && (NFCT_T_NEW == type)) || + ((IPPROTO_TCP == rule->protocol) && (nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_ESTABLISHED))) + { + p_lan2lan->handle_new_connection(&lan2lan_conn); + } + else if ((IPPROTO_UDP == rule->protocol && NFCT_T_DESTROY == type) || + (IPPROTO_TCP == rule->protocol && + nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_FIN_WAIT)) + { + p_lan2lan->handle_del_connection(&lan2lan_conn); + } +} +#endif + +void IPACM_ConntrackListener::CheckSTAClient( + const nat_table_entry *rule, bool *isTempEntry) +{ + int nCnt; + + /* Check whether target is in STA client list or not + if not ignore the connection */ + if(!isStaMode || (StaClntCnt == 0)) + { + return; + } + + if((sta_clnt_ipv4_addr[0] & STA_CLNT_SUBNET_MASK) != + (rule->target_ip & STA_CLNT_SUBNET_MASK)) + { + IPACMDBG("STA client subnet mask not matching\n"); + return; + } + + IPACMDBG("StaClntCnt %d\n", StaClntCnt); + for(nCnt = 0; nCnt < StaClntCnt; nCnt++) + { + IPACMDBG("Comparing trgt_ip 0x%x with sta clnt ip: 0x%x\n", + rule->target_ip, sta_clnt_ipv4_addr[nCnt]); + if(rule->target_ip == sta_clnt_ipv4_addr[nCnt]) + { + IPACMDBG("Match index %d\n", nCnt); + return; + } + } + + IPACMDBG_H("Not matching with STA Clnt Ip Addrs 0x%x\n", + rule->target_ip); + *isTempEntry = true; +} /* conntrack send in host order and ipa expects in host order */ void IPACM_ConntrackListener::ProcessTCPorUDPMsg( @@ -636,19 +1030,16 @@ void IPACM_ConntrackListener::ProcessTCPorUDPMsg( u_int8_t l4proto) { nat_table_entry rule; - u_int8_t tcp_state; uint32_t status = 0; - IPACM_Config *pConfig; uint32_t orig_src_ip, orig_dst_ip; - bool isTempEntry = false; + bool isAdd = false; - memset(&rule, 0, sizeof(rule)); - pConfig = IPACM_Config::GetInstance(); - if(pConfig == NULL) - { - IPACMERR("Unable to get Config instance\n"); - } + nat_entry_bundle nat_entry; + nat_entry.isTempEntry = false; + nat_entry.ct = ct; + nat_entry.type = type; + memset(&rule, 0, sizeof(rule)); IPACMDBG("Received type:%d with proto:%d\n", type, l4proto); status = nfct_get_attr_u32(ct, ATTR_STATUS); @@ -695,116 +1086,19 @@ void IPACM_ConntrackListener::ProcessTCPorUDPMsg( else { IPACMDBG_H("Neither orig src ip:0x%x Nor orig Dst IP:0x%x equal to wan ip:0x%x\n", - orig_src_ip, orig_dst_ip, wan_ipaddr); + orig_src_ip, orig_dst_ip, wan_ipaddr); #ifdef CT_OPT - if(p_lan2lan == NULL) - { - IPACMERR("Lan2Lan Instance is null\n"); - goto IGNORE; - } - - ipacm_event_connection lan2lan_conn = { 0 }; - lan2lan_conn.iptype = IPA_IP_v4; - lan2lan_conn.src_ipv4_addr = orig_src_ip; - lan2lan_conn.dst_ipv4_addr = orig_dst_ip; - - if(((IPPROTO_UDP == rule.protocol) && (NFCT_T_NEW == type)) || - ((IPPROTO_TCP == rule.protocol) && (nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_ESTABLISHED))) - { - p_lan2lan->handle_new_connection(&lan2lan_conn); - } - else if((IPPROTO_UDP == rule.protocol && NFCT_T_DESTROY == type) || - (IPPROTO_TCP == rule.protocol && - nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_FIN_WAIT)) - { - p_lan2lan->handle_del_connection(&lan2lan_conn); - } + HandleLan2Lan(ct, type, &rule); #endif - return; - } + return; + } } - if(IPS_DST_NAT == status) - { - IPACMDBG("Destination NAT\n"); - rule.dst_nat = true; - - IPACMDBG("Parse reply tuple\n"); - rule.target_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC); - rule.target_ip = ntohl(rule.target_ip); - - /* Retriev target/dst port */ - rule.target_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC); - rule.target_port = ntohs(rule.target_port); - if(0 == rule.target_port) - { - IPACMDBG("unable to retrieve target port\n"); - } - - rule.public_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST); - rule.public_port = ntohs(rule.public_port); - - /* Retriev src/private ip address */ - rule.private_ip = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC); - rule.private_ip = ntohl(rule.private_ip); - if(0 == rule.private_ip) - { - IPACMDBG("unable to retrieve private ip address\n"); - } - - /* Retriev src/private port */ - rule.private_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC); - rule.private_port = ntohs(rule.private_port); - if(0 == rule.private_port) - { - IPACMDBG("unable to retrieve private port\n"); - } - } - else if(IPS_SRC_NAT == status) + if(IPS_DST_NAT == status || IPS_SRC_NAT == status) { - IPACMDBG("Source NAT\n"); - rule.dst_nat = false; - - /* Retriev target/dst ip address */ - IPACMDBG("Parse source tuple\n"); - rule.target_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST); - rule.target_ip = ntohl(rule.target_ip); - if(0 == rule.target_ip) - { - IPACMDBG("unable to retrieve target ip address\n"); - } - /* Retriev target/dst port */ - rule.target_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST); - rule.target_port = ntohs(rule.target_port); - if(0 == rule.target_port) - { - IPACMDBG("unable to retrieve target port\n"); - } - - /* Retriev public port */ - rule.public_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST); - rule.public_port = ntohs(rule.public_port); - if(0 == rule.public_port) - { - IPACMDBG("unable to retrieve public port\n"); - } - - /* Retriev src/private ip address */ - rule.private_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC); - rule.private_ip = ntohl(rule.private_ip); - if(0 == rule.private_ip) - { - IPACMDBG("unable to retrieve private ip address\n"); - } - - /* Retriev src/private port */ - rule.private_port = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC); - rule.private_port = ntohs(rule.private_port); - if(0 == rule.private_port) - { - IPACMDBG("unable to retrieve private port\n"); - } + PopulateTCPorUDPEntry(ct, status, &rule); + rule.public_ip = wan_ipaddr; } else { @@ -812,188 +1106,41 @@ void IPACM_ConntrackListener::ProcessTCPorUDPMsg( goto IGNORE; } - if(rule.private_ip != wan_ipaddr) + if (rule.private_ip != wan_ipaddr) { - int cnt; - for(cnt = 0; cnt < MAX_NAT_IFACES; cnt++) + isAdd = AddIface(&rule, &nat_entry.isTempEntry); + if (!isAdd) { - if(nat_iface_ipv4_addr[cnt] != 0) - { - if(rule.private_ip == nat_iface_ipv4_addr[cnt] || - rule.target_ip == nat_iface_ipv4_addr[cnt]) - { - IPACMDBG("matched nat_iface_ipv4_addr entry(%d)\n", cnt); - iptodot("ProcessTCPorUDPMsg(): Nat entry match with ip addr", - nat_iface_ipv4_addr[cnt]); - break; - } - } - } - - if(cnt == MAX_NAT_IFACES) - { - IPACMDBG_H("Not mtaching with nat ifaces\n"); - if(pConfig == NULL) - { - goto IGNORE; - } - - if(pConfig->isPrivateSubnet(rule.private_ip) || - pConfig->isPrivateSubnet(rule.target_ip)) - { - IPACMDBG("Matching with Private subnet\n"); - isTempEntry = true; - } - else - { - goto IGNORE; - } + goto IGNORE; } - } else { - if(isStaMode) { + if (isStaMode) + { IPACMDBG("In STA mode, ignore connections destinated to STA interface\n"); goto IGNORE; } - IPACMDBG("For embedded connections add dummy nat rule\n"); - IPACMDBG("Change private port %d to %d\n", - rule.private_port, rule.public_port); - rule.private_port = rule.public_port; - } - - /* Check whether target is in STA client list or not - if not ignore the connection */ - int nCnt; - - if(!isStaMode || (StaClntCnt == 0)) - { - goto ADD; - } - - if((sta_clnt_ipv4_addr[0] & 0xFFFFFF00) != - (rule.target_ip & 0xFFFFFF00)) - { - IPACMDBG("STA client subnet mask not matching\n"); - goto ADD; - } - - IPACMDBG("StaClntCnt %d\n", StaClntCnt); - for(nCnt = 0; nCnt < StaClntCnt; nCnt++) - { - IPACMDBG("Comparing trgt_ip 0x%x with sta clnt ip: 0x%x\n", - rule.target_ip, sta_clnt_ipv4_addr[nCnt]); - if(rule.target_ip == sta_clnt_ipv4_addr[nCnt]) - { - IPACMDBG("Match index %d\n", nCnt); - goto ADD; - } - } - - IPACMDBG_H("Not matching with STA Clnt Ip Addrs 0x%x\n", - rule.target_ip); - isTempEntry = true; - - -ADD: - IPACMDBG_H("Nat Entry with below information will either be added or deleted\n"); - iptodot("target ip or dst ip", rule.target_ip); - IPACMDBG("target port or dst port: 0x%x Decimal:%d\n", rule.target_port, rule.target_port); - iptodot("private ip or src ip", rule.private_ip); - IPACMDBG("private port or src port: 0x%x, Decimal:%d\n", rule.private_port, rule.private_port); - IPACMDBG("public port or reply dst port: 0x%x, Decimal:%d\n", rule.public_port, rule.public_port); - IPACMDBG("Protocol: %d, destination nat flag: %d\n", rule.protocol, rule.dst_nat); - - rule.public_ip = wan_ipaddr; - if(IPPROTO_TCP == rule.protocol) - { - if(nat_inst == NULL) - { - return; - } - - tcp_state = nfct_get_attr_u8(ct, ATTR_TCP_STATE); - if(TCP_CONNTRACK_ESTABLISHED == tcp_state) - { - IPACMDBG("TCP state TCP_CONNTRACK_ESTABLISHED(%d)\n", tcp_state); - if(!CtList->isWanUp()) - { - IPACMDBG("Wan is not up, cache connections\n"); - nat_inst->CacheEntry(&rule); - } - else if(isTempEntry) - { - nat_inst->AddTempEntry(&rule); - } - else - { - nat_inst->AddEntry(&rule); - } - } - else if(TCP_CONNTRACK_FIN_WAIT == tcp_state || - type == NFCT_T_DESTROY) - { - IPACMDBG("TCP state TCP_CONNTRACK_FIN_WAIT(%d) " - "or type NFCT_T_DESTROY(%d)\n", tcp_state, type); - - nat_inst->DeleteEntry(&rule); - nat_inst->DeleteTempEntry(&rule); - } - else - { - IPACMDBG("Ignore tcp state: %d and type: %d\n", tcp_state, type); - } - - } - else if(IPPROTO_UDP == rule.protocol) - { - if(nat_inst == NULL) - { - return; - } - - if(NFCT_T_NEW == type) - { - IPACMDBG("New UDP connection at time %ld\n", time(NULL)); - if(!CtList->isWanUp()) - { - IPACMDBG("Wan is not up, cache connections\n"); - nat_inst->CacheEntry(&rule); - } - else if(isTempEntry) - { - nat_inst->AddTempEntry(&rule); - } - else - { - nat_inst->AddEntry(&rule); - } - } - else if(NFCT_T_DESTROY == type) - { - IPACMDBG("UDP connection close at time %ld\n", time(NULL)); - nat_inst->DeleteEntry(&rule); - nat_inst->DeleteTempEntry(&rule); - } - } - else - { - IPACMDBG("Ignore protocol: %d and type: %d\n", rule.protocol, type); + IPACMDBG("For embedded connections add dummy nat rule\n"); + IPACMDBG("Change private port %d to %d\n", + rule.private_port, rule.public_port); + rule.private_port = rule.public_port; } + CheckSTAClient(&rule, &nat_entry.isTempEntry); + nat_entry.rule = &rule; + AddORDeleteNatEntry(&nat_entry); return; IGNORE: IPACMDBG_H("ignoring below Nat Entry\n"); - iptodot("target ip or dst ip", rule.target_ip); + iptodot("ProcessTCPorUDPMsg(): target ip or dst ip", rule.target_ip); IPACMDBG("target port or dst port: 0x%x Decimal:%d\n", rule.target_port, rule.target_port); - iptodot("private ip or src ip", rule.private_ip); + iptodot("ProcessTCPorUDPMsg(): private ip or src ip", rule.private_ip); IPACMDBG("private port or src port: 0x%x, Decimal:%d\n", rule.private_port, rule.private_port); IPACMDBG("public port or reply dst port: 0x%x, Decimal:%d\n", rule.public_port, rule.public_port); IPACMDBG("Protocol: %d, destination nat flag: %d\n", rule.protocol, rule.dst_nat); - return; } diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Conntrack_NATApp.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Conntrack_NATApp.cpp index 6efb475..93627bb 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Conntrack_NATApp.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Conntrack_NATApp.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +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 @@ -149,7 +149,7 @@ int NatApp::AddTable(uint32_t pub_ip) return ret; } - /* Add back the cashed NAT-entry */ + /* Add back the cached NAT-entry */ if (pub_ip == pub_ip_addr_pre) { IPACMDBG("Restore the cache to ipa NAT-table\n"); @@ -197,7 +197,7 @@ void NatApp::Reset() /* NAT tbl deleted, reset enabled bit */ for(cnt = 0; cnt < max_entries; cnt++) { - cache[cnt].enabled ==false; + cache[cnt].enabled = false; } } @@ -295,9 +295,9 @@ int NatApp::DeleteEntry(const nat_table_entry *rule) /* 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(); @@ -490,7 +490,8 @@ void NatApp::UpdateUDPTimeStamp() for(cnt = 0; cnt < max_entries; cnt++) { ts = 0; - if(cache[cnt].enabled == true) + 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) @@ -724,8 +725,8 @@ void NatApp::DeleteTempEntry(const nat_table_entry *entry) 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\t", entry->private_port, entry->target_port); - IPACMDBG("protocolcol: %d\n", entry->protocol); + 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++) { @@ -745,13 +746,14 @@ void NatApp::DeleteTempEntry(const nat_table_entry *entry) return; } -void NatApp::FlushTempEntries(uint32_t ip_addr, bool isAdd) +void NatApp::FlushTempEntries(uint32_t ip_addr, bool isAdd, + bool isDummy) { int cnt; int ret; IPACMDBG_H("Received below with isAdd:%d ", isAdd); - IPACMDBG_H("IP Address: (ox%x)\n", ip_addr); + iptodot("IP Address: ", ip_addr); for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++) { @@ -762,6 +764,14 @@ void NatApp::FlushTempEntries(uint32_t ip_addr, bool 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) { @@ -861,6 +871,7 @@ int NatApp::DelEntriesOnSTAClntDiscon(uint32_t ip_addr) void NatApp::CacheEntry(const nat_table_entry *rule) { int cnt; + if(rule->private_ip == 0 || rule->target_ip == 0 || rule->private_port == 0 || @@ -873,7 +884,7 @@ void NatApp::CacheEntry(const nat_table_entry *rule) if(!ChkForDup(rule)) { - for(; cnt < max_entries; cnt++) + for(cnt=0; cnt < max_entries; cnt++) { if(cache[cnt].private_ip == 0 && cache[cnt].target_ip == 0 && diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_EvtDispatcher.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_EvtDispatcher.cpp index 11782df..edb5901 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_EvtDispatcher.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_EvtDispatcher.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -58,7 +58,16 @@ int IPACM_EvtDispatcher::PostEvt Message *item = NULL; MessageQueue *MsgQueue = NULL; - MsgQueue = MessageQueue::getInstance(); + 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"); @@ -72,7 +81,6 @@ int IPACM_EvtDispatcher::PostEvt return IPACM_FAILURE; } - IPACMDBG("Populating item to post to queue\n"); item->evt.callback_ptr = IPACM_EvtDispatcher::ProcessEvt; memcpy(&item->evt.data, data, sizeof(ipacm_cmd_q_data)); diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Filtering.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Filtering.cpp index bd8dadb..7faecad 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Filtering.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Filtering.cpp @@ -1,5 +1,5 @@ -/* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +/* +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 @@ -80,9 +80,8 @@ bool IPACM_Filtering::AddFilteringRule(struct ipa_ioc_add_flt_rule const *ruleTa 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); + 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); @@ -115,6 +114,38 @@ bool IPACM_Filtering::AddFilteringRule(struct ipa_ioc_add_flt_rule const *ruleTa 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; @@ -215,8 +246,7 @@ bool IPACM_Filtering::DeleteFilteringHdls res = false; goto fail; } - - } + } } } @@ -285,7 +315,7 @@ bool IPACM_Filtering::AddWanDLFilteringRule(struct ipa_ioc_add_flt_rule const *r 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--) diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Header.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Header.cpp index 5e56a49..c77c69c 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Header.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Header.cpp @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2013, The Linux Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -203,7 +203,7 @@ 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 != -1); + return (ret == 0); } bool IPACM_Header::DeleteHeaderProcCtx(uint32_t hdl) @@ -225,7 +225,12 @@ bool IPACM_Header::DeleteHeaderProcCtx(uint32_t hdl) 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 != -1); + return (ret == 0); } diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Iface.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Iface.cpp index 5dc7647..04cb162 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Iface.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Iface.cpp @@ -133,6 +133,9 @@ int IPACM_Iface::handle_software_routing_enable(void) 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)); @@ -746,7 +749,7 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype) flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; #ifdef FEATURE_IPA_V3 flt_rule_entry.at_rear = false; - flt_rule_entry.rule.hashable = IPA_RULE_NON_HASHABLE; + 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, @@ -763,11 +766,19 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype) flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xF0000000; flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xE0000000; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.at_rear = true; + flt_rule_entry.rule.hashable = true; +#endif 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)) @@ -832,6 +843,10 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype) flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.at_rear = true; + flt_rule_entry.rule.hashable = true; +#endif memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* Configuring fe80::/10 Link-Scoped Unicast Filtering Rule */ @@ -843,6 +858,10 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype) flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.at_rear = true; + flt_rule_entry.rule.hashable = true; +#endif memcpy(&(m_pFilteringTable->rules[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); /* Configuring fec0::/10 Reserved by IETF Filtering Rule */ @@ -854,6 +873,10 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype) flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.at_rear = true; + flt_rule_entry.rule.hashable = true; +#endif memcpy(&(m_pFilteringTable->rules[2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); #ifdef FEATURE_IPA_ANDROID @@ -968,48 +991,3 @@ int IPACM_Iface::ipa_get_if_index close(fd); return IPACM_SUCCESS; } - -size_t IPACM_Iface::strlcpy(char *dest, const char *src, size_t n) -{ - size_t ret = strlen(src); - size_t len = 0; - if (n > 0) { - if(ret >= n) - { - len = n-1; - IPACMERR(" overflow detected \n"); - } - else - { - len = ret; - } - dest[len] = '\0'; - memcpy(dest, src, len); - } - return ret; -} - -size_t IPACM_Iface::strlcat(char *dest, const char *src, size_t n) -{ - size_t dsize = strlen(dest); - size_t len = strlen(src); - size_t ret = dsize + len; - - if (dsize < n) - { - dest += dsize; - n -= dsize; - if (len >= n) - { - len = n - 1; - IPACMERR(" overflow detected \n"); - } - dest[len] = '\0'; - memcpy(dest, src, len); - } - else - { - IPACMERR(" dest buffer full\n"); - } - return ret; -} diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_IfaceManager.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_IfaceManager.cpp index 59884ab..d6ad9a5 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_IfaceManager.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_IfaceManager.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -245,14 +245,6 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param) #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_ETH_BRIDGE_LE - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_LAN_CLIENT_ADD_EVENT, lan); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_LAN_CLIENT_DEL_EVENT, lan); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT, lan); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT, lan); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT, lan); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT, lan); -#endif #ifdef FEATURE_IPA_ANDROID IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, lan); #endif @@ -303,14 +295,6 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param) 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); -#ifdef FEATURE_ETH_BRIDGE_LE - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_LAN_CLIENT_ADD_EVENT, odu); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_LAN_CLIENT_DEL_EVENT, odu); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT, odu); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT, odu); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT, odu); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT, odu); -#endif IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, odu); IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, odu); IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, odu); @@ -364,10 +348,6 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param) #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_ETH_BRIDGE_LAN_CLIENT_ADD_EVENT, wl); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_LAN_CLIENT_DEL_EVENT, wl); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT, wl); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT, wl); IPACM_EvtDispatcher::registr(IPA_CFG_CHANGE_EVENT, wl); #endif IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, wl); @@ -421,7 +401,7 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param) if(is_sta_mode == WLAN_WAN) { IPACM_EvtDispatcher::registr(IPA_WLAN_LINK_DOWN_EVENT, w); // for STA mode -#ifndef FEATURE_IPA_ANDROI +#ifndef FEATURE_IPA_ANDROID IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_SCC, w); IPACM_EvtDispatcher::registr(IPA_WLAN_SWITCH_TO_MCC, w); #endif diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Lan.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Lan.cpp index 2cc5088..eadf159 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Lan.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Lan.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -55,28 +55,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. bool IPACM_Lan::odu_up = false; -ipa_hdr_l2_type IPACM_Lan::lan_hdr_type = IPA_HDR_L2_NONE; -ipa_hdr_l2_type IPACM_Lan::wlan_hdr_type = IPA_HDR_L2_NONE; - -uint32_t IPACM_Lan::usb_hdr_template_hdl = 0; -uint32_t IPACM_Lan::wlan_hdr_template_hdl = 0; -uint32_t IPACM_Lan::cpe_hdr_template_hdl = 0; - -hdr_proc_ctx_info IPACM_Lan::lan_to_wlan_hdr_proc_ctx; -hdr_proc_ctx_info IPACM_Lan::wlan_to_usb_hdr_proc_ctx; -hdr_proc_ctx_info IPACM_Lan::wlan_to_cpe_hdr_proc_ctx; -hdr_proc_ctx_info IPACM_Lan::wlan_to_wlan_hdr_proc_ctx; -hdr_proc_ctx_info IPACM_Lan::usb_to_cpe_hdr_proc_ctx; -hdr_proc_ctx_info IPACM_Lan::cpe_to_usb_hdr_proc_ctx; - -eth_bridge_subnet_client_info IPACM_Lan::eth_bridge_wlan_client[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; -eth_bridge_subnet_client_info IPACM_Lan::eth_bridge_lan_client[IPA_LAN_TO_LAN_MAX_LAN_CLIENT]; - -int IPACM_Lan::num_wlan_client = 0; -int IPACM_Lan::num_lan_client = 0; -bool IPACM_Lan::is_usb_up = false; -bool IPACM_Lan::is_cpe_up = false; - IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index) { num_eth_client = 0; @@ -87,8 +65,7 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index) odu_route_rule_v4_hdl = NULL; odu_route_rule_v6_hdl = NULL; eth_client = NULL; - int m_fd_odu, ret = IPACM_SUCCESS; - uint32_t* hdr_template_ptr; + int i, m_fd_odu, ret = IPACM_SUCCESS; Nat_App = NatApp::GetInstance(); if (Nat_App == NULL) @@ -100,7 +77,7 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index) /* support eth multiple clients */ if(iface_query != NULL) { - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != WLAN_IF) + if(ipa_if_cate != WLAN_IF) { eth_client_len = (sizeof(ipa_eth_client)) + (iface_query->num_tx_props * sizeof(eth_client_rt_hdl)); eth_client = (ipa_eth_client *)calloc(IPA_MAX_NUM_ETH_CLIENTS, eth_client_len); @@ -113,42 +90,9 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index) IPACMDBG_H(" IPACM->IPACM_Lan(%d) constructor: Tx:%d Rx:%d \n", ipa_if_num, iface_query->num_tx_props, iface_query->num_rx_props); -#ifdef FEATURE_ETH_BRIDGE_LE - if((IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF - || IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) && tx_prop != NULL) - { - if (IPACM_Lan::lan_hdr_type != IPA_HDR_L2_NONE && tx_prop->tx[0].hdr_l2_type != IPACM_Lan::lan_hdr_type) - { - IPACMERR("The LAN header format is not consistent! Now header format is %d.\n", tx_prop->tx[0].hdr_l2_type); - } - else - { - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) - { - hdr_template_ptr = &IPACM_Lan::usb_hdr_template_hdl; - IPACM_Lan::is_usb_up = true; - } - else //else it is ODU_IF (cpe) - { - hdr_template_ptr = &IPACM_Lan::cpe_hdr_template_hdl; - IPACM_Lan::is_cpe_up = true; - } - if(eth_bridge_get_hdr_template_hdl(hdr_template_ptr) == IPACM_FAILURE) - { - IPACMERR("Failed to setup lan hdr template.\n"); - } - else - { - IPACM_Lan::lan_hdr_type = tx_prop->tx[0].hdr_l2_type; - IPACMDBG_H("The LAN header format is %d.\n", tx_prop->tx[0].hdr_l2_type); - add_hdr_proc_ctx(); - } - } - } -#endif /* ODU routing table initilization */ - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) + if(ipa_if_cate == ODU_IF) { odu_route_rule_v4_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t)); odu_route_rule_v6_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t)); @@ -166,24 +110,9 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index) memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t)); memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t)); - memset(lan2lan_flt_rule_hdl_v4, 0, MAX_OFFLOAD_PAIR * sizeof(lan2lan_flt_rule_hdl)); - num_lan2lan_flt_rule_v4 = 0; - - memset(lan2lan_flt_rule_hdl_v6, 0, MAX_OFFLOAD_PAIR * sizeof(lan2lan_flt_rule_hdl)); - num_lan2lan_flt_rule_v6 = 0; - - memset(lan2lan_hdr_hdl_v4, 0, MAX_OFFLOAD_PAIR*sizeof(lan2lan_hdr_hdl)); - memset(lan2lan_hdr_hdl_v6, 0, MAX_OFFLOAD_PAIR*sizeof(lan2lan_hdr_hdl)); - - memset(lan_client_flt_rule_hdl_v4, 0, IPA_LAN_TO_LAN_MAX_LAN_CLIENT * sizeof(lan2lan_flt_rule_hdl)); - memset(lan_client_flt_rule_hdl_v6, 0, IPA_LAN_TO_LAN_MAX_LAN_CLIENT * sizeof(lan2lan_flt_rule_hdl)); - memset(wlan_client_flt_rule_hdl_v4, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(lan2lan_flt_rule_hdl)); - memset(wlan_client_flt_rule_hdl_v6, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(lan2lan_flt_rule_hdl)); - is_active = true; memset(ipv4_icmp_flt_rule_hdl, 0, NUM_IPV4_ICMP_FLT_RULE * sizeof(uint32_t)); - memset(tcp_ctl_flt_rule_hdl_v4, 0, NUM_TCP_CTL_FLT_RULE*sizeof(uint32_t)); - memset(tcp_ctl_flt_rule_hdl_v6, 0, NUM_TCP_CTL_FLT_RULE*sizeof(uint32_t)); + is_mode_switch = false; if_ipv4_subnet =0; memset(private_fl_rule_hdl, 0, IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(uint32_t)); @@ -191,35 +120,11 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index) memset(ipv6_icmp_flt_rule_hdl, 0, NUM_IPV6_ICMP_FLT_RULE * sizeof(uint32_t)); modem_ul_v4_set = false; modem_ul_v6_set = false; - -#ifdef FEATURE_ETH_BRIDGE_LE - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) - { - exp_index_v4 = IPV4_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_CPE_CLIENT + NUM_IPV4_ICMP_FLT_RULE + IPACM_Iface::ipacmcfg->ipa_num_private_subnet; - exp_index_v6 = IPV6_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_CPE_CLIENT + NUM_IPV6_ICMP_FLT_RULE + NUM_IPV6_PREFIX_FLT_RULE; - } - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) - { - exp_index_v4 = IPV4_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT + NUM_IPV4_ICMP_FLT_RULE + IPACM_Iface::ipacmcfg->ipa_num_private_subnet; - exp_index_v6 = IPV6_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT + NUM_IPV6_ICMP_FLT_RULE + NUM_IPV6_PREFIX_FLT_RULE; - } -#else -#ifdef CT_OPT - exp_index_v4 = IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_TCP_CTL_FLT_RULE + NUM_IPV4_ICMP_FLT_RULE +IPACM_Iface::ipacmcfg->ipa_num_private_subnet; - exp_index_v6 = IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + NUM_IPV6_ICMP_FLT_RULE + NUM_IPV6_PREFIX_FLT_RULE; -#else - exp_index_v4 = IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_IPV4_ICMP_FLT_RULE + IPACM_Iface::ipacmcfg->ipa_num_private_subnet; - exp_index_v6 = IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_IPV6_ICMP_FLT_RULE + NUM_IPV6_PREFIX_FLT_RULE; -#endif -#ifdef FEATURE_IPA_ANDROID - exp_index_v4 = exp_index_v4 - IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_MAX_PRIVATE_SUBNET_ENTRIES; -#endif -#endif + memset(ipv6_prefix, 0, sizeof(ipv6_prefix)); /* ODU routing table initilization */ - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) + if(ipa_if_cate == ODU_IF) { - /* only do one time ioctl to odu-driver to infrom in router or bridge mode*/ if (IPACM_Lan::odu_up != true) { @@ -252,55 +157,18 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index) } } - int i; - each_client_rt_rule_count_v4 = 0; - each_client_rt_rule_count_v6 = 0; + each_client_rt_rule_count[IPA_IP_v4] = 0; + each_client_rt_rule_count[IPA_IP_v6] = 0; if(iface_query != NULL && tx_prop != NULL) { for(i=0; i<iface_query->num_tx_props; i++) - { - if(tx_prop->tx[i].ip == IPA_IP_v4) - { - each_client_rt_rule_count_v4++; - } - else - { - each_client_rt_rule_count_v6++; - } - } - } - IPACMDBG_H("Need to add %d IPv4 and %d IPv6 routing rules for eth bridge for each client.\n", each_client_rt_rule_count_v4, each_client_rt_rule_count_v6); - - memset(eth_bridge_lan_client_flt_info, 0, IPA_LAN_TO_LAN_MAX_LAN_CLIENT * sizeof(eth_bridge_client_flt_info)); - memset(eth_bridge_wlan_client_flt_info, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(eth_bridge_client_flt_info)); - - lan_client_flt_info_count = 0; - wlan_client_flt_info_count = 0; - - eth_bridge_lan_client_rt_from_lan_info_v4 = NULL; - eth_bridge_lan_client_rt_from_lan_info_v6 = NULL; - eth_bridge_lan_client_rt_from_wlan_info_v4 = NULL; - eth_bridge_lan_client_rt_from_wlan_info_v6 = NULL; -#ifdef FEATURE_ETH_BRIDGE_LE - if(tx_prop != NULL) - { - client_rt_info_size_v4 = sizeof(eth_bridge_client_rt_info) + each_client_rt_rule_count_v4 * sizeof(uint32_t); - eth_bridge_lan_client_rt_from_lan_info_v4 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_LAN_CLIENT, client_rt_info_size_v4); - eth_bridge_lan_client_rt_from_wlan_info_v4 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_LAN_CLIENT, client_rt_info_size_v4); - client_rt_info_size_v6 = sizeof(eth_bridge_client_rt_info) + each_client_rt_rule_count_v6 * sizeof(uint32_t); - eth_bridge_lan_client_rt_from_lan_info_v6 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v6); - eth_bridge_lan_client_rt_from_wlan_info_v6 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v6); - + each_client_rt_rule_count[tx_prop->tx[i].ip]++; } -#endif - lan_client_rt_from_lan_info_count_v4 = 0; - lan_client_rt_from_lan_info_count_v6 = 0; - lan_client_rt_from_wlan_info_count_v4 = 0; - lan_client_rt_from_wlan_info_count_v6 = 0; + IPACMDBG_H("Need to add %d IPv4 and %d IPv6 routing rules for eth bridge for each client.\n", each_client_rt_rule_count[IPA_IP_v4], each_client_rt_rule_count[IPA_IP_v6]); #ifdef FEATURE_IPA_ANDROID /* set the IPA-client pipe enum */ - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) + if(ipa_if_cate == LAN_IF) { handle_tethering_client(false, IPACM_CLIENT_USB); } @@ -457,8 +325,8 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) IPACMDBG_H("Received IPA_ADDR_ADD_EVENT\n"); /* only call ioctl for ODU iface with bridge mode */ - if((IPACM_Iface::ipacmcfg->ipacm_odu_enable == true) && (IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false) - && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)) + if(IPACM_Iface::ipacmcfg->ipacm_odu_enable == true && IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false + && ipa_if_cate == ODU_IF) { if((data->iptype == IPA_IP_v6) && (num_dft_rt_v6 == 0)) { @@ -483,16 +351,6 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) { return; } - /* ADD ipv4 icmp rule */ - if (data->iptype == IPA_IP_v4) - { - install_ipv4_icmp_flt_rule(); - } - /* ADD ipv6 icmp rule */ - if ((num_dft_rt_v6 == 1) && (data->iptype == IPA_IP_v6)) - { - install_ipv6_icmp_flt_rule(); - } #ifdef FEATURE_IPA_ANDROID add_dummy_private_subnet_flt_rule(data->iptype); @@ -522,6 +380,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) { if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1) { + memcpy(ipv6_prefix, IPACM_Wan::backhaul_ipv6_prefix, sizeof(ipv6_prefix)); install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); if(IPACM_Wan::backhaul_is_sta_mode == false) { @@ -624,6 +483,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) { if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { + memcpy(ipv6_prefix, data_wan_tether->ipv6_prefix, sizeof(ipv6_prefix)); install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix); if(data_wan_tether->is_sta == false) { @@ -719,16 +579,17 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { + memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix)); install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix); - if(data_wan->is_sta == false) - { + if(data_wan->is_sta == false) + { ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6); handle_wan_up_ex(ext_prop, IPA_IP_v6, 0); } - else - { - handle_wan_up(IPA_IP_v6); - } + else + { + handle_wan_up(IPA_IP_v6); + } } break; @@ -773,9 +634,9 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) ipacm_event_data_all *data = (ipacm_event_data_all *)param; ipa_interface_index = iface_ipa_index_query(data->if_index); IPACMDBG_H("Recieved IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT event \n"); - IPACMDBG_H("check iface %s category: %d\n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat); + IPACMDBG_H("check iface %s category: %d\n", dev_name, ipa_if_cate); - if ((ipa_interface_index == ipa_if_num) && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)) + if (ipa_interface_index == ipa_if_num && ipa_if_cate == ODU_IF) { IPACMDBG_H("ODU iface got v4-ip \n"); /* first construc ODU full header */ @@ -806,7 +667,6 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) IPACMDBG_H("ETH iface got client \n"); /* first construc ETH full header */ handle_eth_hdr_init(data->mac_addr); - handle_lan2lan_client_active(data, IPA_LAN_CLIENT_ACTIVE); IPACMDBG_H("construct ETH header and route rules \n"); /* Associate with IP and construct RT-rule */ if (handle_eth_client_ipaddr(data) == IPACM_FAILURE) @@ -819,36 +679,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) /* Add NAT rules after ipv4 RT rules are set */ CtList->HandleNeighIpAddrAddEvt(data); } -#ifdef FEATURE_ETH_BRIDGE_LE - if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) - { - if (IPACM_Lan::cpe_to_usb_hdr_proc_ctx.valid == true) - { - eth_bridge_add_lan_client_rt_rule(data->mac_addr, SRC_LAN, IPA_IP_v4); - eth_bridge_add_lan_client_rt_rule(data->mac_addr, SRC_LAN, IPA_IP_v6); - } - if (IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == true) - { - eth_bridge_add_lan_client_rt_rule(data->mac_addr, SRC_WLAN, IPA_IP_v4); - eth_bridge_add_lan_client_rt_rule(data->mac_addr, SRC_WLAN, IPA_IP_v6); - } - } - if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) - { - if (IPACM_Lan::usb_to_cpe_hdr_proc_ctx.valid == true) - { - eth_bridge_add_lan_client_rt_rule(data->mac_addr, SRC_LAN, IPA_IP_v4); - eth_bridge_add_lan_client_rt_rule(data->mac_addr, SRC_LAN, IPA_IP_v6); - } - if (IPACM_Lan::wlan_to_cpe_hdr_proc_ctx.valid == true) - { - eth_bridge_add_lan_client_rt_rule(data->mac_addr, SRC_WLAN, IPA_IP_v4); - eth_bridge_add_lan_client_rt_rule(data->mac_addr, SRC_WLAN, IPA_IP_v6); - } - } - eth_bridge_post_lan_client_event(data->mac_addr, IPA_ETH_BRIDGE_LAN_CLIENT_ADD_EVENT); - eth_bridge_add_lan_client(data->mac_addr); -#endif + eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->mac_addr); return; } } @@ -860,10 +691,9 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) ipa_interface_index = iface_ipa_index_query(data->if_index); IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT event. \n"); - IPACMDBG_H("check iface %s category: %d\n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat); + IPACMDBG_H("check iface %s category: %d\n", dev_name, ipa_if_cate); /* if ODU in bridge mode, directly return */ - if ((ipa_interface_index == ipa_if_num) && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) - && (IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false)) + if (ipa_if_cate == ODU_IF && IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false) { IPACMDBG_H("ODU is in bridge mode, no action \n"); return; @@ -876,35 +706,11 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) handle_del_ipv6_addr(data); return; } -#ifdef FEATURE_ETH_BRIDGE_LE - if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) - { - if (IPACM_Lan::cpe_to_usb_hdr_proc_ctx.valid == true) - { - eth_bridge_del_lan_client_rt_rule(data->mac_addr, SRC_LAN); - } - if (IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == true) - { - eth_bridge_del_lan_client_rt_rule(data->mac_addr, SRC_WLAN); - } - } - if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) - { - if (IPACM_Lan::usb_to_cpe_hdr_proc_ctx.valid == true) - { - eth_bridge_del_lan_client_rt_rule(data->mac_addr, SRC_LAN); - } - if (IPACM_Lan::wlan_to_cpe_hdr_proc_ctx.valid == true) - { - eth_bridge_del_lan_client_rt_rule(data->mac_addr, SRC_WLAN); - } - } - eth_bridge_post_lan_client_event(data->mac_addr, IPA_ETH_BRIDGE_LAN_CLIENT_DEL_EVENT); - eth_bridge_del_lan_client(data->mac_addr); -#endif + + eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_DEL, IPA_IP_MAX, data->mac_addr); + IPACMDBG_H("LAN iface delete client \n"); handle_eth_client_down_evt(data->mac_addr); - handle_lan2lan_client_active(data, IPA_LAN_CLIENT_INACTIVE); return; } } @@ -922,164 +728,6 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) handle_software_routing_disable(); break; - case IPA_ETH_BRIDGE_LAN_CLIENT_ADD_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_LAN_CLIENT_ADD_EVENT event.\n"); - ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param; - if(mac != NULL) - { - if (mac->if_index == ipa_if_num) - { - IPACMDBG_H("The event was sent by same interface, if_index: %d ignore. \n", mac->if_index); - return; - } - if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) - { - eth_bridge_add_lan_client_flt_rule(mac->mac_addr, IPA_IP_v4); - } - if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) - { - eth_bridge_add_lan_client_flt_rule(mac->mac_addr, IPA_IP_v6); - } - } - else - { - IPACMERR("Event MAC is empty.\n"); - } - } - break; - - case IPA_ETH_BRIDGE_LAN_CLIENT_DEL_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_LAN_CLIENT_DEL_EVENT event.\n"); - ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param; - if(mac != NULL) - { - if (mac->if_index == ipa_if_num) - { - IPACMDBG_H("The event was sent by same interface, if_index: %d ignore. \n", mac->if_index); - return; - } - if(eth_bridge_del_lan_client_flt_rule(mac->mac_addr) == IPACM_FAILURE) - { - IPACMDBG_H("Failed to delete lan client MAC based flt rule.\n"); - } - } - else - { - IPACMERR("Event MAC is empty.\n"); - } - } - break; - - case IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT event.\n"); - ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param; - if(mac != NULL) - { - if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) - { - eth_bridge_add_wlan_client_flt_rule(mac->mac_addr, IPA_IP_v4); - } - if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) - { - eth_bridge_add_wlan_client_flt_rule(mac->mac_addr, IPA_IP_v6); - } - } - else - { - IPACMERR("Event MAC is empty.\n"); - } - } - break; - - case IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT event.\n"); - ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param; - if(mac != NULL) - { - if(eth_bridge_del_wlan_client_flt_rule(mac->mac_addr) == IPACM_FAILURE) - { - IPACMDBG_H("Failed to delete wlan client MAC based flt rule.\n"); - } - } - else - { - IPACMERR("Event MAC is empty.\n"); - } - } - break; - - case IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT event.\n"); - int i; - ipacm_event_data_if_cat* cat = (ipacm_event_data_if_cat*)param; - if(cat == NULL) - { - IPACMERR("Event data is empty.\n"); - return; - } - if (cat->if_cat == IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat) - { - IPACMDBG_H("The event was sent by same interface, if_cat: %d ignore. \n", cat->if_cat); - return; - } - - for(i=0; i<IPACM_Lan::num_lan_client; i++) - { - if(IPACM_Lan::eth_bridge_lan_client[i].ipa_if_num == ipa_if_num) - { - if (cat->if_cat == WLAN_IF) - { - eth_bridge_add_lan_client_rt_rule(IPACM_Lan::eth_bridge_lan_client[i].mac, SRC_WLAN, IPA_IP_v4); - eth_bridge_add_lan_client_rt_rule(IPACM_Lan::eth_bridge_lan_client[i].mac, SRC_WLAN, IPA_IP_v6); - } - else - { - eth_bridge_add_lan_client_rt_rule(IPACM_Lan::eth_bridge_lan_client[i].mac, SRC_LAN, IPA_IP_v4); - eth_bridge_add_lan_client_rt_rule(IPACM_Lan::eth_bridge_lan_client[i].mac, SRC_LAN, IPA_IP_v6); - } - } - } - } - break; - - case IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT event.\n"); - int i; - ipacm_event_data_if_cat* cat = (ipacm_event_data_if_cat*)param; - if(cat == NULL) - { - IPACMERR("Event data is empty.\n"); - return; - } - if (cat->if_cat == IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat) - { - IPACMDBG_H("The event was sent by same interface, if_cat: %d ignore.\n", cat->if_cat); - return; - } - - for(i=0; i<IPACM_Lan::num_lan_client; i++) - { - if(IPACM_Lan::eth_bridge_lan_client[i].ipa_if_num == ipa_if_num) - { - if (cat->if_cat == WLAN_IF) - { - eth_bridge_del_lan_client_rt_rule(IPACM_Lan::eth_bridge_lan_client[i].mac, SRC_WLAN); - } - else - { - eth_bridge_del_lan_client_rt_rule(IPACM_Lan::eth_bridge_lan_client[i].mac, SRC_LAN); - } - } - } - } - break; - case IPA_CRADLE_WAN_MODE_SWITCH: { IPACMDBG_H("Received IPA_CRADLE_WAN_MODE_SWITCH event.\n"); @@ -1292,16 +940,16 @@ int IPACM_Lan::handle_addr_evt(ipacm_event_data_addr *data) /* Add private subnet*/ #ifdef FEATURE_IPA_ANDROID -if (data->iptype == IPA_IP_v4) -{ - IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet); - if_ipv4_subnet = (data->ipv4_addr >> 8) << 8; - IPACMDBG_H(" Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); - if(IPACM_Iface::ipacmcfg->AddPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false) + if (data->iptype == IPA_IP_v4) { - IPACMERR(" can't Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); + IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet); + if_ipv4_subnet = (data->ipv4_addr >> 8) << 8; + IPACMDBG_H(" Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); + if(IPACM_Iface::ipacmcfg->AddPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false) + { + IPACMERR(" can't Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); + } } -} #endif /* defined(FEATURE_IPA_ANDROID)*/ if (data->iptype == IPA_IP_v4) @@ -1323,9 +971,12 @@ if (data->iptype == IPA_IP_v4) rt_rule_entry->at_rear = false; rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; //go to A5 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name); + strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name)); rt_rule_entry->rule.attrib.u.v4.dst_addr = data->ipv4_addr; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -1341,19 +992,13 @@ if (data->iptype == IPA_IP_v4) dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl; IPACMDBG_H("ipv4 iface rt-rule hdl1=0x%x\n", dft_rt_rule_hdl[0]); /* initial multicast/broadcast/fragment filter rule */ -#ifdef FEATURE_ETH_BRIDGE_LE - init_fl_rule(data->iptype); - eth_bridge_handle_dummy_wlan_client_flt_rule(data->iptype); - eth_bridge_handle_dummy_lan_client_flt_rule(data->iptype); - eth_bridge_install_cache_wlan_client_flt_rule(data->iptype); - eth_bridge_install_cache_lan_client_flt_rule(data->iptype); -#else -#ifdef CT_OPT - install_tcp_ctl_flt_rule(IPA_IP_v4); -#endif + init_fl_rule(data->iptype); - add_dummy_lan2lan_flt_rule(data->iptype); -#endif + install_ipv4_icmp_flt_rule(); + + /* populate the flt rule offset for eth bridge */ + eth_bridge_flt_rule_offset[data->iptype] = ipv4_icmp_flt_rule_hdl[0]; + eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v4, NULL); } else { @@ -1383,7 +1028,7 @@ if (data->iptype == IPA_IP_v4) rt_rule->commit = 1; rt_rule->num_rules = NUM_RULES; rt_rule->ip = data->iptype; - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name); + strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name)); rt_rule_entry = &rt_rule->rules[0]; rt_rule_entry->at_rear = false; @@ -1401,6 +1046,9 @@ if (data->iptype == IPA_IP_v4) ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1]; ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2]; ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3]; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -1416,7 +1064,7 @@ if (data->iptype == IPA_IP_v4) dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl; /* setup same rule for v6_wan table*/ - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name); + strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name)); if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -1437,20 +1085,13 @@ if (data->iptype == IPA_IP_v4) if (num_dft_rt_v6 == 0) { - /* initial multicast/broadcast/fragment filter rule */ -#ifdef FEATURE_ETH_BRIDGE_LE - eth_bridge_handle_dummy_wlan_client_flt_rule(data->iptype); - eth_bridge_handle_dummy_lan_client_flt_rule(data->iptype); - eth_bridge_install_cache_wlan_client_flt_rule(data->iptype); - eth_bridge_install_cache_lan_client_flt_rule(data->iptype); - init_fl_rule(data->iptype); -#else -#ifdef CT_OPT - install_tcp_ctl_flt_rule(IPA_IP_v6); -#endif - add_dummy_lan2lan_flt_rule(data->iptype); + install_ipv6_icmp_flt_rule(); + + /* populate the flt rule offset for eth bridge */ + eth_bridge_flt_rule_offset[data->iptype] = ipv6_icmp_flt_rule_hdl[0]; + eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v6, NULL); + init_fl_rule(data->iptype); -#endif } num_dft_rt_v6++; IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6); @@ -1498,13 +1139,6 @@ int IPACM_Lan::handle_private_subnet(ipa_ip_type iptype) m_pFilteringTable->ip = IPA_IP_v4; m_pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet; - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan_v4)) - { - IPACMERR("LAN m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan_v4=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_lan_v4); - free(m_pFilteringTable); - return IPACM_FAILURE; - } - /* Make LAN-traffic always go A5, use default IPA-RT table */ if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4)) { @@ -1521,6 +1155,9 @@ int IPACM_Lan::handle_private_subnet(ipa_ip_type iptype) flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif /* Support private subnet feature including guest-AP can't talk to primary AP etc */ flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl; IPACMDBG_H(" private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name); @@ -1613,6 +1250,9 @@ int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type) { flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; //IPA_PASS_TO_ROUTING } +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl; memcpy(&flt_rule_entry.rule.attrib, @@ -1675,6 +1315,9 @@ int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type) flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_v6.hdl; memcpy(&flt_rule_entry.rule.attrib, @@ -2039,6 +1682,8 @@ int IPACM_Lan::handle_eth_client_ipaddr(ipacm_event_data_all *data) { int clnt_indx; int v6_num; + uint32_t ipv6_link_local_prefix = 0xFE800000; + uint32_t ipv6_link_local_prefix_mask = 0xFFC00000; IPACMDBG_H("number of eth clients: %d\n", num_eth_client); IPACMDBG_H("event MAC %02x:%02x:%02x:%02x:%02x:%02x\n", @@ -2085,10 +1730,10 @@ int IPACM_Lan::handle_eth_client_ipaddr(ipacm_event_data_all *data) get_client_memptr(eth_client, clnt_indx)->route_rule_set_v4 = false; get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr; } + } } - } - else - { + else + { IPACMDBG_H("Invalid client IPv4 address \n"); return IPACM_FAILURE; } @@ -2098,21 +1743,28 @@ int IPACM_Lan::handle_eth_client_ipaddr(ipacm_event_data_all *data) if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) || (data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] || 0)) /* check if all 0 not valid ipv6 address */ { - IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); - if(get_client_memptr(eth_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR) - { + IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); + if( (data->ipv6_addr[0] & ipv6_link_local_prefix_mask) != (ipv6_link_local_prefix & ipv6_link_local_prefix_mask) && + memcmp(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)) != 0) + { + IPACMDBG_H("This IPv6 address is not global IPv6 address with correct prefix, ignore.\n"); + return IPACM_FAILURE; + } + + if(get_client_memptr(eth_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR) + { for(v6_num=0;v6_num < get_client_memptr(eth_client, clnt_indx)->ipv6_set;v6_num++) - { - if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][0] && + { + if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][0] && data->ipv6_addr[1] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][1] && data->ipv6_addr[2]== get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][2] && data->ipv6_addr[3] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][3]) - { - IPACMDBG_H("Already see this ipv6 addr at position: %d for client:%d\n", v6_num, clnt_indx); - return IPACM_FAILURE; /* not setup the RT rules*/ - } - } + { + IPACMDBG_H("Already see this ipv6 addr at position: %d for client:%d\n", v6_num, clnt_indx); + return IPACM_FAILURE; /* not setup the RT rules*/ + } + } /* not see this ipv6 before for wifi client*/ get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0]; @@ -2123,8 +1775,8 @@ int IPACM_Lan::handle_eth_client_ipaddr(ipacm_event_data_all *data) } else { - IPACMDBG_H("Already got 3 ipv6 addr for client:%d\n", clnt_indx); - return IPACM_FAILURE; /* not setup the RT rules*/ + IPACMDBG_H("Already got %d ipv6 addr for client:%d\n", IPV6_NUM_ADDR, clnt_indx); + return IPACM_FAILURE; /* not setup the RT rules*/ } } } @@ -2229,6 +1881,9 @@ int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptyp rt_rule_entry->rule.hdr_hdl = get_client_memptr(eth_client, eth_index)->hdr_hdl_v4; rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(eth_client, eth_index)->v4_addr; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -2268,6 +1923,9 @@ int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptyp rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -2297,6 +1955,9 @@ int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptyp rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -2400,7 +2061,7 @@ int IPACM_Lan::handle_odu_hdr_init(uint8_t *mac_addr) memset(pHeaderDescriptor->hdr[0].name, 0, sizeof(pHeaderDescriptor->hdr[0].name)); - strcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v4); + strlcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)); pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeaderDescriptor->hdr[0].hdr_hdl = -1; pHeaderDescriptor->hdr[0].is_partial = 0; @@ -2480,7 +2141,7 @@ int IPACM_Lan::handle_odu_hdr_init(uint8_t *mac_addr) memset(pHeaderDescriptor->hdr[0].name, 0, sizeof(pHeaderDescriptor->hdr[0].name)); - strcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v6); + strlcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)); pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; pHeaderDescriptor->hdr[0].hdr_hdl = -1; pHeaderDescriptor->hdr[0].is_partial = 0; @@ -2547,13 +2208,13 @@ int IPACM_Lan::handle_odu_route_add() if (IPA_IP_v4 == tx_prop->tx[tx_index].ip) { - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name); + strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name, sizeof(rt_rule->rt_tbl_name)); rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v4; rt_rule->ip = IPA_IP_v4; } else { - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name); + strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name, sizeof(rt_rule->rt_tbl_name)); rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v6; rt_rule->ip = IPA_IP_v6; } @@ -2568,6 +2229,9 @@ int IPACM_Lan::handle_odu_route_add() { rt_rule_entry->rule.attrib.u.v4.dst_addr = 0; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -2590,6 +2254,9 @@ int IPACM_Lan::handle_odu_route_add() rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -2779,10 +2446,9 @@ int IPACM_Lan::handle_down_evt() { int i; int res = IPACM_SUCCESS; - uint32_t temp_eth_bridge_flt_rule[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; IPACMDBG_H("lan handle_down_evt\n "); - if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) + if (ipa_if_cate == ODU_IF) { /* delete ODU default RT rules */ if (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true) @@ -2823,28 +2489,6 @@ int IPACM_Lan::handle_down_evt() goto fail; } -#ifdef FEATURE_ETH_BRIDGE_LE - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) - { - IPACM_Lan::usb_hdr_template_hdl = 0; - IPACM_Lan::is_usb_up = false; - if(IPACM_Lan::is_cpe_up == false) //if all LAN ifaces are down - { - IPACM_Lan::lan_hdr_type = IPA_HDR_L2_NONE; - } - } - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) - { - IPACM_Lan::cpe_hdr_template_hdl = 0; - IPACM_Lan::is_cpe_up = false; - if(IPACM_Lan::is_usb_up == false) //if all LAN ifaces are down - { - IPACM_Lan::lan_hdr_type = IPA_HDR_L2_NONE; - } - } - del_hdr_proc_ctx(); -#endif - /* delete wan filter rule */ if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL) { @@ -2876,71 +2520,6 @@ int IPACM_Lan::handle_down_evt() goto fail; } IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES); -#ifdef FEATURE_ETH_BRIDGE_LE - for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) - { - temp_eth_bridge_flt_rule[i] = wlan_client_flt_rule_hdl_v4[i].rule_hdl; - } - if (m_filtering.DeleteFilteringHdls(temp_eth_bridge_flt_rule, IPA_IP_v4, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) == false) - { - IPACMERR("Error Deleting Filtering Rule, aborting...\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT); - - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) - { - for(i=0; i<IPA_LAN_TO_LAN_MAX_CPE_CLIENT; i++) - { - temp_eth_bridge_flt_rule[i] = lan_client_flt_rule_hdl_v4[i].rule_hdl; - } - if (m_filtering.DeleteFilteringHdls(temp_eth_bridge_flt_rule, IPA_IP_v4, IPA_LAN_TO_LAN_MAX_CPE_CLIENT) == false) - { - IPACMERR("Error Deleting Filtering Rule, aborting...\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_LAN_TO_LAN_MAX_CPE_CLIENT); - } - - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) - { - for(i=0; i<IPA_LAN_TO_LAN_MAX_USB_CLIENT; i++) - { - temp_eth_bridge_flt_rule[i] = lan_client_flt_rule_hdl_v4[i].rule_hdl; - } - if (m_filtering.DeleteFilteringHdls(temp_eth_bridge_flt_rule, IPA_IP_v4, IPA_LAN_TO_LAN_MAX_USB_CLIENT) == false) - { - IPACMERR("Error Deleting Filtering Rule, aborting...\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_LAN_TO_LAN_MAX_USB_CLIENT); - } -#endif -#ifndef FEATURE_ETH_BRIDGE_LE -#ifdef CT_OPT - if (m_filtering.DeleteFilteringHdls(tcp_ctl_flt_rule_hdl_v4, IPA_IP_v4, NUM_TCP_CTL_FLT_RULE) == false) - { - IPACMERR("Error deleting default filtering Rule, aborting...\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, NUM_TCP_CTL_FLT_RULE); -#endif - for(i=0; i<MAX_OFFLOAD_PAIR; i++) - { - if(m_filtering.DeleteFilteringHdls(&(lan2lan_flt_rule_hdl_v4[i].rule_hdl), IPA_IP_v4, 1) == false) - { - IPACMERR("Error deleting lan2lan IPv4 flt rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1); - } - IPACMDBG_H("Deleted lan2lan IPv4 flt rules.\n"); -#endif /* free private-subnet ipv4 filter rules */ if (IPACM_Iface::ipacmcfg->ipa_num_private_subnet > IPA_PRIV_SUBNET_FILTER_RULE_HANDLES) @@ -2961,12 +2540,13 @@ int IPACM_Lan::handle_down_evt() #else if (m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet) == false) { - IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n"); + IPACMERR("Error deleting private subnet IPv4 flt rules.\n"); res = IPACM_FAILURE; goto fail; } IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet); #endif + IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n"); } IPACMDBG_H("Finished delete default iface ipv4 filtering rules \n "); @@ -2987,71 +2567,6 @@ int IPACM_Lan::handle_down_evt() goto fail; } IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES); -#ifdef FEATURE_ETH_BRIDGE_LE - for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) - { - temp_eth_bridge_flt_rule[i] = wlan_client_flt_rule_hdl_v6[i].rule_hdl; - } - if (m_filtering.DeleteFilteringHdls(temp_eth_bridge_flt_rule, IPA_IP_v6, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) == false) - { - IPACMERR("Error Deleting Filtering Rule, aborting...\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT); - - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) - { - for(i=0; i<IPA_LAN_TO_LAN_MAX_CPE_CLIENT; i++) - { - temp_eth_bridge_flt_rule[i] = lan_client_flt_rule_hdl_v6[i].rule_hdl; - } - if (m_filtering.DeleteFilteringHdls(temp_eth_bridge_flt_rule, IPA_IP_v6, IPA_LAN_TO_LAN_MAX_CPE_CLIENT) == false) - { - IPACMERR("Error Deleting Filtering Rule, aborting...\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPA_LAN_TO_LAN_MAX_CPE_CLIENT); - } - - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) - { - for(i=0; i<IPA_LAN_TO_LAN_MAX_USB_CLIENT; i++) - { - temp_eth_bridge_flt_rule[i] = lan_client_flt_rule_hdl_v6[i].rule_hdl; - } - if (m_filtering.DeleteFilteringHdls(temp_eth_bridge_flt_rule, IPA_IP_v6, IPA_LAN_TO_LAN_MAX_USB_CLIENT) == false) - { - IPACMERR("Error Deleting Filtering Rule, aborting...\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPA_LAN_TO_LAN_MAX_USB_CLIENT); - } -#endif -#ifndef FEATURE_ETH_BRIDGE_LE -#ifdef CT_OPT - if (m_filtering.DeleteFilteringHdls(tcp_ctl_flt_rule_hdl_v6, IPA_IP_v6, NUM_TCP_CTL_FLT_RULE) == false) - { - IPACMERR("Error deleting default filtering Rule, aborting...\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_TCP_CTL_FLT_RULE); -#endif - for(i=0; i<MAX_OFFLOAD_PAIR; i++) - { - if(m_filtering.DeleteFilteringHdls(&(lan2lan_flt_rule_hdl_v6[i].rule_hdl), IPA_IP_v6, 1) == false) - { - IPACMERR("Error deleting lan2lan IPv4 flt rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); - } - IPACMDBG_H("Deleted lan2lan IPv6 flt rules.\n"); -#endif } IPACMDBG_H("Finished delete default iface ipv6 filtering rules \n "); @@ -3088,13 +2603,6 @@ int IPACM_Lan::handle_down_evt() IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client); for (i = 0; i < num_eth_client; i++) { -#ifdef FEATURE_ETH_BRIDGE_LE - eth_bridge_del_lan_client_rt_rule(get_client_memptr(eth_client, i)->mac, SRC_LAN); - eth_bridge_del_lan_client_rt_rule(get_client_memptr(eth_client, i)->mac, SRC_WLAN); - eth_bridge_post_lan_client_event(get_client_memptr(eth_client, i)->mac, IPA_ETH_BRIDGE_LAN_CLIENT_DEL_EVENT); - eth_bridge_del_lan_client(get_client_memptr(eth_client, i)->mac); -#endif - /* First reset nat rules and then route rules */ if(get_client_memptr(eth_client, i)->ipv4_set == true) { @@ -3156,9 +2664,7 @@ int IPACM_Lan::handle_down_evt() handle_software_routing_disable(); } - /* posting ip to lan2lan module to delete RT/FILTER rules*/ - post_lan2lan_client_disconnect_msg(IPA_IP_v4); - post_lan2lan_client_disconnect_msg(IPA_IP_v6); + eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL); /* Delete private subnet*/ #ifdef FEATURE_IPA_ANDROID @@ -3173,7 +2679,7 @@ int IPACM_Lan::handle_down_evt() } /* reset the IPA-client pipe enum */ - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != WAN_IF) + if(ipa_if_cate != WAN_IF) { handle_tethering_client(true, IPACM_CLIENT_USB); } @@ -3210,24 +2716,7 @@ fail: { free(iface_query); } -#ifdef FEATURE_ETH_BRIDGE_LE - if(eth_bridge_lan_client_rt_from_lan_info_v4 != NULL) - { - free(eth_bridge_lan_client_rt_from_lan_info_v4); - } - if(eth_bridge_lan_client_rt_from_lan_info_v6 != NULL) - { - free(eth_bridge_lan_client_rt_from_lan_info_v6); - } - if(eth_bridge_lan_client_rt_from_wlan_info_v4 != NULL) - { - free(eth_bridge_lan_client_rt_from_wlan_info_v4); - } - if(eth_bridge_lan_client_rt_from_wlan_info_v6 != NULL) - { - free(eth_bridge_lan_client_rt_from_wlan_info_v6); - } -#endif + is_active = false; post_del_self_evt(); @@ -3245,7 +2734,7 @@ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptyp int i, index; uint32_t value = 0; - IPACMDBG_H("Set extended property rules in LAN\n"); + IPACMDBG_H("Set modem UL flt rules\n"); if (rx_prop == NULL) { @@ -3324,8 +2813,7 @@ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptyp flt_rule_entry.rule.eq_attrib_type = 1; if(iptype == IPA_IP_v4) { - if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF && - IPACM_Wan::isWan_Bridge_Mode()) + if (ipa_if_cate == ODU_IF && IPACM_Wan::isWan_Bridge_Mode()) { IPACMDBG_H("WAN, ODU are in bridge mode \n"); flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; @@ -3346,19 +2834,6 @@ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptyp index = IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, iptype); -#ifndef FEATURE_IPA_ANDROID - if(iptype == IPA_IP_v4 && index != exp_index_v4) - { - IPACMDBG_DMESG("### WARNING ### num flt rules for IPv4 on client %d is not expected: %d expected value: %d", - rx_prop->rx[0].src_pipe, index, exp_index_v4); - } - if(iptype == IPA_IP_v6 && index != exp_index_v6) - { - IPACMDBG_DMESG("### WARNING ### num flt rules for IPv6 on client %d is not expected: %d expected value: %d", - rx_prop->rx[0].src_pipe, index, exp_index_v6); - } -#endif - for(cnt=0; cnt<prop->num_ext_props; cnt++) { memcpy(&flt_rule_entry.rule.eq_attrib, @@ -3381,6 +2856,14 @@ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptyp #ifdef FEATURE_IPA_V3 flt_rule_entry.rule.hashable = prop->prop[cnt].is_rule_hashable; flt_rule_entry.rule.rule_id = prop->prop[cnt].rule_id; + if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA) //turn on meta-data equation + { + flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<9); + 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; + } #endif memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry)); @@ -3454,6 +2937,8 @@ int IPACM_Lan::handle_wan_down_v6(bool is_sta_mode) delete_ipv6_prefix_flt_rule(); + memset(ipv6_prefix, 0, sizeof(ipv6_prefix)); + if(is_sta_mode == false) { if (num_wan_ul_fl_rule_v6 > MAX_WAN_UL_FILTER_RULES) @@ -3518,466 +3003,6 @@ int IPACM_Lan::handle_wan_down_v6(bool is_sta_mode) return IPACM_SUCCESS; } - -/*handle lan2lan client active*/ -int IPACM_Lan::handle_lan2lan_client_active(ipacm_event_data_all *data, ipa_cm_event_id event) -{ - if((tx_prop == NULL) || (rx_prop == NULL)) - { - IPACMDBG_H("No tx/rx properties registered for iface %s, not posting lan2lan event(%d)\n", dev_name, event); - return IPACM_SUCCESS; - } - - if(data == NULL) - { - IPACMERR("Event data is empty.\n"); - return IPACM_FAILURE; - } - - if(data->iptype == IPA_IP_v4 && ip_type != IPA_IP_v4 && ip_type != IPA_IP_MAX) - { - IPACMERR("Client has IPv4 addr but iface does not have IPv4 up.\n"); - return IPACM_FAILURE; - } - if(data->iptype == IPA_IP_v6 && ip_type != IPA_IP_v6 && ip_type != IPA_IP_MAX) - { - IPACMERR("Client has IPv6 addr but iface does not have IPv6 up.\n"); - return IPACM_FAILURE; - } - - ipacm_cmd_q_data evt_data; - memset(&evt_data, 0, sizeof(evt_data)); - - ipacm_event_lan_client* lan_client; - lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client)); - if(lan_client == NULL) - { - IPACMERR("Unable to allocate memory.\n"); - return IPACM_FAILURE; - } - memset(lan_client, 0, sizeof(ipacm_event_lan_client)); - lan_client->iptype = data->iptype; - lan_client->ipv4_addr = data->ipv4_addr; - memcpy(lan_client->ipv6_addr, data->ipv6_addr, 4 * sizeof(uint32_t)); - memcpy(lan_client->mac_addr, data->mac_addr, 6 * sizeof(uint8_t)); - lan_client->p_iface = this; - - evt_data.event = event; - evt_data.evt_data = (void*)lan_client; - - IPACMDBG_H("Posting event: %d\n", event); - IPACM_EvtDispatcher::PostEvt(&evt_data); - return IPACM_SUCCESS; -} - -int IPACM_Lan::add_lan2lan_flt_rule(ipa_ip_type iptype, uint32_t src_v4_addr, uint32_t dst_v4_addr, uint32_t* src_v6_addr, uint32_t* dst_v6_addr, uint32_t* rule_hdl) -{ - if(rx_prop == NULL) - { - IPACMERR("There is no rx_prop for iface %s, not able to add lan2lan filtering rule.\n", dev_name); - return IPACM_FAILURE; - } - if(rule_hdl == NULL) - { - IPACMERR("Filteing rule handle is empty.\n"); - return IPACM_FAILURE; - } - - IPACMDBG_H("Got a new lan2lan flt rule with IP type: %d\n", iptype); - - int i, len, res = IPACM_SUCCESS; - struct ipa_flt_rule_mdfy flt_rule; - struct ipa_ioc_mdfy_flt_rule* pFilteringTable; - - len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy); - - pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); - - if (pFilteringTable == NULL) - { - IPACMERR("Error allocate lan2lan flt rule memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - pFilteringTable->commit = 1; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = 1; - - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); - - if(iptype == IPA_IP_v4) - { - IPACMDBG_H("src_v4_addr: %d dst_v4_addr: %d\n", src_v4_addr, dst_v4_addr); - - if(num_lan2lan_flt_rule_v4 >= MAX_OFFLOAD_PAIR) - { - IPACMERR("Lan2lan flt rule table is full, not able to add.\n"); - res = IPACM_FAILURE; - goto fail; - } - - if(false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v4)) - { - IPACMERR("Failed to get routing table %s handle.\n", IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v4.name); - res = IPACM_FAILURE; - goto fail; - } - IPACMDBG_H("Routing handle for table %s: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v4.name, - IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v4.hdl); - - flt_rule.status = -1; - for(i=0; i<MAX_OFFLOAD_PAIR; i++) - { - if(lan2lan_flt_rule_hdl_v4[i].valid == false) - { - flt_rule.rule_hdl = lan2lan_flt_rule_hdl_v4[i].rule_hdl; - break; - } - } - if(i == MAX_OFFLOAD_PAIR) - { - IPACMERR("Failed to find a filtering rule.\n"); - res = IPACM_FAILURE; - goto fail; - } - - flt_rule.rule.retain_hdr = 0; - flt_rule.rule.to_uc = 0; - flt_rule.rule.eq_attrib_type = 0; - flt_rule.rule.action = IPA_PASS_TO_ROUTING; - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v4.hdl; - - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, - sizeof(flt_rule.rule.attrib)); - IPACMDBG_H("Rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask); - - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR; - flt_rule.rule.attrib.u.v4.src_addr = src_v4_addr; - flt_rule.rule.attrib.u.v4.src_addr_mask = 0xFFFFFFFF; - - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v4.dst_addr = dst_v4_addr; - flt_rule.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; - - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) - { - IPACMERR("Error modifying filtering rule.\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - lan2lan_flt_rule_hdl_v4[i].valid = true; - *rule_hdl = lan2lan_flt_rule_hdl_v4[i].rule_hdl; - num_lan2lan_flt_rule_v4++; - IPACMDBG_H("Flt rule modified, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl, - pFilteringTable->rules[0].status); - } - } - else if(iptype == IPA_IP_v6) - { - if(num_lan2lan_flt_rule_v6 >= MAX_OFFLOAD_PAIR) - { - IPACMERR("Lan2lan flt rule table is full, not able to add.\n"); - res = IPACM_FAILURE; - goto fail; - } - if(src_v6_addr == NULL || dst_v6_addr == NULL) - { - IPACMERR("Got IPv6 flt rule but without IPv6 src/dst addr.\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x\n", src_v6_addr[0], src_v6_addr[1], - src_v6_addr[2], src_v6_addr[3], dst_v6_addr[0], dst_v6_addr[1], dst_v6_addr[2], dst_v6_addr[3]); - - if(false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6)) - { - IPACMERR("Failed to get routing table %s handle.\n", IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6.name); - res = IPACM_FAILURE; - goto fail; - } - IPACMDBG_H("Routing handle for table %s: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6.name, - IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6.hdl); - - flt_rule.status = -1; - for(i=0; i<MAX_OFFLOAD_PAIR; i++) - { - if(lan2lan_flt_rule_hdl_v6[i].valid == false) - { - flt_rule.rule_hdl = lan2lan_flt_rule_hdl_v6[i].rule_hdl; - break; - } - } - if(i == MAX_OFFLOAD_PAIR) - { - IPACMERR("Failed to find a filtering rule handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - - flt_rule.rule.retain_hdr = 0; - flt_rule.rule.to_uc = 0; - flt_rule.rule.eq_attrib_type = 0; - flt_rule.rule.action = IPA_PASS_TO_ROUTING; - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6.hdl; - - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, - sizeof(flt_rule.rule.attrib)); - IPACMDBG_H("Rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask); - - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR; - flt_rule.rule.attrib.u.v6.src_addr[0] = src_v6_addr[0]; - flt_rule.rule.attrib.u.v6.src_addr[1] = src_v6_addr[1]; - flt_rule.rule.attrib.u.v6.src_addr[2] = src_v6_addr[2]; - flt_rule.rule.attrib.u.v6.src_addr[3] = src_v6_addr[3]; - flt_rule.rule.attrib.u.v6.src_addr_mask[0] = 0xFFFFFFFF; - flt_rule.rule.attrib.u.v6.src_addr_mask[1] = 0xFFFFFFFF; - flt_rule.rule.attrib.u.v6.src_addr_mask[2] = 0xFFFFFFFF; - flt_rule.rule.attrib.u.v6.src_addr_mask[3] = 0xFFFFFFFF; - - - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v6.dst_addr[0] = dst_v6_addr[0]; - flt_rule.rule.attrib.u.v6.dst_addr[1] = dst_v6_addr[1]; - flt_rule.rule.attrib.u.v6.dst_addr[2] = dst_v6_addr[2]; - flt_rule.rule.attrib.u.v6.dst_addr[3] = dst_v6_addr[3]; - flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; - flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; - flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; - flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; - - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) - { - IPACMERR("Error modifying filtering rule.\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - lan2lan_flt_rule_hdl_v6[i].valid = true; - *rule_hdl = lan2lan_flt_rule_hdl_v6[i].rule_hdl; - num_lan2lan_flt_rule_v6++; - IPACMDBG_H("Flt rule modified, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl, - pFilteringTable->rules[0].status); - } - } - else - { - IPACMERR("IP type is not expected.\n"); - res = IPACM_FAILURE; - goto fail; - } - -fail: - free(pFilteringTable); - return res; -} - -int IPACM_Lan::add_dummy_lan2lan_flt_rule(ipa_ip_type iptype) -{ - if(rx_prop == NULL) - { - IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy lan2lan filtering rule.\n", dev_name); - return 0; - } - - int i, len, res = IPACM_SUCCESS; - struct ipa_flt_rule_add flt_rule; - ipa_ioc_add_flt_rule* pFilteringTable; - - len = sizeof(struct ipa_ioc_add_flt_rule) + MAX_OFFLOAD_PAIR * sizeof(struct ipa_flt_rule_add); - - pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); - if (pFilteringTable == NULL) - { - IPACMERR("Error allocate flt table memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - pFilteringTable->commit = 1; - pFilteringTable->ep = rx_prop->rx[0].src_pipe; - pFilteringTable->global = false; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = MAX_OFFLOAD_PAIR; - - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); - - flt_rule.rule.retain_hdr = 0; - flt_rule.at_rear = true; - flt_rule.flt_rule_hdl = -1; - flt_rule.status = -1; - flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, - sizeof(flt_rule.rule.attrib)); - - if(iptype == IPA_IP_v4) - { - flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; - flt_rule.rule.attrib.u.v4.src_addr = ~0; - flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; - flt_rule.rule.attrib.u.v4.dst_addr = ~0; - - for(i=0; i<MAX_OFFLOAD_PAIR; i++) - { - memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); - } - - if (false == m_filtering.AddFilteringRule(pFilteringTable)) - { - IPACMERR("Error adding dummy lan2lan v4 flt rule\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, MAX_OFFLOAD_PAIR); - /* copy filter rule hdls */ - for (int i = 0; i < MAX_OFFLOAD_PAIR; i++) - { - if (pFilteringTable->rules[i].status == 0) - { - lan2lan_flt_rule_hdl_v4[i].rule_hdl = pFilteringTable->rules[i].flt_rule_hdl; - IPACMDBG_H("Lan2lan v4 flt rule %d hdl:0x%x\n", i, lan2lan_flt_rule_hdl_v4[i].rule_hdl); - } - else - { - IPACMERR("Failed adding lan2lan v4 flt rule %d\n", i); - res = IPACM_FAILURE; - goto fail; - } - } - } - } - else if(iptype == IPA_IP_v6) - { - flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0; - flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0; - flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0; - flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[0] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[1] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[2] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[3] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0; - - for(i=0; i<MAX_OFFLOAD_PAIR; i++) - { - memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); - } - - if (false == m_filtering.AddFilteringRule(pFilteringTable)) - { - IPACMERR("Error adding dummy lan2lan v6 flt rule\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, MAX_OFFLOAD_PAIR); - /* copy filter rule hdls */ - for (int i = 0; i < MAX_OFFLOAD_PAIR; i++) - { - if (pFilteringTable->rules[i].status == 0) - { - lan2lan_flt_rule_hdl_v6[i].rule_hdl = pFilteringTable->rules[i].flt_rule_hdl; - IPACMDBG_H("Lan2lan v6 flt rule %d hdl:0x%x\n", i, lan2lan_flt_rule_hdl_v6[i].rule_hdl); - } - else - { - IPACMERR("Failed adding lan2lan v6 flt rule %d\n", i); - res = IPACM_FAILURE; - goto fail; - } - } - } - } - else - { - IPACMERR("IP type is not expected.\n"); - goto fail; - } - -fail: - free(pFilteringTable); - return res; -} - -int IPACM_Lan::del_lan2lan_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl) -{ - int i; - - IPACMDBG_H("Del lan2lan flt rule with IP type: %d hdl: %d\n", iptype, rule_hdl); - if(iptype == IPA_IP_v4) - { - for(i=0; i<MAX_OFFLOAD_PAIR; i++) - { - if(lan2lan_flt_rule_hdl_v4[i].rule_hdl == rule_hdl) - { - if(reset_to_dummy_flt_rule(IPA_IP_v4, rule_hdl) == IPACM_FAILURE) - { - IPACMERR("Failed to delete lan2lan v4 flt rule %d\n", rule_hdl); - return IPACM_FAILURE; - } - IPACMDBG_H("Deleted lan2lan v4 flt rule %d\n", rule_hdl); - lan2lan_flt_rule_hdl_v4[i].valid = false; - num_lan2lan_flt_rule_v4--; - break; - } - } - - if(i == MAX_OFFLOAD_PAIR) //not finding the rule - { - IPACMERR("The rule is not found.\n"); - return IPACM_FAILURE; - } - } - else if(iptype == IPA_IP_v6) - { - for(i=0; i<MAX_OFFLOAD_PAIR; i++) - { - if(lan2lan_flt_rule_hdl_v6[i].rule_hdl == rule_hdl) - { - if(reset_to_dummy_flt_rule(IPA_IP_v6, rule_hdl) == IPACM_FAILURE) - { - IPACMERR("Failed to delete lan2lan v6 flt rule %d\n", rule_hdl); - return IPACM_FAILURE; - } - IPACMDBG_H("Deleted lan2lan v6 flt rule %d\n", rule_hdl); - lan2lan_flt_rule_hdl_v6[i].valid = false; - num_lan2lan_flt_rule_v6--; - break; - } - } - - if(i == MAX_OFFLOAD_PAIR) //not finding the rule - { - IPACMERR("The rule is not found.\n"); - return IPACM_FAILURE; - } - } - else - { - IPACMERR("IP type is not expected.\n"); - return IPACM_FAILURE; - } - - return IPACM_SUCCESS; -} - int IPACM_Lan::reset_to_dummy_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl) { int len, res = IPACM_SUCCESS; @@ -4077,451 +3102,6 @@ fail: return res; } -int IPACM_Lan::add_lan2lan_hdr(ipa_ip_type iptype, uint8_t* src_mac, uint8_t* dst_mac, uint32_t* hdr_hdl) -{ - if(tx_prop == NULL) - { - IPACMERR("There is no tx_prop, cannot add header.\n"); - return IPACM_FAILURE; - } - if(src_mac == NULL || dst_mac == NULL) - { - IPACMERR("Either src_mac or dst_mac is null, cannot add header.\n"); - return IPACM_FAILURE; - } - if(hdr_hdl == NULL) - { - IPACMERR("Header handle is empty.\n"); - return IPACM_FAILURE; - } - - int i, j, len; - int res = IPACM_SUCCESS; - char index[4]; - struct ipa_ioc_copy_hdr sCopyHeader; - struct ipa_ioc_add_hdr *pHeader; - - IPACMDBG_H("Get lan2lan header request, src_mac: 0x%02x%02x%02x%02x%02x%02x dst_mac: 0x%02x%02x%02x%02x%02x%02x\n", - src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5], dst_mac[0], dst_mac[1], - dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5]); - - len = sizeof(struct ipa_ioc_add_hdr) + sizeof(struct ipa_hdr_add); - pHeader = (struct ipa_ioc_add_hdr *)malloc(len); - if (pHeader == NULL) - { - IPACMERR("Failed to allocate header\n"); - return IPACM_FAILURE; - } - memset(pHeader, 0, len); - - if(iptype == IPA_IP_v4) - { /* copy partial header for v4*/ - for(i=0; i<tx_prop->num_tx_props; i++) - { - if(tx_prop->tx[i].ip == IPA_IP_v4) - { - IPACMDBG_H("Got v4-header name from %d tx props\n", i); - memset(&sCopyHeader, 0, sizeof(sCopyHeader)); - memcpy(sCopyHeader.name, tx_prop->tx[i].hdr_name, sizeof(sCopyHeader.name)); - - IPACMDBG_H("Header name: %s\n", sCopyHeader.name); - if(m_header.CopyHeader(&sCopyHeader) == false) - { - IPACMERR("Copy header failed\n"); - res = IPACM_FAILURE; - goto fail; - } - - IPACMDBG_H("Header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); - if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) - { - IPACMERR("Header oversize\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - memcpy(pHeader->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); - } - - if(sCopyHeader.is_eth2_ofst_valid) - { - memcpy(&pHeader->hdr[0].hdr[sCopyHeader.eth2_ofst], dst_mac, IPA_MAC_ADDR_SIZE); - memcpy(&pHeader->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE], src_mac, IPA_MAC_ADDR_SIZE); - } - else - { - IPACMERR("Ethernet 2 header offset is invalid.\n"); - } - - pHeader->commit = true; - pHeader->num_hdrs = 1; - - memset(pHeader->hdr[0].name, 0, sizeof(pHeader->hdr[0].name)); - strlcpy(pHeader->hdr[0].name, IPA_LAN_TO_LAN_USB_HDR_NAME_V4, sizeof(pHeader->hdr[0].name)); - pHeader->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0'; - for(j=0; j<MAX_OFFLOAD_PAIR; j++) - { - if( lan2lan_hdr_hdl_v4[j].valid == false) - { - IPACMDBG_H("Construct lan2lan hdr with index %d.\n", j); - break; - } - } - if(j == MAX_OFFLOAD_PAIR) - { - IPACMERR("Failed to find an available hdr index.\n"); - res = IPACM_FAILURE; - goto fail; - } - lan2lan_hdr_hdl_v4[j].valid = true; - snprintf(index,sizeof(index), "%d", j); - if (strlcat(pHeader->hdr[0].name, index, sizeof(pHeader->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) - { - IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeader->hdr[0].name)); - res = IPACM_FAILURE; - goto fail; - } - - pHeader->hdr[0].hdr_len = sCopyHeader.hdr_len; - pHeader->hdr[0].is_partial = 0; - pHeader->hdr[0].hdr_hdl = -1; - pHeader->hdr[0].status = -1; - - if (m_header.AddHeader(pHeader) == false || pHeader->hdr[0].status != 0) - { - IPACMERR("Ioctl IPA_IOC_ADD_HDR failed with status: %d\n", pHeader->hdr[0].status); - res = IPACM_FAILURE; - goto fail; - } - IPACMDBG_H("Installed v4 full header %s header handle 0x%08x\n", pHeader->hdr[0].name, - pHeader->hdr[0].hdr_hdl); - *hdr_hdl = pHeader->hdr[0].hdr_hdl; - lan2lan_hdr_hdl_v4[j].hdr_hdl = pHeader->hdr[0].hdr_hdl; - break; - } - } - } - else if(iptype == IPA_IP_v6) - { /* copy partial header for v6*/ - for(i=0; i<tx_prop->num_tx_props; i++) - { - if(tx_prop->tx[i].ip == IPA_IP_v6) - { - IPACMDBG_H("Got v6-header name from %d tx props\n", i); - memset(&sCopyHeader, 0, sizeof(sCopyHeader)); - memcpy(sCopyHeader.name, tx_prop->tx[i].hdr_name, sizeof(sCopyHeader.name)); - - IPACMDBG_H("Header name: %s\n", sCopyHeader.name); - if(m_header.CopyHeader(&sCopyHeader) == false) - { - IPACMERR("Copy header failed\n"); - res = IPACM_FAILURE; - goto fail; - } - - IPACMDBG_H("Header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); - if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) - { - IPACMERR("Header oversize\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - memcpy(pHeader->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); - } - if(sCopyHeader.is_eth2_ofst_valid) - { - memcpy(&pHeader->hdr[0].hdr[sCopyHeader.eth2_ofst], dst_mac, IPA_MAC_ADDR_SIZE); - memcpy(&pHeader->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE], src_mac, IPA_MAC_ADDR_SIZE); - } - else - { - IPACMERR("Ethernet 2 header offset is invalid.\n"); - } - - pHeader->commit = true; - pHeader->num_hdrs = 1; - - memset(pHeader->hdr[0].name, 0, sizeof(pHeader->hdr[0].name)); - strlcpy(pHeader->hdr[0].name, IPA_LAN_TO_LAN_USB_HDR_NAME_V6, sizeof(pHeader->hdr[0].name)); - pHeader->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0'; - for(j=0; j<MAX_OFFLOAD_PAIR; j++) - { - if( lan2lan_hdr_hdl_v6[j].valid == false) - { - IPACMDBG_H("Construct lan2lan hdr with index %d.\n", j); - break; - } - } - if(j == MAX_OFFLOAD_PAIR) - { - IPACMERR("Failed to find an available hdr index.\n"); - res = IPACM_FAILURE; - goto fail; - } - lan2lan_hdr_hdl_v6[j].valid = true; - snprintf(index,sizeof(index), "%d", j); - if (strlcat(pHeader->hdr[0].name, index, sizeof(pHeader->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) - { - IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeader->hdr[0].name)); - res = IPACM_FAILURE; - goto fail; - } - - pHeader->hdr[0].hdr_len = sCopyHeader.hdr_len; - pHeader->hdr[0].is_partial = 0; - pHeader->hdr[0].hdr_hdl = -1; - pHeader->hdr[0].status = -1; - - if (m_header.AddHeader(pHeader) == false || pHeader->hdr[0].status != 0) - { - IPACMERR("Ioctl IPA_IOC_ADD_HDR failed with status: %d\n", pHeader->hdr[0].status); - res = IPACM_FAILURE; - goto fail; - } - IPACMDBG_H("Installed v6 full header %s header handle 0x%08x\n", pHeader->hdr[0].name, - pHeader->hdr[0].hdr_hdl); - *hdr_hdl = pHeader->hdr[0].hdr_hdl; - lan2lan_hdr_hdl_v6[j].hdr_hdl = pHeader->hdr[0].hdr_hdl; - break; - } - } - } - else - { - IPACMERR("IP type is not expected.\n"); - } - -fail: - free(pHeader); - return res; -} - -int IPACM_Lan::del_lan2lan_hdr(ipa_ip_type iptype, uint32_t hdr_hdl) -{ - int i; - if (m_header.DeleteHeaderHdl(hdr_hdl) == false) - { - IPACMERR("Failed to delete header %d\n", hdr_hdl); - return IPACM_FAILURE; - } - IPACMDBG_H("Deleted header %d\n", hdr_hdl); - - if(iptype == IPA_IP_v4) - { - for(i=0; i<MAX_OFFLOAD_PAIR; i++) - { - if(lan2lan_hdr_hdl_v4[i].hdr_hdl == hdr_hdl) - { - lan2lan_hdr_hdl_v4[i].valid = false; - break; - } - } - if(i == MAX_OFFLOAD_PAIR) - { - IPACMERR("Failed to find corresponding hdr hdl.\n"); - return IPACM_FAILURE; - } - } - else if(iptype == IPA_IP_v6) - { - for(i=0; i<MAX_OFFLOAD_PAIR; i++) - { - if(lan2lan_hdr_hdl_v6[i].hdr_hdl == hdr_hdl) - { - lan2lan_hdr_hdl_v6[i].valid = false; - break; - } - } - if(i == MAX_OFFLOAD_PAIR) - { - IPACMERR("Failed to find corresponding hdr hdl.\n"); - return IPACM_FAILURE; - } - } - else - { - IPACMERR("IP type is not expected.\n"); - return IPACM_FAILURE; - } - return IPACM_SUCCESS; -} - -int IPACM_Lan::add_lan2lan_rt_rule(ipa_ip_type iptype, uint32_t src_v4_addr, uint32_t dst_v4_addr, - uint32_t* src_v6_addr, uint32_t* dst_v6_addr, uint32_t hdr_hdl, lan_to_lan_rt_rule_hdl* rule_hdl) -{ - struct ipa_ioc_add_rt_rule *rt_rule; - struct ipa_rt_rule_add *rt_rule_entry; - uint32_t tx_index; - int len; - int res = IPACM_SUCCESS; - - IPACMDBG_H("Got a new lan2lan rt rule with IP type: %d\n", iptype); - - if(rule_hdl == NULL) - { - IPACMERR("Rule hdl is empty.\n"); - return IPACM_FAILURE; - } - memset(rule_hdl, 0, sizeof(lan_to_lan_rt_rule_hdl)); - - if(tx_prop == NULL) - { - IPACMDBG_H("There is no tx_prop for iface %s, not able to add lan2lan routing rule.\n", dev_name); - return IPACM_FAILURE; - } - - len = sizeof(struct ipa_ioc_add_rt_rule) + sizeof(struct ipa_rt_rule_add); - rt_rule = (struct ipa_ioc_add_rt_rule *)malloc(len); - if (!rt_rule) - { - IPACMERR("Failed to allocate memory for rt rule\n"); - return IPACM_FAILURE; - } - memset(rt_rule, 0, len); - - rt_rule->commit = 1; - rt_rule->num_rules = 1; - rt_rule->ip = iptype; - - if(iptype == IPA_IP_v4) - { - IPACMDBG_H("src_v4_addr: 0x%08x dst_v4_addr: 0x%08x\n", src_v4_addr, dst_v4_addr); - - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v4.name); - rt_rule_entry = &rt_rule->rules[0]; - rt_rule_entry->at_rear = false; - rt_rule_entry->rt_rule_hdl = 0; - rt_rule_entry->status = -1; - - for (tx_index = 0; tx_index<iface_query->num_tx_props; tx_index++) - { - if(tx_prop->tx[tx_index].ip != IPA_IP_v4) - { - IPACMDBG_H("Tx:%d, iptype: %d conflict ip-type: %d bypass\n", - tx_index, tx_prop->tx[tx_index].ip, IPA_IP_v4); - continue; - } - - rt_rule_entry->rule.hdr_hdl = hdr_hdl; - rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; - memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[tx_index].attrib, - sizeof(rt_rule_entry->rule.attrib)); - - rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR; - rt_rule_entry->rule.attrib.u.v4.src_addr = src_v4_addr; - rt_rule_entry->rule.attrib.u.v4.src_addr_mask = 0xFFFFFFFF; - - rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; - rt_rule_entry->rule.attrib.u.v4.dst_addr = dst_v4_addr; - rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; - if(m_routing.AddRoutingRule(rt_rule) == false) - { - IPACMERR("Routing rule addition failed\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACMDBG_H("Added rt rule hdl: 0x%08x\n", rt_rule_entry->rt_rule_hdl); - rule_hdl->rule_hdl[rule_hdl->num_rule] = rt_rule_entry->rt_rule_hdl; - rule_hdl->num_rule++; - } - } - else if(iptype == IPA_IP_v6) - { - if(src_v6_addr == NULL || dst_v6_addr == NULL) - { - IPACMERR("Got IPv6 rt rule but without IPv6 src/dst addr.\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x\n", src_v6_addr[0], src_v6_addr[1], - src_v6_addr[2], src_v6_addr[3], dst_v6_addr[0], dst_v6_addr[1], dst_v6_addr[2], dst_v6_addr[3]); - - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6.name); - rt_rule_entry = &rt_rule->rules[0]; - rt_rule_entry->at_rear = false; - rt_rule_entry->rt_rule_hdl = 0; - rt_rule_entry->status = -1; - - for (tx_index = 0; tx_index<iface_query->num_tx_props; tx_index++) - { - if(tx_prop->tx[tx_index].ip != IPA_IP_v6) - { - IPACMDBG_H("Tx:%d, iptype: %d conflict ip-type: %d bypass\n", - tx_index, tx_prop->tx[tx_index].ip, IPA_IP_v6); - continue; - } - - rt_rule_entry->rule.hdr_hdl = hdr_hdl; - rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; - memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[tx_index].attrib, - sizeof(rt_rule_entry->rule.attrib)); - - rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR; - rt_rule_entry->rule.attrib.u.v6.src_addr[0] = src_v6_addr[0]; - rt_rule_entry->rule.attrib.u.v6.src_addr[1] = src_v6_addr[1]; - rt_rule_entry->rule.attrib.u.v6.src_addr[2] = src_v6_addr[2]; - rt_rule_entry->rule.attrib.u.v6.src_addr[3] = src_v6_addr[3]; - rt_rule_entry->rule.attrib.u.v6.src_addr_mask[0] = 0xFFFFFFFF; - rt_rule_entry->rule.attrib.u.v6.src_addr_mask[1] = 0xFFFFFFFF; - rt_rule_entry->rule.attrib.u.v6.src_addr_mask[2] = 0xFFFFFFFF; - rt_rule_entry->rule.attrib.u.v6.src_addr_mask[3] = 0xFFFFFFFF; - - rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; - rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = dst_v6_addr[0]; - rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = dst_v6_addr[1]; - rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = dst_v6_addr[2]; - rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = dst_v6_addr[3]; - rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; - rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; - rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; - rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; - if(m_routing.AddRoutingRule(rt_rule) == false) - { - IPACMERR("Routing rule addition failed\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACMDBG_H("Added rt rule hdl: 0x%08x\n", rt_rule_entry->rt_rule_hdl); - rule_hdl->rule_hdl[rule_hdl->num_rule] = rt_rule_entry->rt_rule_hdl; - rule_hdl->num_rule++; - } - } - else - { - IPACMERR("IP type is not expected.\n"); - } - -fail: - free(rt_rule); - return res; -} - -int IPACM_Lan::del_lan2lan_rt_rule(ipa_ip_type iptype, lan_to_lan_rt_rule_hdl rule_hdl) -{ - if(rule_hdl.num_rule <= 0 || rule_hdl.num_rule > MAX_NUM_PROP) - { - IPACMERR("The number of rule handles are not correct.\n"); - return IPACM_FAILURE; - } - - int i, res = IPACM_SUCCESS; - - IPACMDBG_H("Get %d rule handles with IP type %d\n", rule_hdl.num_rule, iptype); - for(i=0; i<rule_hdl.num_rule; i++) - { - if(m_routing.DeleteRoutingHdl(rule_hdl.rule_hdl[i], iptype) == false) - { - IPACMERR("Failed to delete routing rule hdl %d.\n", rule_hdl.rule_hdl[i]); - res = IPACM_FAILURE; - } - IPACMDBG_H("Deleted routing rule handle %d\n",rule_hdl.rule_hdl[i]); - } - return res; -} - void IPACM_Lan::post_del_self_evt() { ipacm_cmd_q_data evt; @@ -4561,13 +3141,6 @@ int IPACM_Lan::handle_lan_client_reset_rt(ipa_ip_type iptype) } } /* end of for loop */ - /* Pass info to LAN2LAN module */ - res = post_lan2lan_client_disconnect_msg(iptype); - if (res != IPACM_SUCCESS) - { - IPACMERR("Failed to posting delete old iptype(%d) address.\n", iptype); - return res; - } /* Reset ip-address */ for (i = 0; i < num_eth_client; i++) { @@ -4583,68 +3156,6 @@ int IPACM_Lan::handle_lan_client_reset_rt(ipa_ip_type iptype) return res; } -/*handle lan2lan internal mesg posting*/ -int IPACM_Lan::post_lan2lan_client_disconnect_msg(ipa_ip_type iptype) -{ - int i, j; - ipacm_cmd_q_data evt_data; - ipacm_event_lan_client* lan_client; - - for (i = 0; i < num_eth_client; i++) - { - if((get_client_memptr(eth_client, i)->ipv4_set == true) - && (iptype == IPA_IP_v4)) - { - lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client)); - if(lan_client == NULL) - { - IPACMERR("Failed to allocate memory.\n"); - return IPACM_FAILURE; - } - memset(lan_client, 0, sizeof(ipacm_event_lan_client)); - lan_client->iptype = IPA_IP_v4; - lan_client->ipv4_addr = get_client_memptr(eth_client, i)->v4_addr; - lan_client->p_iface = this; - - memset(&evt_data, 0, sizeof(ipacm_cmd_q_data)); - evt_data.evt_data = (void*)lan_client; - evt_data.event = IPA_LAN_CLIENT_DISCONNECT; - - IPACMDBG_H("Posting event IPA_LAN_CLIENT_DISCONNECT\n"); - IPACM_EvtDispatcher::PostEvt(&evt_data); - } - - if((get_client_memptr(eth_client, i)->ipv6_set > 0) - && (iptype == IPA_IP_v6)) - { - for (j = 0; j < get_client_memptr(eth_client, i)->ipv6_set; j++) - { - lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client)); - if(lan_client == NULL) - { - IPACMERR("Failed to allocate memory.\n"); - return IPACM_FAILURE; - } - memset(lan_client, 0, sizeof(ipacm_event_lan_client)); - lan_client->iptype = IPA_IP_v6; - lan_client->ipv6_addr[0] = get_client_memptr(eth_client, i)->v6_addr[j][0]; - lan_client->ipv6_addr[1] = get_client_memptr(eth_client, i)->v6_addr[j][1]; - lan_client->ipv6_addr[2] = get_client_memptr(eth_client, i)->v6_addr[j][2]; - lan_client->ipv6_addr[3] = get_client_memptr(eth_client, i)->v6_addr[j][3]; - lan_client->p_iface = this; - - memset(&evt_data, 0, sizeof(ipacm_cmd_q_data)); - evt_data.evt_data = (void*)lan_client; - evt_data.event = IPA_LAN_CLIENT_DISCONNECT; - - IPACMDBG_H("Posting event IPA_LAN_CLIENT_DISCONNECT\n"); - IPACM_EvtDispatcher::PostEvt(&evt_data); - } - } - } /* end of for loop */ - return IPACM_SUCCESS; -} - int IPACM_Lan::install_ipv4_icmp_flt_rule() { int len; @@ -4677,10 +3188,12 @@ int IPACM_Lan::install_ipv4_icmp_flt_rule() 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)); - flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); - flt_rule_entry.rule.attrib.attrib_mask = IPA_FLT_PROTOCOL; + flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL; flt_rule_entry.rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP; memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); @@ -4701,110 +3214,62 @@ int IPACM_Lan::install_ipv4_icmp_flt_rule() return IPACM_SUCCESS; } -void IPACM_Lan::install_tcp_ctl_flt_rule(ipa_ip_type iptype) +int IPACM_Lan::install_ipv6_icmp_flt_rule() { - if (rx_prop == NULL) - { - IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); - return; - } - - int len, i; - struct ipa_flt_rule_add flt_rule; - ipa_ioc_add_flt_rule* pFilteringTable; - len = sizeof(struct ipa_ioc_add_flt_rule) + NUM_TCP_CTL_FLT_RULE * sizeof(struct ipa_flt_rule_add); + int len; + struct ipa_ioc_add_flt_rule* flt_rule; + struct ipa_flt_rule_add flt_rule_entry; - pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); - if (pFilteringTable == NULL) + if(rx_prop != NULL) { - IPACMERR("Error allocate flt table memory...\n"); - return; - } - memset(pFilteringTable, 0, len); + len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); - pFilteringTable->commit = 1; - pFilteringTable->ip = iptype; - pFilteringTable->ep = rx_prop->rx[0].src_pipe; - pFilteringTable->global = false; - pFilteringTable->num_rules = NUM_TCP_CTL_FLT_RULE; + flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len); + if (!flt_rule) + { + IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); + return IPACM_FAILURE; + } - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); + flt_rule->commit = 1; + flt_rule->ep = rx_prop->rx[0].src_pipe; + flt_rule->global = false; + flt_rule->ip = IPA_IP_v6; + flt_rule->num_rules = 1; - flt_rule.at_rear = true; - flt_rule.flt_rule_hdl = -1; - flt_rule.status = -1; + memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); - flt_rule.rule.retain_hdr = 1; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; + flt_rule_entry.rule.retain_hdr = 1; + flt_rule_entry.rule.to_uc = 0; + flt_rule_entry.rule.eq_attrib_type = 0; + 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.rule.hashable = IPA_RULE_NON_HASHABLE; + flt_rule_entry.rule.hashable = false; #endif - flt_rule.rule.eq_attrib_type = 1; - - flt_rule.rule.eq_attrib.rule_eq_bitmap = 0; - - if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA) - { - flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<14); - flt_rule.rule.eq_attrib.metadata_meq32_present = 1; - flt_rule.rule.eq_attrib.metadata_meq32.offset = 0; - flt_rule.rule.eq_attrib.metadata_meq32.value = rx_prop->rx[0].attrib.meta_data; - flt_rule.rule.eq_attrib.metadata_meq32.mask = rx_prop->rx[0].attrib.meta_data_mask; - } - - flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<1); - flt_rule.rule.eq_attrib.protocol_eq_present = 1; - flt_rule.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP; - - flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<8); - flt_rule.rule.eq_attrib.num_ihl_offset_meq_32 = 1; - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12; - - /* add TCP FIN rule*/ - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_FIN_SHIFT); - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_FIN_SHIFT); - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_add)); - - /* add TCP SYN rule*/ - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_SYN_SHIFT); - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_SYN_SHIFT); - memcpy(&(pFilteringTable->rules[1]), &flt_rule, sizeof(struct ipa_flt_rule_add)); - - /* add TCP RST rule*/ - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_RST_SHIFT); - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_RST_SHIFT); - memcpy(&(pFilteringTable->rules[2]), &flt_rule, sizeof(struct ipa_flt_rule_add)); + 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_NEXT_HDR; + flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6; + memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); - if (false == m_filtering.AddFilteringRule(pFilteringTable)) - { - IPACMERR("Error adding tcp control flt rule\n"); - goto fail; - } - else - { - if(iptype == IPA_IP_v4) + if (m_filtering.AddFilteringRule(flt_rule) == false) { - for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++) - { - tcp_ctl_flt_rule_hdl_v4[i] = pFilteringTable->rules[i].flt_rule_hdl; - } - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, NUM_TCP_CTL_FLT_RULE); + IPACMERR("Error Adding Filtering rule, aborting...\n"); + free(flt_rule); + return IPACM_FAILURE; } else { - for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++) - { - tcp_ctl_flt_rule_hdl_v6[i] = pFilteringTable->rules[i].flt_rule_hdl; - } - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, NUM_TCP_CTL_FLT_RULE); + IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); + ipv6_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl; + IPACMDBG_H("IPv6 icmp filter rule HDL:0x%x\n", ipv6_icmp_flt_rule_hdl[0]); + free(flt_rule); } } - -fail: - free(pFilteringTable); - return; + return IPACM_SUCCESS; } int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype) @@ -4847,6 +3312,9 @@ int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype) flt_rule.flt_rule_hdl = -1; flt_rule.status = -1; flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; +#ifdef FEATURE_IPA_V3 + flt_rule.rule.hashable = true; +#endif memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); @@ -5016,10 +3484,9 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; #ifdef FEATURE_IPA_V3 - flt_rule_entry.rule.hashable = IPA_RULE_NON_HASHABLE; + flt_rule_entry.rule.hashable = false; #endif memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); - flt_rule_entry.rule.attrib.attrib_mask = flt_rule_entry.rule.attrib.attrib_mask & ~((uint32_t)IPA_FLT_META_DATA); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = prefix[0]; flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = prefix[1]; @@ -5059,65 +3526,6 @@ void IPACM_Lan::delete_ipv6_prefix_flt_rule() return; } -int IPACM_Lan::install_ipv6_icmp_flt_rule() -{ - - int len; - struct ipa_ioc_add_flt_rule* flt_rule; - struct ipa_flt_rule_add flt_rule_entry; - - if(rx_prop != NULL) - { - len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); - - flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len); - if (!flt_rule) - { - IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); - return IPACM_FAILURE; - } - - flt_rule->commit = 1; - flt_rule->ep = rx_prop->rx[0].src_pipe; - flt_rule->global = false; - flt_rule->ip = IPA_IP_v6; - flt_rule->num_rules = 1; - - memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); - - flt_rule_entry.rule.retain_hdr = 1; - flt_rule_entry.rule.to_uc = 0; - flt_rule_entry.rule.eq_attrib_type = 0; - 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.rule.hashable = IPA_RULE_NON_HASHABLE; -#endif - memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); - flt_rule_entry.rule.attrib.attrib_mask = flt_rule_entry.rule.attrib.attrib_mask & ~((uint32_t)IPA_FLT_META_DATA); - flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR; - flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6; - memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); - - if (m_filtering.AddFilteringRule(flt_rule) == false) - { - IPACMERR("Error Adding Filtering rule, aborting...\n"); - free(flt_rule); - return IPACM_FAILURE; - } - else - { - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); - ipv6_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl; - IPACMDBG_H("IPv6 icmp filter rule HDL:0x%x\n", ipv6_icmp_flt_rule_hdl[0]); - free(flt_rule); - } - } - return IPACM_SUCCESS; -} - int IPACM_Lan::handle_addr_evt_odu_bridge(ipacm_event_data_addr* data) { int fd, res = IPACM_SUCCESS; @@ -5151,1062 +3559,7 @@ int IPACM_Lan::handle_addr_evt_odu_bridge(ipacm_event_data_addr* data) return res; } -int IPACM_Lan::eth_bridge_handle_dummy_wlan_client_flt_rule(ipa_ip_type iptype) -{ - if(rx_prop == NULL) - { - IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy wlan client specific filtering rule.\n", dev_name); - return 0; - } - - int i, len, res = IPACM_SUCCESS; - struct ipa_flt_rule_add flt_rule; - ipa_ioc_add_flt_rule* pFilteringTable; - - len = sizeof(struct ipa_ioc_add_flt_rule) + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(struct ipa_flt_rule_add); - - pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); - if (pFilteringTable == NULL) - { - IPACMERR("Error allocate flt table memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - pFilteringTable->commit = 1; - pFilteringTable->ep = rx_prop->rx[0].src_pipe; - pFilteringTable->global = false; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; - - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); - - flt_rule.rule.retain_hdr = 0; - flt_rule.at_rear = true; - flt_rule.flt_rule_hdl = -1; - flt_rule.status = -1; - flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, - sizeof(flt_rule.rule.attrib)); - - if(iptype == IPA_IP_v4) - { - flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; - flt_rule.rule.attrib.u.v4.src_addr = ~0; - flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; - flt_rule.rule.attrib.u.v4.dst_addr = ~0; - - for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) - { - memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); - } - - if (false == m_filtering.AddFilteringRule(pFilteringTable)) - { - IPACMERR("Error adding dummy lan2lan v4 flt rule\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT); - /* copy filter rule hdls */ - for (int i = 0; i < IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) - { - if (pFilteringTable->rules[i].status == 0) - { - wlan_client_flt_rule_hdl_v4[i].rule_hdl = pFilteringTable->rules[i].flt_rule_hdl; - wlan_client_flt_rule_hdl_v4[i].valid = true; - IPACMDBG_H("Wlan client v4 flt rule %d hdl:0x%x\n", i, wlan_client_flt_rule_hdl_v4[i].rule_hdl); - } - else - { - IPACMERR("Failed adding wlan client v4 flt rule %d\n", i); - res = IPACM_FAILURE; - goto fail; - } - } - } - } - else if(iptype == IPA_IP_v6) - { - flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0; - flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0; - flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0; - flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[0] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[1] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[2] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[3] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0; - - for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) - { - memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); - } - - if (false == m_filtering.AddFilteringRule(pFilteringTable)) - { - IPACMERR("Error adding dummy lan2lan v6 flt rule\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT); - /* copy filter rule hdls */ - for (int i = 0; i < IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) - { - if (pFilteringTable->rules[i].status == 0) - { - wlan_client_flt_rule_hdl_v6[i].rule_hdl = pFilteringTable->rules[i].flt_rule_hdl; - wlan_client_flt_rule_hdl_v6[i].valid = true; - IPACMDBG_H("Wlan client v6 flt rule %d hdl:0x%x\n", i, wlan_client_flt_rule_hdl_v6[i].rule_hdl); - } - else - { - IPACMERR("Failed adding wlan client v6 flt rule %d\n", i); - res = IPACM_FAILURE; - goto fail; - } - } - } - } - else - { - IPACMERR("IP type is not expected.\n"); - goto fail; - } - -fail: - free(pFilteringTable); - return res; -} - -int IPACM_Lan::eth_bridge_handle_dummy_lan_client_flt_rule(ipa_ip_type iptype) -{ - if(rx_prop == NULL) - { - IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy lan client specific filtering rule.\n", dev_name); - return 0; - } - - int i, len, res = IPACM_SUCCESS, num_dummy_rules; - struct ipa_flt_rule_add flt_rule; - ipa_ioc_add_flt_rule* pFilteringTable; - - if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) - { - num_dummy_rules = IPA_LAN_TO_LAN_MAX_CPE_CLIENT; - } - if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) - { - num_dummy_rules = IPA_LAN_TO_LAN_MAX_USB_CLIENT; - } - - len = sizeof(struct ipa_ioc_add_flt_rule) + num_dummy_rules * sizeof(struct ipa_flt_rule_add); - - pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); - if (pFilteringTable == NULL) - { - IPACMERR("Error allocate flt table memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - pFilteringTable->commit = 1; - pFilteringTable->ep = rx_prop->rx[0].src_pipe; - pFilteringTable->global = false; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = num_dummy_rules; - - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); - - flt_rule.rule.retain_hdr = 0; - flt_rule.at_rear = true; - flt_rule.flt_rule_hdl = -1; - flt_rule.status = -1; - flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, - sizeof(flt_rule.rule.attrib)); - - if(iptype == IPA_IP_v4) - { - flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; - flt_rule.rule.attrib.u.v4.src_addr = ~0; - flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; - flt_rule.rule.attrib.u.v4.dst_addr = ~0; - - for(i=0; i < num_dummy_rules; i++) - { - memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); - } - - if (false == m_filtering.AddFilteringRule(pFilteringTable)) - { - IPACMERR("Error adding dummy lan2lan v4 flt rule\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, num_dummy_rules); - /* copy filter rule hdls */ - for (int i = 0; i < num_dummy_rules; i++) - { - if (pFilteringTable->rules[i].status == 0) - { - lan_client_flt_rule_hdl_v4[i].rule_hdl = pFilteringTable->rules[i].flt_rule_hdl; - lan_client_flt_rule_hdl_v4[i].valid = true; - IPACMDBG_H("Lan client v4 flt rule %d hdl:0x%x\n", i, lan_client_flt_rule_hdl_v4[i].rule_hdl); - } - else - { - IPACMERR("Failed adding lan client v4 flt rule %d\n", i); - res = IPACM_FAILURE; - goto fail; - } - } - } - } - else if(iptype == IPA_IP_v6) - { - flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0; - flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0; - flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0; - flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[0] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[1] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[2] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[3] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0; - - for(i=0; i<num_dummy_rules; i++) - { - memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); - } - - if (false == m_filtering.AddFilteringRule(pFilteringTable)) - { - IPACMERR("Error adding dummy lan2lan v6 flt rule\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, num_dummy_rules); - /* copy filter rule hdls */ - for (int i = 0; i < num_dummy_rules; i++) - { - if (pFilteringTable->rules[i].status == 0) - { - lan_client_flt_rule_hdl_v6[i].rule_hdl = pFilteringTable->rules[i].flt_rule_hdl; - lan_client_flt_rule_hdl_v6[i].valid = true; - IPACMDBG_H("Lan client v6 flt rule %d hdl:0x%x\n", i, lan_client_flt_rule_hdl_v6[i].rule_hdl); - } - else - { - IPACMERR("Failed adding lan client v6 flt rule %d\n", i); - res = IPACM_FAILURE; - goto fail; - } - } - } - } - else - { - IPACMERR("IP type is not expected.\n"); - goto fail; - } - -fail: - free(pFilteringTable); - return res; -} - -int IPACM_Lan::eth_bridge_post_lan_client_event(uint8_t* mac_addr, ipa_cm_event_id evt) -{ - if(mac_addr == NULL) - { - IPACMERR("Event mac is empty.\n"); - return IPACM_FAILURE; - } - - ipacm_cmd_q_data evt_data; - memset(&evt_data, 0, sizeof(evt_data)); - - ipacm_event_data_mac* mac; - mac = (ipacm_event_data_mac*)malloc(sizeof(ipacm_event_data_mac)); - if(mac == NULL) - { - IPACMERR("Unable to allocate memory.\n"); - return IPACM_FAILURE; - } - memset(mac, 0, sizeof(ipacm_event_data_mac)); - memcpy(mac->mac_addr, mac_addr, 6 * sizeof(uint8_t)); - mac->if_index = ipa_if_num; - - evt_data.event = evt; - evt_data.evt_data = (void*)mac; - IPACMDBG_H("Posting event: %d if_index: %d \n", evt, mac->if_index); - IPACM_EvtDispatcher::PostEvt(&evt_data); - return IPACM_SUCCESS; -} - -int IPACM_Lan::eth_bridge_add_wlan_client_flt_rule(uint8_t* mac, ipa_ip_type iptype) -{ - int i, len, res = IPACM_SUCCESS, client_position; - struct ipa_flt_rule_mdfy flt_rule; - struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL; - bool client_is_found = false; - - if (rx_prop == NULL) - { - IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); - return IPACM_FAILURE; - } - if(mac == NULL) - { - IPACMERR("MAC address is empty.\n"); - return IPACM_FAILURE; - } - if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == false) - { - IPACMDBG_H("USB to WLAN hdr proc ctx has not been set, don't add client specific flt rule.\n"); - return IPACM_FAILURE; - } - - IPACMDBG_H("Received WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - for(i=0; i<wlan_client_flt_info_count; i++) - { - if(memcmp(eth_bridge_wlan_client_flt_info[i].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[i].mac)) == 0) - { - client_is_found = true; - client_position = i; - if( (iptype == IPA_IP_v4 && eth_bridge_wlan_client_flt_info[i].flt_rule_set_v4 == true) - || (iptype == IPA_IP_v6 && eth_bridge_wlan_client_flt_info[i].flt_rule_set_v6 == true)) - { - IPACMDBG_H("Flt rule for iptype %d has been set.\n", iptype); - return IPACM_SUCCESS; - } - break; - } - } - - if(client_is_found == false && wlan_client_flt_info_count == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - { - IPACMDBG_H("The wlan client flt table is already full.\n"); - return IPACM_FAILURE; - } - - len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy); - pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); - if (!pFilteringTable) - { - IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - /* add mac based rule*/ - pFilteringTable->commit = 1; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = 1; - - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); - flt_rule.status = -1; - - flt_rule.rule.retain_hdr = 0; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_ROUTING; - flt_rule.rule.eq_attrib_type = 0; - - /* point to USB-WLAN routing table */ - if(iptype == IPA_IP_v4) - { - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4.hdl; - IPACMDBG_H("LAN->WLAN filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4.name); - } - else - { - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6.hdl; - IPACMDBG_H("LAN->WLAN filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6.name); - } - - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); - if(IPACM_Lan::lan_hdr_type == IPA_HDR_L2_ETHERNET_II) - { - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; - } - else if(IPACM_Lan::lan_hdr_type == IPA_HDR_L2_802_3) - { - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; - } - else - { - IPACMERR("USB hdr type is not expected.\n"); - res = IPACM_FAILURE; - goto fail; - } - memcpy(flt_rule.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule.rule.attrib.dst_mac_addr)); - memset(flt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule.rule.attrib.dst_mac_addr_mask)); - - if(iptype == IPA_IP_v4) - { - for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) - { - if(wlan_client_flt_rule_hdl_v4[i].valid == true) - { - flt_rule.rule_hdl = wlan_client_flt_rule_hdl_v4[i].rule_hdl; - wlan_client_flt_rule_hdl_v4[i].valid = false; - break; - } - } - if(i == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - { - IPACMDBG_H("Cannot find a valid flt rule hdl.\n"); - res = IPACM_FAILURE; - goto fail; - } - } - else - { - for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) - { - if(wlan_client_flt_rule_hdl_v6[i].valid == true) - { - flt_rule.rule_hdl = wlan_client_flt_rule_hdl_v6[i].rule_hdl; - wlan_client_flt_rule_hdl_v6[i].valid = false; - break; - } - } - if(i == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - { - IPACMDBG_H("Cannot find a valid flt rule hdl.\n"); - res = IPACM_FAILURE; - goto fail; - } - } - - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) - { - IPACMERR("Failed to add wlan client filtering rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - - if(client_is_found == false) - { - client_position = wlan_client_flt_info_count; - wlan_client_flt_info_count++; - } - - memcpy(eth_bridge_wlan_client_flt_info[client_position].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[client_position].mac)); - if(iptype == IPA_IP_v4) - { - eth_bridge_wlan_client_flt_info[client_position].flt_rule_set_v4 = true; - eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v4 = wlan_client_flt_rule_hdl_v4[i].rule_hdl; - } - else - { - eth_bridge_wlan_client_flt_info[client_position].flt_rule_set_v6 = true; - eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v6 = wlan_client_flt_rule_hdl_v6[i].rule_hdl; - } - -fail: - free(pFilteringTable); - - return res; -} - -int IPACM_Lan::eth_bridge_del_wlan_client_flt_rule(uint8_t* mac) -{ - if(mac == NULL) - { - IPACMERR("Client MAC address is empty.\n"); - return IPACM_FAILURE; - } - - IPACMDBG_H("Received WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - int i, j, res = IPACM_SUCCESS; - for(i=0; i<wlan_client_flt_info_count; i++) - { - if(memcmp(eth_bridge_wlan_client_flt_info[i].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[i].mac)) == 0) - { - break; - } - } - - if(i == wlan_client_flt_info_count) - { - IPACMERR("Do not find the wlan client.\n"); - return IPACM_FAILURE; - } - - if(eth_bridge_wlan_client_flt_info[i].flt_rule_set_v4 == true) - { - if(reset_to_dummy_flt_rule(IPA_IP_v4, eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v4) == IPACM_SUCCESS) - { - for(j=0; j<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; j++) - { - if(wlan_client_flt_rule_hdl_v4[j].rule_hdl == eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v4) - { - wlan_client_flt_rule_hdl_v4[j].valid = true; - break; - } - } - if(j == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - { - IPACMERR("Not finding the rule handle in handle pool.\n"); - return IPACM_FAILURE; - } - } - else - { - IPACMERR("Failed to delete the wlan client specific flt rule.\n"); - return IPACM_FAILURE; - } - } - if(eth_bridge_wlan_client_flt_info[i].flt_rule_set_v6 == true) - { - if(reset_to_dummy_flt_rule(IPA_IP_v6, eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v6) == IPACM_SUCCESS) - { - for(j=0; j<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; j++) - { - if(wlan_client_flt_rule_hdl_v6[j].rule_hdl == eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v6) - { - wlan_client_flt_rule_hdl_v6[j].valid = true; - break; - } - } - if(j == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - { - IPACMERR("Not finding the rule handle in handle pool.\n"); - return IPACM_FAILURE; - } - } - else - { - IPACMERR("Failed to delete the wlan client specific flt rule.\n"); - return IPACM_FAILURE; - } - } - - for(j=i+1; j<wlan_client_flt_info_count; j++) - { - memcpy(&(eth_bridge_wlan_client_flt_info[j-1]), &(eth_bridge_wlan_client_flt_info[j]), sizeof(eth_bridge_client_flt_info)); - } - memset(&(eth_bridge_wlan_client_flt_info[wlan_client_flt_info_count-1]), 0, sizeof(eth_bridge_client_flt_info)); - wlan_client_flt_info_count--; - - return res; -} - -int IPACM_Lan::eth_bridge_add_lan_client_flt_rule(uint8_t* mac, ipa_ip_type iptype) -{ - int i, len, res = IPACM_SUCCESS, client_position; - struct ipa_flt_rule_mdfy flt_rule; - struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL; - bool client_is_found = false; - - if (rx_prop == NULL) - { - IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); - return IPACM_FAILURE; - } - if (mac == NULL) - { - IPACMERR("MAC address is empty.\n"); - return IPACM_FAILURE; - } - if (IPACM_Lan::usb_to_cpe_hdr_proc_ctx.valid == false && IPACM_Lan::cpe_to_usb_hdr_proc_ctx.valid == false) - { - IPACMDBG_H("USB to CPE and CPE to USB hdr proc ctx have not been set, don't add client specific flt rule.\n"); - return IPACM_FAILURE; - } - - IPACMDBG_H("Received LAN client MAC 0x%02x%02x%02x%02x%02x%02x. if_cat: %d \n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], - IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat); - - for (i=0; i<lan_client_flt_info_count; i++) - { - if (memcmp(eth_bridge_lan_client_flt_info[i].mac, mac, sizeof(eth_bridge_lan_client_flt_info[i].mac)) == 0) - { - client_is_found = true; - client_position = i; - if ((iptype == IPA_IP_v4 && eth_bridge_lan_client_flt_info[i].flt_rule_set_v4 == true) - || (iptype == IPA_IP_v6 && eth_bridge_lan_client_flt_info[i].flt_rule_set_v6 == true)) - { - IPACMDBG_H("Flt rule for iptype %d has been set.\n", iptype); - return IPACM_SUCCESS; - } - break; - } - } - - if (client_is_found == false && lan_client_flt_info_count == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - { - IPACMDBG_H("The lan client flt table is already full.\n"); - return IPACM_FAILURE; - } - - len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy); - pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); - if (!pFilteringTable) - { - IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - /* add mac based rule*/ - pFilteringTable->commit = 1; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = 1; - - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); - flt_rule.status = -1; - - flt_rule.rule.retain_hdr = 0; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_ROUTING; - flt_rule.rule.eq_attrib_type = 0; - - /* point to LAN-LAN routing table */ - if (iptype == IPA_IP_v4) - { - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_lan_v4)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_lan_v4.hdl; - IPACMDBG_H("LAN->LAN filter rule use table: %s\n", IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_lan_v4.name); - } - else - { - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_lan_v6)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_lan_v6.hdl; - IPACMDBG_H("LAN->LAN filter rule use table: %s\n", IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_lan_v6.name); - } - - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); - - if (IPACM_Lan::lan_hdr_type == IPA_HDR_L2_ETHERNET_II) - { - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; - } - else if (IPACM_Lan::lan_hdr_type == IPA_HDR_L2_802_3) - { - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; - } - else - { - IPACMERR("LAN hdr type is not expected.\n"); - res = IPACM_FAILURE; - goto fail; - } - - memcpy(flt_rule.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule.rule.attrib.dst_mac_addr)); - memset(flt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule.rule.attrib.dst_mac_addr_mask)); - - if (iptype == IPA_IP_v4) - { - for (i=0; i<IPA_LAN_TO_LAN_MAX_LAN_CLIENT; i++) - { - if (lan_client_flt_rule_hdl_v4[i].valid == true) - { - flt_rule.rule_hdl = lan_client_flt_rule_hdl_v4[i].rule_hdl; - lan_client_flt_rule_hdl_v4[i].valid = false; - break; - } - } - if (i == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - { - IPACMDBG_H("Cannot find a valid flt rule hdl.\n"); - res = IPACM_FAILURE; - goto fail; - } - } - else - { - for (i=0; i<IPA_LAN_TO_LAN_MAX_LAN_CLIENT; i++) - { - if (lan_client_flt_rule_hdl_v6[i].valid == true) - { - flt_rule.rule_hdl = lan_client_flt_rule_hdl_v6[i].rule_hdl; - lan_client_flt_rule_hdl_v6[i].valid = false; - break; - } - } - if (i == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - { - IPACMDBG_H("Cannot find a valid flt rule hdl.\n"); - res = IPACM_FAILURE; - goto fail; - } - } - - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) - { - IPACMERR("Failed to add wlan client filtering rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - - if (client_is_found == false) - { - client_position = lan_client_flt_info_count; - lan_client_flt_info_count++; - } - - memcpy(eth_bridge_lan_client_flt_info[client_position].mac, mac, sizeof(eth_bridge_lan_client_flt_info[client_position].mac)); - - if (iptype == IPA_IP_v4) - { - eth_bridge_lan_client_flt_info[client_position].flt_rule_set_v4 = true; - eth_bridge_lan_client_flt_info[client_position].flt_rule_hdl_v4 = lan_client_flt_rule_hdl_v4[i].rule_hdl; - } - else - { - eth_bridge_lan_client_flt_info[client_position].flt_rule_set_v6 = true; - eth_bridge_lan_client_flt_info[client_position].flt_rule_hdl_v6 = lan_client_flt_rule_hdl_v6[i].rule_hdl; - } - -fail: - free(pFilteringTable); - - return res; -} - -int IPACM_Lan::eth_bridge_del_lan_client_flt_rule(uint8_t* mac) -{ - if (mac == NULL) - { - IPACMERR("Client MAC address is empty.\n"); - return IPACM_FAILURE; - } - - IPACMDBG_H("Received LAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - int i, j, res = IPACM_SUCCESS; - for (i=0; i<lan_client_flt_info_count; i++) - { - if (memcmp(eth_bridge_lan_client_flt_info[i].mac, mac, sizeof(eth_bridge_lan_client_flt_info[i].mac)) == 0) - { - break; - } - } - - if (i == lan_client_flt_info_count) - { - IPACMERR("Do not find the lan client.\n"); - return IPACM_FAILURE; - } - - if (eth_bridge_lan_client_flt_info[i].flt_rule_set_v4 == true) - { - if (reset_to_dummy_flt_rule(IPA_IP_v4, eth_bridge_lan_client_flt_info[i].flt_rule_hdl_v4) == IPACM_SUCCESS) - { - for (j=0; j<IPA_LAN_TO_LAN_MAX_LAN_CLIENT; j++) - { - if (lan_client_flt_rule_hdl_v4[j].rule_hdl == eth_bridge_lan_client_flt_info[i].flt_rule_hdl_v4) - { - lan_client_flt_rule_hdl_v4[j].valid = true; - break; - } - } - if (j == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - { - IPACMERR("Not finding the rule handle in handle pool.\n"); - return IPACM_FAILURE; - } - } - else - { - IPACMERR("Failed to delete the lan client specific flt rule.\n"); - return IPACM_FAILURE; - } - } - if (eth_bridge_lan_client_flt_info[i].flt_rule_set_v6 == true) - { - if (reset_to_dummy_flt_rule(IPA_IP_v6, eth_bridge_lan_client_flt_info[i].flt_rule_hdl_v6) == IPACM_SUCCESS) - { - for (j=0; j<IPA_LAN_TO_LAN_MAX_LAN_CLIENT; j++) - { - if (lan_client_flt_rule_hdl_v6[j].rule_hdl == eth_bridge_lan_client_flt_info[i].flt_rule_hdl_v6) - { - lan_client_flt_rule_hdl_v6[j].valid = true; - break; - } - } - if (j == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - { - IPACMERR("Not finding the rule handle in handle pool.\n"); - return IPACM_FAILURE; - } - } - else - { - IPACMERR("Failed to delete the lan client specific flt rule.\n"); - return IPACM_FAILURE; - } - } - - for (j=i+1; j<lan_client_flt_info_count; j++) - { - memcpy(&(eth_bridge_lan_client_flt_info[j-1]), &(eth_bridge_lan_client_flt_info[j]), sizeof(eth_bridge_client_flt_info)); - } - memset(&(eth_bridge_lan_client_flt_info[lan_client_flt_info_count-1]), 0, sizeof(eth_bridge_client_flt_info)); - lan_client_flt_info_count--; - - return res; -} - -int IPACM_Lan::add_hdr_proc_ctx() -{ - int len, res = IPACM_SUCCESS; - struct ipa_ioc_add_hdr_proc_ctx* pHeaderProcTable = NULL; - - len = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_add); - pHeaderProcTable = (ipa_ioc_add_hdr_proc_ctx*)malloc(len); - if(pHeaderProcTable == NULL) - { - IPACMERR("Cannot allocate header processing table.\n"); - return IPACM_FAILURE; - } - - if(IPACM_Lan::wlan_hdr_type != IPA_HDR_L2_NONE) - { - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF) - { - if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == false) - { - memset(pHeaderProcTable, 0, len); - pHeaderProcTable->commit = 1; - pHeaderProcTable->num_proc_ctxs = 1; - pHeaderProcTable->proc_ctx[0].type = get_hdr_proc_type(IPACM_Lan::wlan_hdr_type, IPACM_Lan::wlan_hdr_type); - pHeaderProcTable->proc_ctx[0].hdr_hdl = IPACM_Lan::wlan_hdr_template_hdl; - if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) - { - IPACMERR("Adding WLAN to WLAN hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); - res = IPACM_FAILURE; - } - else - { - IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.proc_ctx_hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; - IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid = true; - IPACMDBG_H("WLAN to WLAN hdr proc ctx is added successfully. \n"); - } - } - } - - if(IPACM_Lan::lan_hdr_type != IPA_HDR_L2_NONE) - { - if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == false) - { - memset(pHeaderProcTable, 0, len); - pHeaderProcTable->commit = 1; - pHeaderProcTable->num_proc_ctxs = 1; - pHeaderProcTable->proc_ctx[0].type = get_hdr_proc_type(IPACM_Lan::lan_hdr_type, IPACM_Lan::wlan_hdr_type); - pHeaderProcTable->proc_ctx[0].hdr_hdl = IPACM_Lan::wlan_hdr_template_hdl; - if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) - { - IPACMERR("Adding LAN to WLAN hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Lan::lan_to_wlan_hdr_proc_ctx.proc_ctx_hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; - IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid = true; - IPACMDBG_H("LAN to WLAN hdr proc ctx is added successfully. \n"); - } - - ipacm_cmd_q_data evt_data; - memset(&evt_data, 0, sizeof(ipacm_cmd_q_data)); - - ipacm_event_data_if_cat* cat; - cat = (ipacm_event_data_if_cat*)malloc(sizeof(ipacm_event_data_if_cat)); - if(cat == NULL) - { - IPACMERR("Unable to allocate memory.\n"); - return IPACM_FAILURE; - } - memset(cat, 0, sizeof(ipacm_event_data_if_cat)); - cat->if_cat = IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat; - - evt_data.evt_data = cat; - evt_data.event = IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT; - IPACMDBG_H("Posting event IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT\n"); - IPACM_EvtDispatcher::PostEvt(&evt_data); - } - - if(IPACM_Lan::is_usb_up == true && IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == false) - { - memset(pHeaderProcTable, 0, len); - pHeaderProcTable->commit = 1; - pHeaderProcTable->num_proc_ctxs = 1; - pHeaderProcTable->proc_ctx[0].type = get_hdr_proc_type(IPACM_Lan::wlan_hdr_type, IPACM_Lan::lan_hdr_type); - pHeaderProcTable->proc_ctx[0].hdr_hdl = IPACM_Lan::usb_hdr_template_hdl; - if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) - { - IPACMERR("Adding WLAN to USB hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Lan::wlan_to_usb_hdr_proc_ctx.proc_ctx_hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; - IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid = true; - IPACMDBG_H("WLAN to USB hdr proc ctx is added successfully. \n"); - } - } - - if(IPACM_Lan::is_cpe_up == true && IPACM_Lan::wlan_to_cpe_hdr_proc_ctx.valid == false) - { - memset(pHeaderProcTable, 0, len); - pHeaderProcTable->commit = 1; - pHeaderProcTable->num_proc_ctxs = 1; - pHeaderProcTable->proc_ctx[0].type = get_hdr_proc_type(IPACM_Lan::wlan_hdr_type, IPACM_Lan::lan_hdr_type); - pHeaderProcTable->proc_ctx[0].hdr_hdl = IPACM_Lan::cpe_hdr_template_hdl; - if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) - { - IPACMERR("Adding WLAN to CPE hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Lan::wlan_to_cpe_hdr_proc_ctx.proc_ctx_hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; - IPACM_Lan::wlan_to_cpe_hdr_proc_ctx.valid = true; - IPACMDBG_H("WLAN to CPE hdr proc ctx is added successfully. \n"); - - } - } - } - } - - if(IPACM_Lan::lan_hdr_type != IPA_HDR_L2_NONE) - { - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF || - (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)) - { - if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false) - { - IPACMDBG_H("ODU is in bridge mode, do not set CPE to USB and USB to CPE hdr proc ctx.\n"); - return res; - } - if(IPACM_Lan::is_cpe_up == true && IPACM_Lan::is_usb_up == true && - IPACM_Lan::cpe_to_usb_hdr_proc_ctx.valid == false && IPACM_Lan::usb_to_cpe_hdr_proc_ctx.valid == false) - { - memset(pHeaderProcTable, 0, len); - pHeaderProcTable->commit = 1; - pHeaderProcTable->num_proc_ctxs = 1; - pHeaderProcTable->proc_ctx[0].type = get_hdr_proc_type(IPACM_Lan::lan_hdr_type, IPACM_Lan::lan_hdr_type); - pHeaderProcTable->proc_ctx[0].hdr_hdl = IPACM_Lan::usb_hdr_template_hdl; - if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) - { - IPACMERR("Adding CPE to USB hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Lan::cpe_to_usb_hdr_proc_ctx.proc_ctx_hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; - IPACM_Lan::cpe_to_usb_hdr_proc_ctx.valid = true; - IPACMDBG_H("CPE to USB hdr proc ctx is added successfully. \n"); - } - - pHeaderProcTable->commit = 1; - pHeaderProcTable->num_proc_ctxs = 1; - pHeaderProcTable->proc_ctx[0].type = get_hdr_proc_type(IPACM_Lan::lan_hdr_type, IPACM_Lan::lan_hdr_type); - pHeaderProcTable->proc_ctx[0].hdr_hdl = IPACM_Lan::cpe_hdr_template_hdl; - if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) - { - IPACMERR("Adding USB to CPE hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Lan::usb_to_cpe_hdr_proc_ctx.proc_ctx_hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; - IPACM_Lan::usb_to_cpe_hdr_proc_ctx.valid = true; - IPACMDBG_H("USB to CPE hdr proc ctx is added successfully. \n"); - } - - ipacm_cmd_q_data evt_data; - memset(&evt_data, 0, sizeof(ipacm_cmd_q_data)); - - ipacm_event_data_if_cat* cat; - cat = (ipacm_event_data_if_cat*)malloc(sizeof(ipacm_event_data_if_cat)); - if(cat == NULL) - { - IPACMERR("Unable to allocate memory.\n"); - return IPACM_FAILURE; - } - memset(cat, 0, sizeof(ipacm_event_data_if_cat)); - cat->if_cat = IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat; - - evt_data.evt_data = cat; - evt_data.event = IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT; - IPACMDBG_H("Posting event IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT\n"); - IPACM_EvtDispatcher::PostEvt(&evt_data); - } - } - } - else - { - IPACMDBG_H("Not adding header processing context.\n"); - } - -fail: - free(pHeaderProcTable); - return res; -} - -ipa_hdr_proc_type IPACM_Lan::get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2) +ipa_hdr_proc_type IPACM_Lan::eth_bridge_get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2) { if(t1 == IPA_HDR_L2_ETHERNET_II) { @@ -6235,592 +3588,6 @@ ipa_hdr_proc_type IPACM_Lan::get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_ty return IPA_HDR_PROC_NONE; } -int IPACM_Lan::eth_bridge_install_cache_wlan_client_flt_rule(ipa_ip_type iptype) -{ - int i; - - IPACMDBG_H("There are %d wlan clients cached.\n",IPACM_Lan::num_wlan_client); - for(i=0; i<IPACM_Lan::num_wlan_client; i++) - { - eth_bridge_add_wlan_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, iptype); - } - return IPACM_SUCCESS; -} - -int IPACM_Lan::eth_bridge_install_cache_lan_client_flt_rule(ipa_ip_type iptype) -{ - int i; - - IPACMDBG_H("There are %d lan clients cached.\n", IPACM_Lan::num_lan_client); - for(i=0; i<IPACM_Lan::num_lan_client; i++) - { - if (IPACM_Lan::eth_bridge_lan_client[i].ipa_if_num != ipa_if_num) - { - eth_bridge_add_lan_client_flt_rule(IPACM_Lan::eth_bridge_lan_client[i].mac, iptype); - } - } - return IPACM_SUCCESS; -} - -int IPACM_Lan::eth_bridge_add_lan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src, ipa_ip_type iptype) -{ - if (tx_prop == NULL) - { - IPACMDBG_H("Tx prop is empty, not adding routing rule.\n"); - return IPACM_SUCCESS; - } - if (mac == NULL) - { - IPACMERR("Client MAC address is empty.\n"); - return IPACM_FAILURE; - } - - IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x. src_iface: %d if_cat: %d \n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], src, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat ); - - if (src == SRC_WLAN && IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF - && IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == false) - { - IPACMDBG_H("WLAN to USB hdr proc ctx has not been set, don't add USB routing rule.\n"); - return IPACM_FAILURE; - } - if (src == SRC_WLAN && IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF - && IPACM_Lan::wlan_to_cpe_hdr_proc_ctx.valid == false) - { - IPACMDBG_H("WLAN to CPE hdr proc ctx has not been set, don't add CPE routing rule.\n"); - return IPACM_FAILURE; - } - - if (src == SRC_LAN && IPACM_Lan::usb_to_cpe_hdr_proc_ctx.valid == false - && IPACM_Lan::cpe_to_usb_hdr_proc_ctx.valid == false) - { - IPACMDBG_H("hdr proc ctx between USB and CPE has not been set, don't add routing rule.\n"); - return IPACM_FAILURE; - } - - if(iptype == IPA_IP_v4) - { - if((src == SRC_LAN && lan_client_rt_from_lan_info_count_v4 == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - || (src == SRC_WLAN && lan_client_rt_from_wlan_info_count_v4 == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)) - { - IPACMDBG_H("client number has reached maximum.\n"); - return IPACM_FAILURE; - } - } - else - { - if ((src == SRC_LAN && lan_client_rt_from_lan_info_count_v6 == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - || (src == SRC_WLAN && lan_client_rt_from_wlan_info_count_v6 == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)) - { - IPACMDBG_H("client number has reached maximum.\n"); - return IPACM_FAILURE; - } - } - - int i, len, res = IPACM_SUCCESS; - struct ipa_ioc_add_rt_rule* rt_rule_table = NULL; - struct ipa_rt_rule_add rt_rule; - int position, num_rt_rule; - - if (src == SRC_LAN) - { - if (iptype == IPA_IP_v4) - { - for (i=0; i<lan_client_rt_from_lan_info_count_v4; i++) - { - if (memcmp(eth_bridge_get_client_rt_info_ptr(i, src, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, iptype)->mac)) == 0) - { - IPACMDBG_H("The client's routing rule was added before.\n"); - return IPACM_SUCCESS; - } - } - memcpy(eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_lan_info_count_v4, src, iptype)->mac, mac, - sizeof(eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_lan_info_count_v4, src, iptype)->mac)); - } - else - { - for (i=0; i<lan_client_rt_from_lan_info_count_v6; i++) - { - if (memcmp(eth_bridge_get_client_rt_info_ptr(i, src, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, iptype)->mac)) == 0) - { - IPACMDBG_H("The client's routing rule was added before.\n"); - return IPACM_SUCCESS; - } - } - memcpy(eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_lan_info_count_v6, src, iptype)->mac, mac, - sizeof(eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_lan_info_count_v6, src, iptype)->mac)); - } - } - else - { - if (iptype == IPA_IP_v4) - { - for (i=0; i<lan_client_rt_from_wlan_info_count_v4; i++) - { - if (memcmp(eth_bridge_get_client_rt_info_ptr(i, src, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, iptype)->mac)) == 0) - { - IPACMDBG_H("The client's routing rule was added before.\n"); - return IPACM_SUCCESS; - } - } - memcpy(eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_wlan_info_count_v4, src, iptype)->mac, mac, - sizeof(eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_wlan_info_count_v4, src, iptype)->mac)); - } - else - { - for (i=0; i<lan_client_rt_from_wlan_info_count_v6; i++) - { - if (memcmp(eth_bridge_get_client_rt_info_ptr(i, src, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, iptype)->mac)) == 0) - { - IPACMDBG_H("The client's routing rule was added before.\n"); - return IPACM_SUCCESS; - } - } - memcpy(eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_wlan_info_count_v6, src, iptype)->mac, mac, - sizeof(eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_wlan_info_count_v6, src, iptype)->mac)); - } - } - - if (iptype == IPA_IP_v4) - { - num_rt_rule = each_client_rt_rule_count_v4; - } - else - { - num_rt_rule = each_client_rt_rule_count_v6; - } - - len = sizeof(ipa_ioc_add_rt_rule) + num_rt_rule * sizeof(ipa_rt_rule_add); - rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(len); - if (rt_rule_table == NULL) - { - IPACMERR("Failed to allocate memory.\n"); - return IPACM_FAILURE; - } - memset(rt_rule_table, 0, len); - - rt_rule_table->commit = 1; - rt_rule_table->ip = iptype; - rt_rule_table->num_rules = num_rt_rule; - if (src == SRC_LAN) - { - if (iptype == IPA_IP_v4) - { - strlcpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_lan_v4.name, sizeof(rt_rule_table->rt_tbl_name)); - } - else - { - strlcpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_lan_v6.name, sizeof(rt_rule_table->rt_tbl_name)); - } - } - else - { - if (iptype == IPA_IP_v4) - { - strlcpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4.name, sizeof(rt_rule_table->rt_tbl_name)); - } - else - { - strlcpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6.name, sizeof(rt_rule_table->rt_tbl_name)); - } - } - rt_rule_table->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0'; - memset(&rt_rule, 0, sizeof(ipa_rt_rule_add)); - rt_rule.at_rear = false; - rt_rule.status = -1; - rt_rule.rt_rule_hdl = -1; - - rt_rule.rule.hdr_hdl = 0; - if(src == SRC_LAN) - { - if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) - { - rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::cpe_to_usb_hdr_proc_ctx.proc_ctx_hdl; - } - else if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) - { - rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::usb_to_cpe_hdr_proc_ctx.proc_ctx_hdl; - } - else - { - IPACMERR("Iface category is not expected.\n"); - res = IPACM_FAILURE; - goto fail; - } - } - else - { - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) - { - rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::wlan_to_usb_hdr_proc_ctx.proc_ctx_hdl; - } - else if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF) - { - rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::wlan_to_cpe_hdr_proc_ctx.proc_ctx_hdl; - } - else - { - IPACMERR("Iface category is not expected.\n"); - res = IPACM_FAILURE; - goto fail; - } - } - position = 0; - for(i=0; i<iface_query->num_tx_props; i++) - { - if(tx_prop->tx[i].ip == iptype) - { - if(position >= num_rt_rule) - { - IPACMERR("Number of routing rules already exceeds limit.\n"); - res = IPACM_FAILURE; - goto fail; - } - rt_rule.rule.dst = tx_prop->tx[i].dst_pipe; - - memcpy(&rt_rule.rule.attrib, &tx_prop->tx[i].attrib, sizeof(rt_rule.rule.attrib)); - if(src == SRC_WLAN) //src is WLAN means packet is from WLAN - { - if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II) - { - rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; - } - else - { - rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; - } - } - else //packet is from LAN - { - if(IPACM_Lan::lan_hdr_type == IPA_HDR_L2_ETHERNET_II) - { - rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; - } - else - { - rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; - } - } - memcpy(rt_rule.rule.attrib.dst_mac_addr, mac, sizeof(rt_rule.rule.attrib.dst_mac_addr)); - memset(rt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule.rule.attrib.dst_mac_addr_mask)); - - memcpy(&(rt_rule_table->rules[position]), &rt_rule, sizeof(rt_rule_table->rules[position])); - position++; - } - } - if(false == m_routing.AddRoutingRule(rt_rule_table)) - { - IPACMERR("Routing rule addition failed!\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - if(src == SRC_LAN) - { - for(i=0; i<num_rt_rule; i++) - { - if(iptype == IPA_IP_v4) - { - eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_lan_info_count_v4, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; - } - else - { - eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_lan_info_count_v6, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; - } - } - if(iptype == IPA_IP_v4) - { - lan_client_rt_from_lan_info_count_v4++; - IPACMDBG_H("Now the number of IPv4 rt rule on lan-lan rt table is %d.\n", lan_client_rt_from_lan_info_count_v4); - } - else - { - lan_client_rt_from_lan_info_count_v6++; - IPACMDBG_H("Now the number of IPv6 rt rule on lan-lan rt table is %d.\n", lan_client_rt_from_lan_info_count_v6); - } - } - else - { - for(i=0; i<num_rt_rule; i++) - { - if(iptype == IPA_IP_v4) - { - eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_wlan_info_count_v4, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; - } - else - { - eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_wlan_info_count_v6, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; - } - } - if(iptype == IPA_IP_v4) - { - lan_client_rt_from_wlan_info_count_v4++; - IPACMDBG_H("Now the number of IPv4 rt rule on lan-wlan rt table is %d.\n", lan_client_rt_from_wlan_info_count_v4); - } - else - { - lan_client_rt_from_wlan_info_count_v6++; - IPACMDBG_H("Now the number of IPv6 rt rule on lan-wlan rt table is %d.\n", lan_client_rt_from_wlan_info_count_v6); - } - } - } - -fail: - if(rt_rule_table != NULL) - { - free(rt_rule_table); - } - return res; -} - -int IPACM_Lan::eth_bridge_del_lan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src) -{ - if(tx_prop == NULL) - { - IPACMDBG_H("Tx prop is empty, not deleting routing rule.\n"); - return IPACM_SUCCESS; - } - if(mac == NULL) - { - IPACMERR("Client MAC address is empty.\n"); - return IPACM_FAILURE; - } - - IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x. src_iface: %d \n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], src); - - int i, position; - - /* first delete the rt rules from IPv4 rt table*/ - if(src == SRC_LAN) - { - for(i=0; i<lan_client_rt_from_lan_info_count_v4; i++) - { - if(memcmp(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac)) == 0) - { - position = i; - IPACMDBG_H("The client is found at position %d.\n", position); - break; - } - } - if(i == lan_client_rt_from_lan_info_count_v4) - { - IPACMERR("The client is not found.\n"); - return IPACM_FAILURE; - } - } - else - { - for(i=0; i<lan_client_rt_from_wlan_info_count_v4; i++) - { - if(memcmp(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac)) == 0) - { - position = i; - IPACMDBG_H("The client is found at position %d.\n", position); - break; - } - } - if(i == lan_client_rt_from_wlan_info_count_v4) - { - IPACMERR("The client is not found.\n"); - return IPACM_FAILURE; - } - } - - for(i=0; i<each_client_rt_rule_count_v4; i++) - { - if(m_routing.DeleteRoutingHdl(eth_bridge_get_client_rt_info_ptr(position, src, IPA_IP_v4)->rt_rule_hdl[i], IPA_IP_v4) == false) - { - IPACMERR("Failed to delete routing rule %d.\n", i); - return IPACM_FAILURE; - } - } - - if(src == SRC_LAN) - { - for(i=position+1; i<lan_client_rt_from_lan_info_count_v4; i++) - { - memcpy(eth_bridge_get_client_rt_info_ptr(i-1, src, IPA_IP_v4), eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4), client_rt_info_size_v4); - } - memset(eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_lan_info_count_v4-1, src, IPA_IP_v4), 0, client_rt_info_size_v4); - lan_client_rt_from_lan_info_count_v4--; - IPACMDBG_H("Now the number of IPv4 rt rule from lan info is %d.\n", lan_client_rt_from_lan_info_count_v4); - } - else - { - for(i=position+1; i<lan_client_rt_from_wlan_info_count_v4; i++) - { - memcpy(eth_bridge_get_client_rt_info_ptr(i-1, src, IPA_IP_v4), eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4), client_rt_info_size_v4); - } - memset(eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_wlan_info_count_v4-1, src, IPA_IP_v4), 0, client_rt_info_size_v4); - lan_client_rt_from_wlan_info_count_v4--; - IPACMDBG_H("Now the number of IPv4 rt rule from wlan info is %d.\n", lan_client_rt_from_wlan_info_count_v4); - } - - /*delete rt rules from IPv6 rt table */ - if(src == SRC_LAN) - { - for(i=0; i<lan_client_rt_from_lan_info_count_v6; i++) - { - if(memcmp(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac)) == 0) - { - position = i; - IPACMDBG_H("The client is found at position %d.\n", position); - break; - } - } - if(i == lan_client_rt_from_lan_info_count_v6) - { - IPACMERR("The client is not found.\n"); - return IPACM_FAILURE; - } - } - else - { - for(i=0; i<lan_client_rt_from_wlan_info_count_v6; i++) - { - if(memcmp(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac)) == 0) - { - position = i; - IPACMDBG_H("The client is found at position %d.\n", position); - break; - } - } - if(i == lan_client_rt_from_wlan_info_count_v6) - { - IPACMERR("The client is not found.\n"); - return IPACM_FAILURE; - } - } - - for(i=0; i<each_client_rt_rule_count_v6; i++) - { - if(m_routing.DeleteRoutingHdl(eth_bridge_get_client_rt_info_ptr(position, src, IPA_IP_v6)->rt_rule_hdl[i], IPA_IP_v6) == false) - { - IPACMERR("Failed to delete routing rule %d.\n", i); - return IPACM_FAILURE; - } - } - - if(src == SRC_LAN) - { - for(i=position+1; i<lan_client_rt_from_lan_info_count_v6; i++) - { - memcpy(eth_bridge_get_client_rt_info_ptr(i-1, src, IPA_IP_v6), eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6), client_rt_info_size_v6); - } - memset(eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_lan_info_count_v6-1, src, IPA_IP_v6), 0, client_rt_info_size_v6); - lan_client_rt_from_lan_info_count_v6--; - IPACMDBG_H("Now the number of IPv6 rt rule from lan info is %d.\n", lan_client_rt_from_lan_info_count_v6); - } - else - { - for(i=position+1; i<lan_client_rt_from_wlan_info_count_v6; i++) - { - memcpy(eth_bridge_get_client_rt_info_ptr(i-1, src, IPA_IP_v6), eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6), client_rt_info_size_v6); - } - memset(eth_bridge_get_client_rt_info_ptr(lan_client_rt_from_wlan_info_count_v6-1, src, IPA_IP_v6), 0, client_rt_info_size_v6); - lan_client_rt_from_wlan_info_count_v6--; - IPACMDBG_H("Now the number of IPv6 rt rule from wlan info is %d.\n", lan_client_rt_from_wlan_info_count_v6); - } - - return IPACM_SUCCESS; -} - -eth_bridge_client_rt_info* IPACM_Lan::eth_bridge_get_client_rt_info_ptr(uint8_t index, eth_bridge_src_iface src, ipa_ip_type iptype) -{ - void* result; - - if(src == SRC_LAN) - { - if(iptype == IPA_IP_v4) - { - result = (void*)((void*)eth_bridge_lan_client_rt_from_lan_info_v4 + index * client_rt_info_size_v4); - } - else - { - result = (void*)((void*)eth_bridge_lan_client_rt_from_lan_info_v6 + index * client_rt_info_size_v6); - } - } - else - { - if(iptype == IPA_IP_v4) - { - result = (void*)((void*)eth_bridge_lan_client_rt_from_wlan_info_v4 + index * client_rt_info_size_v4); - } - else - { - result = (void*)((void*)eth_bridge_lan_client_rt_from_wlan_info_v6 + index * client_rt_info_size_v6); - } - } - return (eth_bridge_client_rt_info*)result; -} - - -void IPACM_Lan::eth_bridge_add_lan_client(uint8_t* mac) -{ - if(IPACM_Lan::num_lan_client == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - { - IPACMDBG_H("USB client table is already full.\n"); - return; - } - - if(mac == NULL) - { - IPACMERR("Mac address is empty.\n"); - return; - } - - int i; - for(i=0; i<IPACM_Lan::num_lan_client; i++) - { - if(memcmp(IPACM_Lan::eth_bridge_lan_client[i].mac, mac, sizeof(IPACM_Lan::eth_bridge_lan_client[i].mac)) == 0) - { - IPACMDBG_H("The lan client mac has been added before at position %d.\n", i); - return; - } - } - - memcpy(IPACM_Lan::eth_bridge_lan_client[IPACM_Lan::num_lan_client].mac, mac, sizeof(IPACM_Lan::eth_bridge_lan_client[IPACM_Lan::num_lan_client].mac)); - IPACM_Lan::eth_bridge_lan_client[IPACM_Lan::num_lan_client].ipa_if_num = ipa_if_num; - IPACM_Lan::num_lan_client++; - IPACMDBG_H("Now total num of lan clients is %d\n", IPACM_Lan::num_lan_client); - return; -} - -void IPACM_Lan::eth_bridge_del_lan_client(uint8_t* mac) -{ - if(mac == NULL) - { - IPACMERR("Mac address is empty.\n"); - return; - } - - int i, j; - for(i=0; i<IPACM_Lan::num_lan_client; i++) - { - if(memcmp(IPACM_Lan::eth_bridge_lan_client[i].mac, mac, sizeof(IPACM_Lan::eth_bridge_lan_client[i].mac)) == 0) - { - IPACMDBG_H("Found LAN client at position %d.\n", i); - break; - } - } - - if(i == IPACM_Lan::num_lan_client) - { - IPACMDBG_H("Not finding the LAN client.\n"); - return; - } - - for(j=i+1; j<IPACM_Lan::num_lan_client; j++) - { - memcpy(IPACM_Lan::eth_bridge_lan_client[j-1].mac, IPACM_Lan::eth_bridge_lan_client[j].mac, sizeof(IPACM_Lan::eth_bridge_lan_client[j].mac)); - IPACM_Lan::eth_bridge_lan_client[j-1].ipa_if_num = IPACM_Lan::eth_bridge_lan_client[j].ipa_if_num; - } - IPACM_Lan::num_lan_client--; - IPACMDBG_H("Now total num of lan clients is %d\n", IPACM_Lan::num_lan_client); - return; -} - int IPACM_Lan::eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl) { if(hdr_hdl == NULL) @@ -6843,120 +3610,6 @@ int IPACM_Lan::eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl) return IPACM_SUCCESS; } -int IPACM_Lan::del_hdr_proc_ctx() -{ - if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true) - { - if((IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF) - || (IPACM_Lan::is_usb_up == false && IPACM_Lan::is_cpe_up == false)) - { - if(m_header.DeleteHeaderProcCtx(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.proc_ctx_hdl) == false) - { - IPACMERR("Failed to delete usb to wlan hdr proc ctx.\n"); - return IPACM_FAILURE; - } - IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid = false; - - ipacm_cmd_q_data evt_data; - memset(&evt_data, 0, sizeof(ipacm_cmd_q_data)); - - ipacm_event_data_if_cat* cat; - cat = (ipacm_event_data_if_cat*)malloc(sizeof(ipacm_event_data_if_cat)); - if(cat == NULL) - { - IPACMERR("Unable to allocate memory.\n"); - return IPACM_FAILURE; - } - memset(cat, 0, sizeof(ipacm_event_data_if_cat)); - cat->if_cat = IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat; - - evt_data.evt_data = cat; - evt_data.event = IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT; - IPACMDBG_H("Posting event IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT\n"); - IPACM_EvtDispatcher::PostEvt(&evt_data); - } - } - - if(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == true) - { - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF || IPACM_Lan::is_usb_up == false) - { - if(m_header.DeleteHeaderProcCtx(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.proc_ctx_hdl) == false) - { - IPACMERR("Failed to delete wlan to usb hdr proc ctx.\n"); - return IPACM_FAILURE; - } - IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid = false; - } - } - - if(IPACM_Lan::wlan_to_cpe_hdr_proc_ctx.valid == true) - { - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF || IPACM_Lan::is_cpe_up == false) - { - if(m_header.DeleteHeaderProcCtx(IPACM_Lan::wlan_to_cpe_hdr_proc_ctx.proc_ctx_hdl) == false) - { - IPACMERR("Failed to delete wlan to cpe hdr proc ctx.\n"); - return IPACM_FAILURE; - } - IPACM_Lan::wlan_to_cpe_hdr_proc_ctx.valid = false; - } - } - - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF) - { - if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true) - { - if(m_header.DeleteHeaderProcCtx(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.proc_ctx_hdl) == false) - { - IPACMERR("Failed to delete wlan to wlan hdr proc ctx.\n"); - return IPACM_FAILURE; - } - IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid = false; - } - } - - if(IPACM_Lan::cpe_to_usb_hdr_proc_ctx.valid == true && IPACM_Lan::usb_to_cpe_hdr_proc_ctx.valid == true) - { - if((IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == LAN_IF) - || (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ODU_IF)) - { - if(m_header.DeleteHeaderProcCtx(IPACM_Lan::cpe_to_usb_hdr_proc_ctx.proc_ctx_hdl) == false) - { - IPACMERR("Failed to delete cpe to usb hdr proc ctx.\n"); - return IPACM_FAILURE; - } - IPACM_Lan::cpe_to_usb_hdr_proc_ctx.valid = false; - - if(m_header.DeleteHeaderProcCtx(IPACM_Lan::usb_to_cpe_hdr_proc_ctx.proc_ctx_hdl) == false) - { - IPACMERR("Failed to delete usb to cpe hdr proc ctx.\n"); - return IPACM_FAILURE; - } - IPACM_Lan::usb_to_cpe_hdr_proc_ctx.valid = false; - - ipacm_cmd_q_data evt_data; - memset(&evt_data, 0, sizeof(ipacm_cmd_q_data)); - - ipacm_event_data_if_cat* cat; - cat = (ipacm_event_data_if_cat*)malloc(sizeof(ipacm_event_data_if_cat)); - if(cat == NULL) - { - IPACMERR("Unable to allocate memory.\n"); - return IPACM_FAILURE; - } - memset(cat, 0, sizeof(ipacm_event_data_if_cat)); - cat->if_cat = IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat; - - evt_data.evt_data = cat; - evt_data.event = IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT; - IPACMDBG_H("Posting event IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT\n"); - IPACM_EvtDispatcher::PostEvt(&evt_data); - } - } - return IPACM_SUCCESS; -} - int IPACM_Lan::handle_cradle_wan_mode_switch(bool is_wan_bridge_mode) { struct ipa_flt_rule_mdfy flt_rule_entry; @@ -7204,3 +3857,365 @@ int IPACM_Lan::handle_tethering_client(bool reset, ipacm_client_enum ipa_client) close(fd_wwan_ioctl); return ret; } + +/* mac address has to be provided for client related events */ +void IPACM_Lan::eth_bridge_post_event(ipa_cm_event_id evt, ipa_ip_type iptype, uint8_t *mac) +{ + ipacm_cmd_q_data eth_bridge_evt; + ipacm_event_eth_bridge *evt_data; + + evt_data = (ipacm_event_eth_bridge*)malloc(sizeof(ipacm_event_eth_bridge)); + if(evt_data == NULL) + { + IPACMERR("Failed to allocate memory.\n"); + return; + } + memset(evt_data, 0, sizeof(ipacm_event_eth_bridge)); + + evt_data->p_iface = this; + evt_data->iptype = iptype; + if(mac) + { + IPACMDBG_H("Client mac: 0x%02x%02x%02x%02x%02x%02x \n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + memcpy(evt_data->mac_addr, mac, sizeof(evt_data->mac_addr)); + } + + memset(ð_bridge_evt, 0, sizeof(ipacm_cmd_q_data)); + eth_bridge_evt.evt_data = (void*)evt_data; + eth_bridge_evt.event = evt; + + IPACMDBG_H("Posting event %s\n", + IPACM_Iface::ipacmcfg->getEventName(evt)); + IPACM_EvtDispatcher::PostEvt(ð_bridge_evt); +} + +/* add header processing context and return handle to lan2lan controller */ +int IPACM_Lan::eth_bridge_add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_hdr_type, uint32_t *hdl) +{ + int len, res = IPACM_SUCCESS; + uint32_t hdr_template; + ipa_ioc_add_hdr_proc_ctx* pHeaderProcTable = NULL; + + len = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_add); + pHeaderProcTable = (ipa_ioc_add_hdr_proc_ctx*)malloc(len); + if(pHeaderProcTable == NULL) + { + IPACMERR("Cannot allocate header processing context table.\n"); + return IPACM_FAILURE; + } + + memset(pHeaderProcTable, 0, len); + pHeaderProcTable->commit = 1; + pHeaderProcTable->num_proc_ctxs = 1; + pHeaderProcTable->proc_ctx[0].type = eth_bridge_get_hdr_proc_type(peer_l2_hdr_type, tx_prop->tx[0].hdr_l2_type); + eth_bridge_get_hdr_template_hdl(&hdr_template); + pHeaderProcTable->proc_ctx[0].hdr_hdl = hdr_template; + if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) + { + IPACMERR("Adding hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); + res = IPACM_FAILURE; + goto end; + } + + *hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; + +end: + free(pHeaderProcTable); + return res; +} + +/* add routing rule and return handle to lan2lan controller */ +int IPACM_Lan::eth_bridge_add_rt_rule(uint8_t *mac, char *rt_tbl_name, uint32_t hdr_proc_ctx_hdl, + ipa_hdr_l2_type peer_l2_hdr_type, ipa_ip_type iptype, uint32_t *rt_rule_hdl, int *rt_rule_count) +{ + int i, len, res = IPACM_SUCCESS; + struct ipa_ioc_add_rt_rule* rt_rule_table = NULL; + struct ipa_rt_rule_add rt_rule; + int position, num_rt_rule; + + IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x.\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + num_rt_rule = each_client_rt_rule_count[iptype]; + + len = sizeof(ipa_ioc_add_rt_rule) + num_rt_rule * sizeof(ipa_rt_rule_add); + rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(len); + if (rt_rule_table == NULL) + { + IPACMERR("Failed to allocate memory.\n"); + return IPACM_FAILURE; + } + memset(rt_rule_table, 0, len); + + rt_rule_table->commit = 1; + rt_rule_table->ip = iptype; + rt_rule_table->num_rules = num_rt_rule; + strlcpy(rt_rule_table->rt_tbl_name, rt_tbl_name, sizeof(rt_rule_table->rt_tbl_name)); + rt_rule_table->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = 0; + + memset(&rt_rule, 0, sizeof(ipa_rt_rule_add)); + rt_rule.at_rear = false; + rt_rule.status = -1; + rt_rule.rt_rule_hdl = -1; +#ifdef FEATURE_IPA_V3 + rt_rule.rule.hashable = true; +#endif + rt_rule.rule.hdr_hdl = 0; + rt_rule.rule.hdr_proc_ctx_hdl = hdr_proc_ctx_hdl; + + position = 0; + for(i=0; i<iface_query->num_tx_props; i++) + { + if(tx_prop->tx[i].ip == iptype) + { + if(position >= num_rt_rule || position >= MAX_NUM_PROP) + { + IPACMERR("Number of routing rules already exceeds limit.\n"); + res = IPACM_FAILURE; + goto end; + } + + if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->isMCC_Mode) + { + IPACMDBG_H("In WLAN MCC mode, use alt dst pipe: %d\n", + tx_prop->tx[i].alt_dst_pipe); + rt_rule.rule.dst = tx_prop->tx[i].alt_dst_pipe; + } + else + { + IPACMDBG_H("It is not WLAN MCC mode, use dst pipe: %d\n", + tx_prop->tx[i].dst_pipe); + rt_rule.rule.dst = tx_prop->tx[i].dst_pipe; + } + + memcpy(&rt_rule.rule.attrib, &tx_prop->tx[i].attrib, sizeof(rt_rule.rule.attrib)); + if(peer_l2_hdr_type == IPA_HDR_L2_ETHERNET_II) + rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; + else + rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; + memcpy(rt_rule.rule.attrib.dst_mac_addr, mac, sizeof(rt_rule.rule.attrib.dst_mac_addr)); + memset(rt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule.rule.attrib.dst_mac_addr_mask)); + + memcpy(&(rt_rule_table->rules[position]), &rt_rule, sizeof(rt_rule_table->rules[position])); + position++; + } + } + if(false == m_routing.AddRoutingRule(rt_rule_table)) + { + IPACMERR("Routing rule addition failed!\n"); + res = IPACM_FAILURE; + goto end; + } + else + { + *rt_rule_count = position; + for(i=0; i<position; i++) + rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; + } + +end: + free(rt_rule_table); + return res; +} + +/* modify routing rule*/ +int IPACM_Lan::eth_bridge_modify_rt_rule(uint8_t *mac, uint32_t hdr_proc_ctx_hdl, + ipa_hdr_l2_type peer_l2_hdr_type, ipa_ip_type iptype, uint32_t *rt_rule_hdl, int rt_rule_count) +{ + struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL; + struct ipa_rt_rule_mdfy *rt_rule_entry; + int len, index, res = IPACM_SUCCESS; + + if(tx_prop == NULL) + { + IPACMDBG_H("No tx properties \n"); + return IPACM_FAILURE; + } + + if(ipa_if_cate != WLAN_IF) + { + IPACMDBG_H("This is not WLAN IF, no need to modify rt rule.\n"); + return IPACM_SUCCESS; + } + + IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + len = sizeof(struct ipa_ioc_mdfy_rt_rule) + rt_rule_count * sizeof(struct ipa_rt_rule_mdfy); + rt_rule = (struct ipa_ioc_mdfy_rt_rule *)malloc(len); + if(rt_rule == NULL) + { + IPACMERR("Unable to allocate memory for modify rt rule\n"); + return IPACM_FAILURE; + } + memset(rt_rule, 0, len); + + rt_rule->commit = 1; + rt_rule->num_rules = 0; + rt_rule->ip = iptype; + + for (index = 0; index < tx_prop->num_tx_props; index++) + { + if (tx_prop->tx[index].ip == iptype) + { + if (rt_rule->num_rules >= rt_rule_count) + { + IPACMERR("Number of routing rules exceeds limit.\n"); + res = IPACM_FAILURE; + goto end; + } + + rt_rule_entry = &rt_rule->rules[rt_rule->num_rules]; + + if (IPACM_Iface::ipacmcfg->isMCC_Mode) + { + IPACMDBG_H("In WLAN MCC mode, use alt dst pipe: %d\n", + tx_prop->tx[index].alt_dst_pipe); + rt_rule_entry->rule.dst = tx_prop->tx[index].alt_dst_pipe; + } + else + { + IPACMDBG_H("In WLAN SCC mode, use dst pipe: %d\n", + tx_prop->tx[index].dst_pipe); + rt_rule_entry->rule.dst = tx_prop->tx[index].dst_pipe; + } + + rt_rule_entry->rule.hdr_hdl = 0; + rt_rule_entry->rule.hdr_proc_ctx_hdl = hdr_proc_ctx_hdl; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif + memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[index].attrib, + sizeof(rt_rule_entry->rule.attrib)); + if(peer_l2_hdr_type == IPA_HDR_L2_ETHERNET_II) + rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; + else + rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; + memcpy(rt_rule_entry->rule.attrib.dst_mac_addr, mac, + sizeof(rt_rule_entry->rule.attrib.dst_mac_addr)); + memset(rt_rule_entry->rule.attrib.dst_mac_addr_mask, 0xFF, + sizeof(rt_rule_entry->rule.attrib.dst_mac_addr_mask)); + + rt_rule_entry->rt_rule_hdl = rt_rule_hdl[rt_rule->num_rules]; + rt_rule->num_rules++; + } + } + + if(m_routing.ModifyRoutingRule(rt_rule) == false) + { + IPACMERR("Failed to modify routing rules.\n"); + res = IPACM_FAILURE; + goto end; + } + if(m_routing.Commit(iptype) == false) + { + IPACMERR("Failed to commit routing rules.\n"); + res = IPACM_FAILURE; + goto end; + } + IPACMDBG("Modified routing rules successfully.\n"); + +end: + free(rt_rule); + return res; +} + +int IPACM_Lan::eth_bridge_add_flt_rule(uint8_t *mac, uint32_t rt_tbl_hdl, ipa_ip_type iptype, uint32_t *flt_rule_hdl) +{ + int len, res = IPACM_SUCCESS; + struct ipa_flt_rule_add flt_rule_entry; + struct ipa_ioc_add_flt_rule_after *pFilteringTable = NULL; + +#ifdef FEATURE_IPA_V3 + if (rx_prop == NULL || tx_prop == NULL) + { + IPACMDBG_H("No rx or tx properties registered for iface %s\n", dev_name); + return IPACM_FAILURE; + } + + IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + len = sizeof(struct ipa_ioc_add_flt_rule_after) + sizeof(struct ipa_flt_rule_add); + pFilteringTable = (struct ipa_ioc_add_flt_rule_after*)malloc(len); + if (!pFilteringTable) + { + IPACMERR("Failed to allocate ipa_ioc_add_flt_rule_after memory...\n"); + return IPACM_FAILURE; + } + memset(pFilteringTable, 0, len); + + /* add mac based rule*/ + pFilteringTable->commit = 1; + pFilteringTable->ep = rx_prop->rx[0].src_pipe; + pFilteringTable->ip = iptype; + pFilteringTable->num_rules = 1; + pFilteringTable->add_after_hdl = eth_bridge_flt_rule_offset[iptype]; + + memset(&flt_rule_entry, 0, sizeof(flt_rule_entry)); + flt_rule_entry.at_rear = 1; + + flt_rule_entry.rule.retain_hdr = 0; + flt_rule_entry.rule.to_uc = 0; + flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; + flt_rule_entry.rule.eq_attrib_type = 0; + flt_rule_entry.rule.rt_tbl_hdl = rt_tbl_hdl; + + memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); + if(tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_ETHERNET_II) + { + flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; + } + else + { + flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; + } + + memcpy(flt_rule_entry.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr)); + memset(flt_rule_entry.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr_mask)); + + memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry)); + if (false == m_filtering.AddFilteringRuleAfter(pFilteringTable)) + { + IPACMERR("Failed to add client filtering rules.\n"); + res = IPACM_FAILURE; + goto end; + } + *flt_rule_hdl = pFilteringTable->rules[0].flt_rule_hdl; + +end: + free(pFilteringTable); +#endif + return res; +} + +int IPACM_Lan::eth_bridge_del_flt_rule(uint32_t flt_rule_hdl, ipa_ip_type iptype) +{ + if(m_filtering.DeleteFilteringHdls(&flt_rule_hdl, iptype, 1) == false) + { + IPACMERR("Failed to delete the client specific flt rule.\n"); + return IPACM_FAILURE; + } + return IPACM_SUCCESS; +} + +int IPACM_Lan::eth_bridge_del_rt_rule(uint32_t rt_rule_hdl, ipa_ip_type iptype) +{ + if(m_routing.DeleteRoutingHdl(rt_rule_hdl, iptype) == false) + { + IPACMERR("Failed to delete routing rule.\n"); + return IPACM_FAILURE; + } + return IPACM_SUCCESS; +} + +/* delete header processing context */ +int IPACM_Lan::eth_bridge_del_hdr_proc_ctx(uint32_t hdr_proc_ctx_hdl) +{ + if(m_header.DeleteHeaderProcCtx(hdr_proc_ctx_hdl) == false) + { + IPACMERR("Failed to delete hdr proc ctx.\n"); + return IPACM_FAILURE; + } + return IPACM_SUCCESS; +} diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_LanToLan.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_LanToLan.cpp index 0abfc42..6817177 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_LanToLan.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_LanToLan.cpp @@ -39,1567 +39,1214 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <stdlib.h> -#include <assert.h> #include "IPACM_LanToLan.h" #include "IPACM_Wlan.h" -#define ipv6_multicast_addr 0xff000000 -#define ipv6_multicast_mask 0xff000000 +#define __stringify(x...) #x -#define max_cache_connection 20 +const char *ipa_l2_hdr_type[] = { + __stringify(NONE), + __stringify(ETH_II), + __stringify(802_3), + __stringify(L2_MAX) +}; -IPACM_LanToLan* IPACM_LanToLan::p_instance = NULL; - -IPACM_LanToLan::IPACM_LanToLan() +IPACM_LanToLan_Iface::IPACM_LanToLan_Iface(IPACM_Lan *p_iface) { - num_offload_pair_v4_ = 0; - num_offload_pair_v6_ = 0; - client_info_v4_.reserve(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_LAN_CLIENT); - client_info_v6_.reserve(3*(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_LAN_CLIENT)); - p_instance = this; - - IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_ACTIVE, this); - IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_INACTIVE, this); - IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_DISCONNECT, this); - IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_POWER_SAVE, this); - IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_POWER_RECOVER, this); - IPACM_EvtDispatcher::registr(IPA_LAN_TO_LAN_NEW_CONNECTION, this); - IPACM_EvtDispatcher::registr(IPA_LAN_TO_LAN_DEL_CONNECTION, this); - return; -} + int i; -IPACM_LanToLan::~IPACM_LanToLan() -{ - client_table_v4::iterator it_v4; - for(it_v4 = client_info_v4_.begin(); it_v4 != client_info_v4_.end(); it_v4++) + m_p_iface = p_iface; + memset(m_is_ip_addr_assigned, 0, sizeof(m_is_ip_addr_assigned)); + m_support_inter_iface_offload = true; + m_support_intra_iface_offload = false; + for(i = 0; i < IPA_HDR_L2_MAX; i++) { - turnoff_offload_links(IPA_IP_v4, &(it_v4->second)); - clear_peer_list(&(it_v4->second)); + ref_cnt_peer_l2_hdr_type[i] = 0; + hdr_proc_ctx_for_inter_interface[i] = 0; } - client_info_v4_.clear(); - IPACMDBG("Clear IPv4 hash table in Lan2Lan distructor.\n"); + hdr_proc_ctx_for_intra_interface = 0; - client_table_v6::iterator it_v6; - for(it_v6 = client_info_v6_.begin(); it_v6 != client_info_v6_.end(); it_v6++) + if(p_iface->ipa_if_cate == WLAN_IF) { - turnoff_offload_links(IPA_IP_v6, &(it_v6->second)); - clear_peer_list(&(it_v6->second)); + IPACMDBG_H("Interface %s is WLAN interface.\n", p_iface->dev_name); + m_support_intra_iface_offload = true; + if( ((IPACM_Wlan*)p_iface)->is_guest_ap() ) + { + IPACMDBG_H("Interface %s is guest AP.\n", p_iface->dev_name); + m_support_inter_iface_offload = false; + } } - client_info_v6_.clear(); - IPACMDBG("Clear IPv6 hash table in Lan2Lan distructor.\n"); + return; +} + +IPACM_LanToLan_Iface::~IPACM_LanToLan_Iface() +{ +} + +IPACM_LanToLan::IPACM_LanToLan() +{ + IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_IFACE_UP, this); + IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_IFACE_DOWN, this); + IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_CLIENT_ADD, this); + IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_CLIENT_DEL, this); + IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, this); + + return; +} +IPACM_LanToLan::~IPACM_LanToLan() +{ + IPACMDBG_DMESG("WARNING: UNEXPECTEDLY KILL LAN2LAN CONTROLLER!\n"); return; } void IPACM_LanToLan::event_callback(ipa_cm_event_id event, void* param) { + ipacm_event_eth_bridge *data = (ipacm_event_eth_bridge*)param; + IPACMDBG_H("Get %s event.\n", IPACM_Iface::ipacmcfg->getEventName(event)); + switch(event) { - case IPA_LAN_CLIENT_ACTIVE: + case IPA_ETH_BRIDGE_IFACE_UP: { - IPACMDBG_H("Get IPA_LAN_CLIENT_ACTIVE event.\n"); - ipacm_event_lan_client* data = (ipacm_event_lan_client*)param; - handle_client_active(data); + handle_iface_up(data); break; } - case IPA_LAN_CLIENT_INACTIVE: + case IPA_ETH_BRIDGE_IFACE_DOWN: { - IPACMDBG_H("Get IPA_LAN_CLIENT_INACTIVE event.\n"); - ipacm_event_lan_client* data = (ipacm_event_lan_client*)param; - handle_client_inactive(data); + handle_iface_down(data); break; } - case IPA_LAN_CLIENT_DISCONNECT: + case IPA_ETH_BRIDGE_CLIENT_ADD: { - IPACMDBG_H("Get IPA_LAN_CLIENT_DISCONNECT event.\n"); - ipacm_event_lan_client* data = (ipacm_event_lan_client*)param; - handle_client_disconnect(data); + handle_client_add(data); break; } - case IPA_LAN_TO_LAN_NEW_CONNECTION: + case IPA_ETH_BRIDGE_CLIENT_DEL: { - IPACMDBG_H("Get IPA_LAN_TO_LAN_NEW_CONNECTION event.\n"); - ipacm_event_connection* data = (ipacm_event_connection*)param; - handle_new_lan2lan_connection(data); + handle_client_del(data); break; } - case IPA_LAN_TO_LAN_DEL_CONNECTION: + case IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH: { - IPACMDBG_H("Get IPA_LAN_TO_LAN_DEL_CONNECTION event.\n"); - ipacm_event_connection* data = (ipacm_event_connection*)param; - handle_del_lan2lan_connection(data); - break; - } - case IPA_LAN_CLIENT_POWER_SAVE: - { - IPACMDBG_H("Get IPA_LAN_CLIENT_POWER_SAVE event.\n"); - ipacm_event_lan_client* data = (ipacm_event_lan_client*)param; - handle_client_power_save(data); - break; - } - case IPA_LAN_CLIENT_POWER_RECOVER: - { - IPACMDBG_H("Get IPA_LAN_CLIENT_POWER_RECOVER event.\n"); - ipacm_event_lan_client* data = (ipacm_event_lan_client*)param; - handle_client_power_recover(data); + handle_wlan_scc_mcc_switch(data); break; } default: break; } + + print_data_structure_info(); return; } -void IPACM_LanToLan::handle_client_active(ipacm_event_lan_client* data) +void IPACM_LanToLan::handle_iface_up(ipacm_event_eth_bridge *data) { - if(data == NULL) - { - IPACMERR("No client info is found.\n"); - return; - } - if(data->mac_addr == NULL || data->ipv6_addr == NULL || data->p_iface == NULL) - { - IPACMERR("Event data is not populated properly.\n"); - return; - } - if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6) - { - IPACMERR("IP type is not expected.\n"); - return; - } - - IPACMDBG_H("New client info: iface %s, iptype: %d, mac: 0x%02x%02x%02x%02x%02x%02x, v4_addr: 0x%08x, v6_addr: 0x%08x%08x%08x%08x \n", - data->p_iface->dev_name, data->iptype, - data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], - data->ipv4_addr, data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); + list<IPACM_LanToLan_Iface>::iterator it; - bool client_not_found; - client_info* client_ptr; - - if(data->iptype == IPA_IP_v4) - { - client_not_found = (client_info_v4_.count(data->ipv4_addr) == 0); - IPACMDBG_H("Is the client not found? %d\n", client_not_found); - client_info& client = client_info_v4_[data->ipv4_addr]; - client_ptr = &client; - } - else + IPACMDBG_H("Interface name: %s IP type: %d\n", data->p_iface->dev_name, data->iptype); + for(it = m_iface.begin(); it != m_iface.end(); it++) { - uint64_t v6_addr; - memcpy(&v6_addr, &(data->ipv6_addr[2]), sizeof(uint64_t)); + if(it->get_iface_pointer() == data->p_iface) + { + IPACMDBG_H("Found the interface.\n"); + if(it->get_m_is_ip_addr_assigned(data->iptype) == false) + { + IPACMDBG_H("IP type %d was not active before, activating it now.\n", data->iptype); + it->set_m_is_ip_addr_assigned(data->iptype, true); - client_not_found = (client_info_v6_.count(v6_addr) == 0); - IPACMDBG_H("Is the client not found? %d\n", client_not_found); - client_info& client = client_info_v6_[v6_addr]; - client_ptr = &client; + /* install inter-interface rules */ + if(it->get_m_support_inter_iface_offload()) + it->add_all_inter_interface_client_flt_rule(data->iptype); + + /* install intra-BSS rules */ + if(it->get_m_support_intra_iface_offload()) + it->add_all_intra_interface_client_flt_rule(data->iptype); + } + break; + } } - if(client_not_found == true) + if(it == m_iface.end()) //If the interface has not been created before { - if(data->iptype == IPA_IP_v4) + if(m_iface.size() == MAX_NUM_IFACE) { - client_ptr->ip.ipv4_addr = data->ipv4_addr; + IPACMERR("The number of interfaces has reached maximum %d.\n", MAX_NUM_IFACE); + return; } - else + + if(!data->p_iface->tx_prop || !data->p_iface->rx_prop) { - memcpy(client_ptr->ip.ipv6_addr, data->ipv6_addr, sizeof(client_ptr->ip.ipv6_addr)); + IPACMERR("The interface %s does not have tx_prop or rx_prop.\n", data->p_iface->dev_name); + return; } - memcpy(client_ptr->mac_addr, data->mac_addr, sizeof(client_ptr->mac_addr)); - client_ptr->is_active = true; - client_ptr->is_powersave = false; - client_ptr->p_iface = data->p_iface; - generate_new_connection(data->iptype, client_ptr); - check_cache_connection(data->iptype, client_ptr); - } - else //the client is found - { - if(client_ptr->is_active == true) //the client is active + if(data->p_iface->tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_NONE || data->p_iface->tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_MAX) { - IPACMDBG_H("The client is active.\n"); - if(memcmp(client_ptr->mac_addr, data->mac_addr, sizeof(client_ptr->mac_addr)) == 0) - { - IPACMDBG_H("Mac addr is the same, do nothing.\n"); - } - else - { - IPACMERR("The new client has same IP but differenc mac.\n"); - turnoff_offload_links(data->iptype, client_ptr); - clear_peer_list(client_ptr); + IPACMERR("Invalid l2 header type %s!\n", ipa_l2_hdr_type[data->p_iface->tx_prop->tx[0].hdr_l2_type]); + return; + } - if(data->iptype == IPA_IP_v4) - { - client_ptr->ip.ipv4_addr = data->ipv4_addr; - } - else - { - memcpy(client_ptr->ip.ipv6_addr, data->ipv6_addr, sizeof(client_ptr->ip.ipv6_addr)); - } - memcpy(client_ptr->mac_addr, data->mac_addr, sizeof(client_ptr->mac_addr)); - client_ptr->is_active = true; - client_ptr->is_powersave = false; - client_ptr->p_iface = data->p_iface; + IPACMDBG_H("Does not find the interface, insert a new one.\n"); + IPACM_LanToLan_Iface new_iface(data->p_iface); + new_iface.set_m_is_ip_addr_assigned(data->iptype, true); - generate_new_connection(data->iptype, client_ptr); - check_cache_connection(data->iptype, client_ptr); - } - } - else //the client is inactive + m_iface.push_front(new_iface); + IPACMDBG_H("Now the total number of interfaces is %d.\n", m_iface.size()); + + IPACM_LanToLan_Iface &front_iface = m_iface.front(); + + /* install inter-interface rules */ + if(front_iface.get_m_support_inter_iface_offload()) { - IPACMDBG_H("The client is inactive.\n"); - if(data->iptype == IPA_IP_v4) - { - client_ptr->ip.ipv4_addr = data->ipv4_addr; - } - else + for(it = ++m_iface.begin(); it != m_iface.end(); it++) { - memcpy(client_ptr->ip.ipv6_addr, data->ipv6_addr, sizeof(client_ptr->ip.ipv6_addr)); + /* populate hdr_proc_ctx and routing table handle */ + handle_new_iface_up(&front_iface, &(*it)); + + /* add client specific routing rule on existing interface */ + it->add_client_rt_rule_for_new_iface(); } - memcpy(client_ptr->mac_addr, data->mac_addr, sizeof(client_ptr->mac_addr)); - client_ptr->is_active = true; - client_ptr->is_powersave = false; - client_ptr->p_iface = data->p_iface; - - check_potential_link(data->iptype, client_ptr); - generate_new_connection(data->iptype, client_ptr); - check_cache_connection(data->iptype, client_ptr); + + /* add client specific filtering rule on new interface */ + front_iface.add_all_inter_interface_client_flt_rule(data->iptype); } + + /* populate the intra-interface information */ + if(front_iface.get_m_support_intra_iface_offload()) + { + front_iface.handle_intra_interface_info(); + } + + /* handle cached client add event */ + handle_cached_client_add_event(front_iface.get_iface_pointer()); } - IPACMDBG_H("There are %d clients in v4 table and %d clients in v6 table.\n", client_info_v4_.size(), client_info_v6_.size()); return; } -void IPACM_LanToLan::check_potential_link(ipa_ip_type iptype, client_info* client) +void IPACM_LanToLan::handle_iface_down(ipacm_event_eth_bridge *data) { - if(client == NULL) - { - IPACMERR("Client is NULL.\n"); - return; - } - - IPACMDBG_H("Check client's peer list.\n"); - IPACMDBG_H("Client: IP type: %d, IPv4 addr: 0x%08x, IPv6 addr: 0x%08x%08x%08x%08x\n", iptype, client->ip.ipv4_addr, - client->ip.ipv6_addr[0], client->ip.ipv6_addr[1], client->ip.ipv6_addr[2], client->ip.ipv6_addr[3]); + list<IPACM_LanToLan_Iface>::iterator it_target_iface; - peer_info_list::iterator peer_it; - int res, num = 0; + IPACMDBG_H("Interface name: %s\n", data->p_iface->dev_name); - for(peer_it = client->peer.begin(); peer_it != client->peer.end(); peer_it++) + for(it_target_iface = m_iface.begin(); it_target_iface != m_iface.end(); it_target_iface++) { - if(peer_it->peer_pointer->is_active == true && peer_it->num_connection > 0) + if(it_target_iface->get_iface_pointer() == data->p_iface) { - res = IPACM_SUCCESS; - res = add_offload_link(iptype, client, peer_it->peer_pointer); - res = add_offload_link(iptype, peer_it->peer_pointer, client); - if(res == IPACM_SUCCESS) - { - if(iptype == IPA_IP_v4) - { - num_offload_pair_v4_ ++; - IPACMDBG_H("Now the number of v4 offload links is %d.\n", num_offload_pair_v4_); - } - else - { - num_offload_pair_v6_ ++; - IPACMDBG_H("Now the number of v6 offload links is %d.\n", num_offload_pair_v6_); - } - num++; - } + IPACMDBG_H("Found the interface.\n"); + break; } } - IPACMDBG_H("Added %d offload links in total.\n", num); - return; -} -int IPACM_LanToLan::add_offload_link(ipa_ip_type iptype, client_info* client, client_info* peer) -{ - if( (iptype == IPA_IP_v4 && num_offload_pair_v4_ >= MAX_OFFLOAD_PAIR) - || (iptype == IPA_IP_v6 && num_offload_pair_v6_ >= MAX_OFFLOAD_PAIR) ) - { - IPACMDBG_H("The number of offload pairs already reaches maximum.\n"); - return IPACM_FAILURE; - } - if(client == NULL || peer == NULL) + if(it_target_iface == m_iface.end()) { - IPACMERR("Either client or peer is NULL.\n"); - return IPACM_FAILURE; + IPACMDBG_H("The interface has not been found.\n"); + /* clear cached client add event for the unfound interface*/ + clear_cached_client_add_event(data->p_iface); + return; } - uint32_t hdr_hdl, flt_hdl; - lan_to_lan_rt_rule_hdl rt_rule_hdl; + it_target_iface->handle_down_event(); + m_iface.erase(it_target_iface); - offload_link_info link_info; - - - if(iptype == IPA_IP_v4) - { - IPACMDBG_H("Add offload link for IPv4, client IP: 0x%08x, peer IP: 0x%08x \n", client->ip.ipv4_addr, peer->ip.ipv4_addr); - } - else if(iptype == IPA_IP_v6) - { - IPACMDBG_H("Add offload link for IPv6, client IP: 0x%08x%08x%08x%08x, peer IP: 0x%08x%08x%08x%08x \n", - client->ip.ipv6_addr[0], client->ip.ipv6_addr[1], client->ip.ipv6_addr[2], client->ip.ipv6_addr[3], - peer->ip.ipv6_addr[0], peer->ip.ipv6_addr[1], peer->ip.ipv6_addr[2], peer->ip.ipv6_addr[3]); - } - else - { - IPACMERR("IP type is not expected.\n"); - return IPACM_FAILURE; - } + return; +} - //add lan2lan header - if(peer->p_iface->add_lan2lan_hdr(iptype, client->mac_addr, peer->mac_addr, &hdr_hdl) == IPACM_FAILURE) - { - IPACMERR("Failed to create lan2lan header.\n"); - return IPACM_FAILURE; - } - IPACMDBG_H("Created lan2lan hdr with hdl %d.\n", hdr_hdl); +void IPACM_LanToLan::handle_new_iface_up(IPACM_LanToLan_Iface *new_iface, IPACM_LanToLan_Iface *exist_iface) +{ + char rt_tbl_name_for_flt[IPA_IP_MAX][IPA_RESOURCE_NAME_MAX]; + char rt_tbl_name_for_rt[IPA_IP_MAX][IPA_RESOURCE_NAME_MAX]; - //add lan2lan routing/filtering rules - if(peer->p_iface->add_lan2lan_rt_rule(iptype, client->ip.ipv4_addr, peer->ip.ipv4_addr, - client->ip.ipv6_addr, peer->ip.ipv6_addr, hdr_hdl, &rt_rule_hdl) == IPACM_FAILURE) - { - IPACMERR("Failed to create lan2lan rt rule.\n"); - goto rt_fail; - } - IPACMDBG_H("Created %d lan2lan rt rules.\n", rt_rule_hdl.num_rule); - IPACMDBG_H("Created lan2lan rt rules with hdl: %d.\n", rt_rule_hdl.rule_hdl[0]); + IPACMDBG_H("Populate peer info between: new_iface %s, existing iface %s\n", new_iface->get_iface_pointer()->dev_name, + exist_iface->get_iface_pointer()->dev_name); - if(client->p_iface->add_lan2lan_flt_rule(iptype, client->ip.ipv4_addr, peer->ip.ipv4_addr, - client->ip.ipv6_addr, peer->ip.ipv6_addr, &flt_hdl) == IPACM_FAILURE) - { - IPACMERR("Failed to create lan2lan flt rule.\n"); - goto flt_fail; - } - IPACMDBG_H("Created lan2lan flt rule with hdl %d.\n", flt_hdl); + /* populate the routing table information */ + snprintf(rt_tbl_name_for_flt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX, "eth_v4_%s_to_%s", + ipa_l2_hdr_type[exist_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type], + ipa_l2_hdr_type[new_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type]); + IPACMDBG_H("IPv4 routing table for flt name: %s\n", rt_tbl_name_for_flt[IPA_IP_v4]); - link_info.peer_pointer = peer; - link_info.flt_rule_hdl = flt_hdl; - link_info.hdr_hdl = hdr_hdl; - memcpy(&link_info.rt_rule_hdl, &rt_rule_hdl, sizeof(lan_to_lan_rt_rule_hdl)); + snprintf(rt_tbl_name_for_flt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX, "eth_v6_%s_to_%s", + ipa_l2_hdr_type[exist_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type], + ipa_l2_hdr_type[new_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type]); + IPACMDBG_H("IPv6 routing table for flt name: %s\n", rt_tbl_name_for_flt[IPA_IP_v6]); - client->link.push_back(link_info); + snprintf(rt_tbl_name_for_rt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX, "eth_v4_%s_to_%s", + ipa_l2_hdr_type[new_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type], + ipa_l2_hdr_type[exist_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type]); + IPACMDBG_H("IPv4 routing table for rt name: %s\n", rt_tbl_name_for_rt[IPA_IP_v4]); - return IPACM_SUCCESS; + snprintf(rt_tbl_name_for_rt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX, "eth_v6_%s_to_%s", + ipa_l2_hdr_type[new_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type], + ipa_l2_hdr_type[exist_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type]); + IPACMDBG_H("IPv6 routing table for rt name: %s\n", rt_tbl_name_for_rt[IPA_IP_v6]); -flt_fail: - peer->p_iface->del_lan2lan_rt_rule(iptype, rt_rule_hdl); + /* add new peer info in both new iface and existing iface */ + exist_iface->handle_new_iface_up(rt_tbl_name_for_flt, rt_tbl_name_for_rt, new_iface); -rt_fail: - peer->p_iface->del_lan2lan_hdr(iptype, hdr_hdl); + new_iface->handle_new_iface_up(rt_tbl_name_for_rt, rt_tbl_name_for_flt, exist_iface); - return IPACM_FAILURE; + return; } -void IPACM_LanToLan::handle_client_inactive(ipacm_event_lan_client* data) +void IPACM_LanToLan::handle_client_add(ipacm_event_eth_bridge *data) { - if(data == NULL) - { - IPACMERR("No client info is found.\n"); - return; - } - if(data->mac_addr == NULL || data->ipv6_addr == NULL || data->p_iface == NULL) - { - IPACMERR("Event data is not populated properly.\n"); - return; - } - if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6) - { - IPACMERR("IP type is not expected: %d.\n", data->iptype); - return; - } - - IPACMDBG_H("Del client info: iface %s, iptype: %d, mac: 0x%02x%02x%02x%02x%02x%02x, v4_addr: 0x%08x, v6_addr: 0x%08x%08x%08x%08x \n", - data->p_iface->dev_name, data->iptype, - data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], - data->ipv4_addr, data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); + list<IPACM_LanToLan_Iface>::iterator it_iface; - client_info* client_ptr; - uint64_t v6_addr; + IPACMDBG_H("Incoming client MAC: 0x%02x%02x%02x%02x%02x%02x, interface: %s\n", data->mac_addr[0], data->mac_addr[1], + data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->p_iface->dev_name); - if(data->iptype == IPA_IP_v4) - { - if(client_info_v4_.count(data->ipv4_addr) == 0)//if not found the client, return - { - IPACMERR("The client is not found the client, return.\n"); - return; - } - IPACMDBG_H("The client is found.\n"); - client_info& client = client_info_v4_[data->ipv4_addr]; - client_ptr = &client; - } - else + for(it_iface = m_iface.begin(); it_iface != m_iface.end(); it_iface++) { - memcpy(&v6_addr, &(data->ipv6_addr[2]), sizeof(uint64_t)); - if(client_info_v6_.count(v6_addr) == 0) //if not found the client, insert it in table + if(it_iface->get_iface_pointer() == data->p_iface) //find the interface { - IPACMERR("The client is not found the client, return.\n"); - return; + IPACMDBG_H("Found the interface.\n"); + it_iface->handle_client_add(data->mac_addr); + break; } - IPACMDBG_H("The client is found.\n"); - client_info& client = client_info_v6_[v6_addr]; - client_ptr = &client; } - turnoff_offload_links(data->iptype, client_ptr); - client_ptr->is_active = false; - if(client_ptr->peer.size() == 0) + /* if the iface was not found, cache the client add event */ + if(it_iface == m_iface.end()) { - IPACMDBG_H("Peer list is empty, remove client entry.\n"); - if(data->iptype == IPA_IP_v4) + IPACMDBG_H("The interface is not found.\n"); + if(m_cached_client_add_event.size() < MAX_NUM_CACHED_CLIENT_ADD_EVENT) { - client_info_v4_.erase(data->ipv4_addr); + IPACMDBG_H("Cached the client information.\n"); + m_cached_client_add_event.push_front(*data); } else { - client_info_v6_.erase(v6_addr); + IPACMDBG_H("Cached client add event has reached maximum number.\n"); } } return; } -int IPACM_LanToLan::turnoff_offload_links(ipa_ip_type iptype, client_info* client) +void IPACM_LanToLan::handle_client_del(ipacm_event_eth_bridge *data) { - if(client == NULL) - { - IPACMERR("Client is NULL.\n"); - return IPACM_FAILURE; - } + list<IPACM_LanToLan_Iface>::iterator it_iface; - bool err_flag; - offload_link_info_list::iterator client_it; - offload_link_info_list::iterator peer_it; - client_info* peer; + IPACMDBG_H("Incoming client MAC: 0x%02x%02x%02x%02x%02x%02x, interface: %s\n", data->mac_addr[0], data->mac_addr[1], + data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->p_iface->dev_name); - for(client_it = client->link.begin(); client_it != client->link.end(); client_it++) + for(it_iface = m_iface.begin(); it_iface != m_iface.end(); it_iface++) { - peer = client_it->peer_pointer; - if(del_offload_link(iptype, client->p_iface, peer->p_iface, &(*client_it)) == IPACM_FAILURE) - { - IPACMERR("Failed to delete client's offload link.\n"); - return IPACM_FAILURE; - } - - err_flag = true; - for(peer_it = peer->link.begin(); peer_it != peer->link.end(); peer_it++) - { - if(peer_it->peer_pointer == client) - { - if(del_offload_link(iptype, peer->p_iface, client->p_iface, &(*peer_it)) == IPACM_FAILURE) - { - IPACMERR("Failed to delete peer's offload link.\n"); - return IPACM_FAILURE; - } - peer->link.erase(peer_it); - err_flag = false; - break; - } - } - if(err_flag) - { - IPACMERR("Unable to find corresponding offload link in peer's entry.\n"); - return IPACM_FAILURE; - } - if(iptype == IPA_IP_v4) + if(it_iface->get_iface_pointer() == data->p_iface) //found the interface { - num_offload_pair_v4_ --; - IPACMDBG_H("Now the number of v4 offload pair is %d\n", num_offload_pair_v4_); - } - else - { - num_offload_pair_v6_ --; - IPACMDBG_H("Now the number of v6 offload pair is %d\n", num_offload_pair_v6_); + IPACMDBG_H("Found the interface.\n"); + it_iface->handle_client_del(data->mac_addr); + break; } } - client->link.clear(); - return IPACM_SUCCESS; -} - -int IPACM_LanToLan::del_offload_link(ipa_ip_type iptype, IPACM_Lan* client, IPACM_Lan* peer, offload_link_info* link) -{ - if(client == NULL || peer == NULL || link == NULL) + if(it_iface == m_iface.end()) { - IPACMERR("Either iface or link is NULL.\n"); - return IPACM_FAILURE; + IPACMDBG_H("The interface is not found.\n"); } - IPACMDBG_H("Delete an offload link for IP type: %d\n", iptype); - - int res = IPACM_SUCCESS; - - if(client->del_lan2lan_flt_rule(iptype, link->flt_rule_hdl) == IPACM_FAILURE) - { - IPACMERR("Failed to delete flt rule.\n"); - res = IPACM_FAILURE; - } + return; +} - if(peer->del_lan2lan_rt_rule(iptype, link->rt_rule_hdl) == IPACM_FAILURE) - { - IPACMERR("Failed to delete rt rules.\n"); - res = IPACM_FAILURE; - } +void IPACM_LanToLan::handle_wlan_scc_mcc_switch(ipacm_event_eth_bridge *data) +{ + list<IPACM_LanToLan_Iface>::iterator it_iface; - if(peer->del_lan2lan_hdr(iptype, link->hdr_hdl) == IPACM_FAILURE) + IPACMDBG_H("Incoming interface: %s\n", data->p_iface->dev_name); + for(it_iface = m_iface.begin(); it_iface != m_iface.end(); it_iface++) { - IPACMERR("Failed to delete header.\n"); - res = IPACM_FAILURE; + if(it_iface->get_iface_pointer() == data->p_iface) + { + it_iface->handle_wlan_scc_mcc_switch(); + break; + } } - - return res; + return; } -void IPACM_LanToLan::handle_client_disconnect(ipacm_event_lan_client* data) +void IPACM_LanToLan::handle_cached_client_add_event(IPACM_Lan *p_iface) { - if(data == NULL) - { - IPACMERR("No client info is found.\n"); - return; - } - if(data->mac_addr == NULL || data->ipv6_addr == NULL || data->p_iface == NULL) - { - IPACMERR("Event data is not populated properly.\n"); - return; - } - if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6) - { - IPACMERR("IP type is not expected: %d.\n", data->iptype); - return; - } + list<ipacm_event_eth_bridge>::iterator it; - IPACMDBG_H("Del client info: iface %s, iptype: %d, mac: 0x%02x%02x%02x%02x%02x%02x, v4_addr: 0x%08x, v6_addr: 0x%08x%08x%08x%08x \n", - data->p_iface->dev_name, data->iptype, - data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], - data->ipv4_addr, data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); - - client_info* client_ptr; - uint64_t v6_addr; - if(data->iptype == IPA_IP_v4) + it = m_cached_client_add_event.begin(); + while(it != m_cached_client_add_event.end()) { - if(client_info_v4_.count(data->ipv4_addr) == 0) //if not found the client, return + if(it->p_iface == p_iface) { - IPACMERR("The client is not found the client, return.\n"); - return; + IPACMDBG_H("Found client with MAC: 0x%02x%02x%02x%02x%02x%02x\n", it->mac_addr[0], it->mac_addr[1], + it->mac_addr[2], it->mac_addr[3], it->mac_addr[4], it->mac_addr[5]); + handle_client_add(&(*it)); + it = m_cached_client_add_event.erase(it); } - IPACMDBG_H("The client is found.\n"); - client_info& client = client_info_v4_[data->ipv4_addr]; - client_ptr = &client; - } - else - { - memcpy(&v6_addr, &(data->ipv6_addr[2]), sizeof(uint64_t)); - if(client_info_v6_.count(v6_addr) == 0) //if not found the client, insert it in table + else { - IPACMERR("The client is not found the client, return.\n"); - return; + it++; } - IPACMDBG_H("The client is found.\n"); - client_info& client = client_info_v6_[v6_addr]; - client_ptr = &client; - } - - turnoff_offload_links(data->iptype, client_ptr); - clear_peer_list(client_ptr); - if(data->iptype == IPA_IP_v4) - { - client_info_v4_.erase(data->ipv4_addr); - } - else - { - client_info_v6_.erase(v6_addr); } return; } -int IPACM_LanToLan::clear_peer_list(client_info* client) +void IPACM_LanToLan::clear_cached_client_add_event(IPACM_Lan *p_iface) { - if(client == NULL) - { - IPACMERR("Client is NULL.\n"); - return IPACM_FAILURE; - } - - bool err_flag; - peer_info_list::iterator client_it; - peer_info_list::iterator peer_it; - client_info* peer; + list<ipacm_event_eth_bridge>::iterator it; - for(client_it = client->peer.begin(); client_it != client->peer.end(); client_it++) + it = m_cached_client_add_event.begin(); + while(it != m_cached_client_add_event.end()) { - err_flag = true; - peer = client_it->peer_pointer; - for(peer_it = peer->peer.begin(); peer_it != peer->peer.end(); peer_it++) + if(it->p_iface == p_iface) { - if(peer_it->peer_pointer == client) - { - peer->peer.erase(peer_it); - err_flag = false; - break; - } + IPACMDBG_H("Found client with MAC: 0x%02x%02x%02x%02x%02x%02x\n", it->mac_addr[0], it->mac_addr[1], + it->mac_addr[2], it->mac_addr[3], it->mac_addr[4], it->mac_addr[5]); + it = m_cached_client_add_event.erase(it); } - if(err_flag == true) + else { - IPACMERR("Failed to find peer info.\n"); - return IPACM_FAILURE; + it++; } } - client->peer.clear(); - return IPACM_SUCCESS; + return; } -void IPACM_LanToLan::handle_client_power_save(ipacm_event_lan_client* data) +void IPACM_LanToLan::print_data_structure_info() { - if(data == NULL) - { - IPACMERR("No client info is found.\n"); - return; - } - if(data->mac_addr == NULL || data->ipv6_addr == NULL || data->p_iface == NULL) + list<IPACM_LanToLan_Iface>::iterator it; + list<ipacm_event_eth_bridge>::iterator it_event; + int i; + + IPACMDBG_H("There are %d interfaces in total.\n", m_iface.size()); + + for(it = m_iface.begin(); it != m_iface.end(); it++) { - IPACMERR("Event data is not populated properly.\n"); - return; + it->print_data_structure_info(); } - if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6) + + IPACMDBG_H("There are %d cached client add events in total.\n", m_cached_client_add_event.size()); + + i = 1; + for(it_event = m_cached_client_add_event.begin(); it_event != m_cached_client_add_event.end(); it_event++) { - IPACMERR("IP type is not expected: %d.\n", data->iptype); - return; + IPACMDBG_H("Client %d MAC: 0x%02x%02x%02x%02x%02x%02x, interface: %s\n", i, it_event->mac_addr[0], it_event->mac_addr[1], it_event->mac_addr[2], + it_event->mac_addr[3], it_event->mac_addr[4], it_event->mac_addr[5], it_event->p_iface->dev_name); + i++; } - IPACMDBG_H("Client power save info: iface %s, iptype: %d, mac: 0x%02x%02x%02x%02x%02x%02x, v4_addr: 0x%08x, v6_addr: 0x%08x%08x%08x%08x \n", - data->p_iface->dev_name, data->iptype, - data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], - data->ipv4_addr, data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); + return; +} - client_info* client_ptr; - uint64_t v6_addr; +void IPACM_LanToLan_Iface::add_client_rt_rule_for_new_iface() +{ + list<client_info>::iterator it; + ipa_hdr_l2_type peer_l2_type; + peer_iface_info &peer = m_peer_iface_info.front(); - if(data->iptype == IPA_IP_v4) + peer_l2_type = peer.peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type; + if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 1) { - if(client_info_v4_.count(data->ipv4_addr) == 0)//if not found the client, return + for(it = m_client_info.begin(); it != m_client_info.end(); it++) { - IPACMERR("The client is not found the client, return.\n"); - return; + add_client_rt_rule(&peer, &(*it)); } - IPACMDBG_H("The client is found.\n"); - client_info& client = client_info_v4_[data->ipv4_addr]; - client_ptr = &client; - } - else - { - memcpy(&v6_addr, &(data->ipv6_addr[2]), sizeof(uint64_t)); - if(client_info_v6_.count(v6_addr) == 0) //if not found the client, insert it in table - { - IPACMERR("The client is not found the client, return.\n"); - return; - } - IPACMDBG_H("The client is found.\n"); - client_info& client = client_info_v6_[v6_addr]; - client_ptr = &client; } - if(remove_flt_rules(data->iptype, client_ptr) == IPACM_FAILURE) - { - IPACMERR("Failed to remove flt rules when power save.\n"); - return; - } - client_ptr->is_active = false; - client_ptr->is_powersave = true; return; } -void IPACM_LanToLan::handle_new_lan2lan_connection(ipacm_event_connection* data) +void IPACM_LanToLan_Iface::add_client_rt_rule(peer_iface_info *peer_info, client_info *client) { - IPACMDBG_H("New lan2lan connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", data->iptype, data->src_ipv4_addr, data->dst_ipv4_addr); - IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", data->src_ipv6_addr[0], data->src_ipv6_addr[1], data->src_ipv6_addr[2], - data->src_ipv6_addr[3], data->dst_ipv6_addr[0], data->dst_ipv6_addr[1], data->dst_ipv6_addr[2], data->dst_ipv6_addr[3]); + int i, num_rt_rule; + uint32_t rt_rule_hdl[MAX_NUM_PROP]; + ipa_hdr_l2_type peer_l2_hdr_type; - client_info* src_client_ptr; - client_info* dst_client_ptr; + peer_l2_hdr_type = peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type; - if(data->iptype == IPA_IP_v4) + /* if the peer info is not for intra interface communication */ + if(peer_info->peer != this) { - if(client_info_v4_.count(data->src_ipv4_addr) == 0 || client_info_v4_.count(data->dst_ipv4_addr) == 0) + IPACMDBG_H("This is for inter interface communication.\n"); + + m_p_iface->eth_bridge_add_rt_rule(client->mac_addr, peer_info->rt_tbl_name_for_rt[IPA_IP_v4], hdr_proc_ctx_for_inter_interface[peer_l2_hdr_type], + peer_l2_hdr_type, IPA_IP_v4, rt_rule_hdl, &num_rt_rule); + + client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4] = num_rt_rule; + IPACMDBG_H("Number of IPv4 routing rule is %d.\n", num_rt_rule); + for(i=0; i<num_rt_rule; i++) { - IPACMERR("Either source or destination is not in table.\n"); - return; + IPACMDBG_H("Routing rule %d handle %d\n", i, rt_rule_hdl[i]); + client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4][i] = rt_rule_hdl[i]; } - client_info& src_client = client_info_v4_[data->src_ipv4_addr]; - src_client_ptr = &src_client; - client_info& dst_client = client_info_v4_[data->dst_ipv4_addr]; - dst_client_ptr = &dst_client; - } - else //ipv6 case - { - uint64_t src_ipv6_addr; - uint64_t dst_ipv6_addr; - memcpy(&src_ipv6_addr, &(data->src_ipv6_addr[2]), sizeof(uint64_t)); - memcpy(&dst_ipv6_addr, &(data->dst_ipv6_addr[2]), sizeof(uint64_t)); - if(client_info_v6_.count(src_ipv6_addr) == 0 || client_info_v6_.count(dst_ipv6_addr) == 0) + m_p_iface->eth_bridge_add_rt_rule(client->mac_addr, peer_info->rt_tbl_name_for_rt[IPA_IP_v6], hdr_proc_ctx_for_inter_interface[peer_l2_hdr_type], + peer_l2_hdr_type, IPA_IP_v6, rt_rule_hdl, &num_rt_rule); + + client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6] = num_rt_rule; + IPACMDBG_H("Number of IPv6 routing rule is %d.\n", num_rt_rule); + for(i=0; i<num_rt_rule; i++) { - IPACMERR("Either source or destination is not in table.\n"); - return; + IPACMDBG_H("Routing rule %d handle %d\n", i, rt_rule_hdl[i]); + client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6][i] = rt_rule_hdl[i]; } - client_info& src_client = client_info_v6_[src_ipv6_addr]; - src_client_ptr = &src_client; - client_info& dst_client = client_info_v6_[dst_ipv6_addr]; - dst_client_ptr = &dst_client; } - - IPACMDBG_H("Both src and dst are already in table.\n"); - bool is_first_connection; - is_first_connection = add_connection(src_client_ptr, dst_client_ptr); - - if(is_first_connection && src_client_ptr->is_active && dst_client_ptr->is_active) + else { - IPACMDBG_H("This is first connection, add offload links.\n"); + IPACMDBG_H("This is for intra interface communication.\n"); + m_p_iface->eth_bridge_add_rt_rule(client->mac_addr, peer_info->rt_tbl_name_for_rt[IPA_IP_v4], hdr_proc_ctx_for_intra_interface, + peer_l2_hdr_type, IPA_IP_v4, rt_rule_hdl, &num_rt_rule); - if(add_offload_link(data->iptype, src_client_ptr, dst_client_ptr) == IPACM_FAILURE) + client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4] = num_rt_rule; + IPACMDBG_H("Number of IPv4 routing rule is %d.\n", num_rt_rule); + for(i=0; i<num_rt_rule; i++) { - IPACMERR("Failed to add offload link for src->dst direction.\n"); - return; - } - if(add_offload_link(data->iptype, dst_client_ptr, src_client_ptr) == IPACM_FAILURE) - { - IPACMERR("Failed to add offload link for dst->src direction.\n"); - return; + IPACMDBG_H("Routing rule %d handle %d\n", i, rt_rule_hdl[i]); + client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][i] = rt_rule_hdl[i]; } - if(data->iptype == IPA_IP_v4) - { - num_offload_pair_v4_ ++; - IPACMDBG_H("Added offload links, now num_offload_pair_v4_: %d\n", num_offload_pair_v4_); - } - else + m_p_iface->eth_bridge_add_rt_rule(client->mac_addr, peer_info->rt_tbl_name_for_rt[IPA_IP_v6], hdr_proc_ctx_for_intra_interface, + peer_l2_hdr_type, IPA_IP_v6, rt_rule_hdl, &num_rt_rule); + + client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6] = num_rt_rule; + IPACMDBG_H("Number of IPv6 routing rule is %d.\n", num_rt_rule); + for(i=0; i<num_rt_rule; i++) { - num_offload_pair_v6_ ++; - IPACMDBG_H("Added offload links, now num_offload_pair_v6_: %d\n", num_offload_pair_v6_); + IPACMDBG_H("Routing rule %d handle %d\n", i, rt_rule_hdl[i]); + client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][i] = rt_rule_hdl[i]; } } + return; } -//If need to insert an entry in peer list, return true, otherwise return false -bool IPACM_LanToLan::add_connection(client_info* src_client, client_info* dst_client) +void IPACM_LanToLan_Iface::add_all_inter_interface_client_flt_rule(ipa_ip_type iptype) { - if(src_client == NULL || dst_client == NULL) - { - IPACMERR("Either source or dest client is NULL.\n"); - return false; - } - - peer_info_list::iterator it; - peer_info new_peer; - bool ret = false; + list<peer_iface_info>::iterator it_iface; + list<client_info>::iterator it_client; - for(it = src_client->peer.begin(); it != src_client->peer.end(); it++) + for(it_iface = m_peer_iface_info.begin(); it_iface != m_peer_iface_info.end(); it_iface++) { - if(it->peer_pointer == dst_client) + IPACMDBG_H("Add flt rules for clients of interface %s.\n", it_iface->peer->get_iface_pointer()->dev_name); + for(it_client = it_iface->peer->m_client_info.begin(); it_client != it_iface->peer->m_client_info.end(); it_client++) { - it->num_connection++; - IPACMDBG_H("Find dst client entry in peer list, connection count: %d\n", it->num_connection); - break; + add_client_flt_rule(&(*it_iface), &(*it_client), iptype); } } - if(it == src_client->peer.end()) + return; +} + +void IPACM_LanToLan_Iface::add_all_intra_interface_client_flt_rule(ipa_ip_type iptype) +{ + list<client_info>::iterator it_client; + + IPACMDBG_H("Add flt rules for own clients.\n"); + for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) { - IPACMDBG_H("Not finding dst client entry, insert a new one in peer list.\n"); - new_peer.peer_pointer = dst_client; - new_peer.num_connection = 1; - src_client->peer.push_back(new_peer); - ret = true; + add_client_flt_rule(&m_intra_interface_info, &(*it_client), iptype); } - for(it = dst_client->peer.begin(); it != dst_client->peer.end(); it++) + return; +} + +void IPACM_LanToLan_Iface::add_one_client_flt_rule(IPACM_LanToLan_Iface *peer_iface, client_info *client) +{ + list<peer_iface_info>::iterator it; + + for(it = m_peer_iface_info.begin(); it != m_peer_iface_info.end(); it++) { - if(it->peer_pointer == src_client) + if(it->peer == peer_iface) { - it->num_connection++; - IPACMDBG_H("Find dst client entry in peer list, connection count: %d\n", it->num_connection); + IPACMDBG_H("Found the peer iface info.\n"); + if(m_is_ip_addr_assigned[IPA_IP_v4]) + { + add_client_flt_rule(&(*it), client, IPA_IP_v4); + } + if(m_is_ip_addr_assigned[IPA_IP_v6]) + { + add_client_flt_rule(&(*it), client, IPA_IP_v6); + } + break; } } - if(it == dst_client->peer.end()) - { - IPACMDBG_H("Not finding src client entry, insert a new one in peer list.\n"); - new_peer.peer_pointer = src_client; - new_peer.num_connection = 1; - dst_client->peer.push_back(new_peer); - ret = true; - } - return ret; + return; } -void IPACM_LanToLan::handle_del_lan2lan_connection(ipacm_event_connection* data) +void IPACM_LanToLan_Iface::add_client_flt_rule(peer_iface_info *peer, client_info *client, ipa_ip_type iptype) { - IPACMDBG_H("Del lan2lan connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", data->iptype, data->src_ipv4_addr, data->dst_ipv4_addr); - IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", data->src_ipv6_addr[0], data->src_ipv6_addr[1], data->src_ipv6_addr[2], - data->src_ipv6_addr[3], data->dst_ipv6_addr[0], data->dst_ipv6_addr[1], data->dst_ipv6_addr[2], data->dst_ipv6_addr[3]); + list<flt_rule_info>::iterator it_flt; + uint32_t flt_rule_hdl; + flt_rule_info new_flt_info; + ipa_ioc_get_rt_tbl rt_tbl; - bool res; - uint64_t src_ipv6_addr, dst_ipv6_addr; - client_info* src_client_ptr; - client_info* dst_client_ptr; + rt_tbl.ip = iptype; + memcpy(rt_tbl.name, peer->rt_tbl_name_for_flt[iptype], sizeof(rt_tbl.name)); + IPACMDBG_H("This flt rule points to rt tbl %s.\n", rt_tbl.name); - if(data->iptype == IPA_IP_v4) - { - if(client_info_v4_.count(data->src_ipv4_addr) == 0 - || client_info_v4_.count(data->dst_ipv4_addr) == 0) //if not found the client - { - IPACMDBG_H("Not found either source or dest client, return.\n"); - return; - } - client_info& src_client = client_info_v4_[data->src_ipv4_addr]; - client_info& dst_client = client_info_v4_[data->dst_ipv4_addr]; - src_client_ptr = &src_client; - dst_client_ptr = &dst_client; - } - else + if(IPACM_Iface::m_routing.GetRoutingTable(&rt_tbl) == false) { - memcpy(&src_ipv6_addr, &(data->src_ipv6_addr[2]), sizeof(uint64_t)); - memcpy(&dst_ipv6_addr, &(data->dst_ipv6_addr[2]), sizeof(uint64_t)); - if(client_info_v6_.count(src_ipv6_addr) == 0 - || client_info_v6_.count(dst_ipv6_addr) == 0)//if not found the client - { - IPACMDBG_H("Not found either source or dest client, return.\n"); - return; - } - client_info& src_client = client_info_v6_[src_ipv6_addr]; - client_info& dst_client = client_info_v6_[dst_ipv6_addr]; - src_client_ptr = &src_client; - dst_client_ptr = &dst_client; + IPACMERR("Failed to get routing table.\n"); + return; } - res = remove_connection(src_client_ptr, dst_client_ptr); + m_p_iface->eth_bridge_add_flt_rule(client->mac_addr, rt_tbl.hdl, + iptype, &flt_rule_hdl); + IPACMDBG_H("Installed flt rule for IP type %d: handle %d\n", iptype, flt_rule_hdl); - if(res && src_client_ptr->is_active && dst_client_ptr->is_active) - { - IPACMDBG_H("Erase link info for both src and dst entries.\n"); - erase_offload_link(data->iptype, src_client_ptr, dst_client_ptr); - } - else + for(it_flt = peer->flt_rule.begin(); it_flt != peer->flt_rule.end(); it_flt++) { - if(res && src_client_ptr->is_powersave && (dst_client_ptr->is_active || dst_client_ptr->is_powersave)) - { - IPACMDBG_H("Erase link info for both src and dst entries due to src powersave.\n"); - erase_offload_link(data->iptype, src_client_ptr, dst_client_ptr); - } - if(res && dst_client_ptr->is_powersave && (src_client_ptr->is_active || src_client_ptr->is_powersave)) + if(it_flt->p_client == client) //the client is already in the flt info list { - IPACMDBG_H("Erase link info for both src and dst entries due to dst powersave.\n"); - erase_offload_link(data->iptype, dst_client_ptr, src_client_ptr); + IPACMDBG_H("The client is found in flt info list.\n"); + it_flt->flt_rule_hdl[iptype] = flt_rule_hdl; + break; } } - //if the src client is not active and not powersave mode, if peer list is empty, remove client entry - if(res && src_client_ptr->is_active == false && src_client_ptr->is_powersave == false && src_client_ptr->peer.size() == 0) + if(it_flt == peer->flt_rule.end()) //the client is not in the flt info list { - IPACMDBG_H("Peer list of src is empty, remove src entry.\n"); - if(data->iptype == IPA_IP_v4) - { - client_info_v4_.erase(data->src_ipv4_addr); - } - else - { - client_info_v6_.erase(src_ipv6_addr); - } - } + IPACMDBG_H("The client is not found in flt info list, insert a new one.\n"); + memset(&new_flt_info, 0, sizeof(new_flt_info)); + new_flt_info.p_client = client; + new_flt_info.flt_rule_hdl[iptype] = flt_rule_hdl; - //if the dst client is not active and not powersave mode, if peer list is empty, remove client entry - if(res && dst_client_ptr->is_active == false && dst_client_ptr->is_powersave == false && dst_client_ptr->peer.size() == 0) - { - IPACMDBG_H("Peer list of dst is empty, remove dst entry.\n"); - if(data->iptype == IPA_IP_v4) - { - client_info_v4_.erase(data->dst_ipv4_addr); - } - else - { - client_info_v6_.erase(dst_ipv6_addr); - } + peer->flt_rule.push_front(new_flt_info); } + return; } -//If need to remove an entry in peer list, return true, otherwise return false -bool IPACM_LanToLan::remove_connection(client_info* src_client, client_info* dst_client) +void IPACM_LanToLan_Iface::del_one_client_flt_rule(IPACM_LanToLan_Iface *peer_iface, client_info *client) { - if(src_client == NULL || dst_client == NULL) - { - IPACMERR("Either source or dest client is NULL.\n"); - return false; - } - - peer_info_list::iterator it; - bool ret = false; + list<peer_iface_info>::iterator it; - for(it = src_client->peer.begin(); it != src_client->peer.end(); it++) + for(it = m_peer_iface_info.begin(); it != m_peer_iface_info.end(); it++) { - if(it->peer_pointer == dst_client) + if(it->peer == peer_iface) { - it->num_connection--; - IPACMDBG_H("Find dst client entry in src peer list, connection count: %d\n", it->num_connection); - if(it->num_connection == 0) - { - IPACMDBG_H("Need to remove dst entry in src peer list.\n"); - ret = true; - } + IPACMDBG_H("Found the peer iface info.\n"); + del_client_flt_rule(&(*it), client); break; } } - if(ret == true) - { - src_client->peer.erase(it); - } + return; +} - ret = false; - for(it = dst_client->peer.begin(); it != dst_client->peer.end(); it++) +void IPACM_LanToLan_Iface::del_client_flt_rule(peer_iface_info *peer, client_info *client) +{ + list<flt_rule_info>::iterator it_flt; + + for(it_flt = peer->flt_rule.begin(); it_flt != peer->flt_rule.end(); it_flt++) { - if(it->peer_pointer == src_client) + if(it_flt->p_client == client) //found the client in flt info list { - it->num_connection--; - IPACMDBG_H("Find src client entry in dst peer list, connection count: %d\n", it->num_connection); - if(it->num_connection == 0) + IPACMDBG_H("Found the client in flt info list.\n"); + if(m_is_ip_addr_assigned[IPA_IP_v4]) + { + m_p_iface->eth_bridge_del_flt_rule(it_flt->flt_rule_hdl[IPA_IP_v4], IPA_IP_v4); + IPACMDBG_H("IPv4 flt rule %d is deleted.\n", it_flt->flt_rule_hdl[IPA_IP_v4]); + } + if(m_is_ip_addr_assigned[IPA_IP_v6]) { - IPACMDBG_H("Need to remove src entry in dst peer list.\n"); - ret = true; + m_p_iface->eth_bridge_del_flt_rule(it_flt->flt_rule_hdl[IPA_IP_v6], IPA_IP_v6); + IPACMDBG_H("IPv6 flt rule %d is deleted.\n", it_flt->flt_rule_hdl[IPA_IP_v6]); } + + peer->flt_rule.erase(it_flt); break; } } - if(ret == true) - { - dst_client->peer.erase(it); - } - return ret; + return; } -void IPACM_LanToLan::erase_offload_link(ipa_ip_type iptype, client_info* src_client, client_info* dst_client) +void IPACM_LanToLan_Iface::del_client_rt_rule(peer_iface_info *peer, client_info *client) { - if(src_client == NULL || dst_client == NULL) - { - IPACMERR("Either source or dest client is NULL.\n"); - return; - } + ipa_hdr_l2_type peer_l2_hdr_type; + int i, num_rules; - offload_link_info_list::iterator it; - int res_src = IPACM_FAILURE, res_dst = IPACM_FAILURE; - - for(it = src_client->link.begin(); it != src_client->link.end(); it++) + peer_l2_hdr_type = peer->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type; + /* if the peer info is not for intra interface communication */ + if(peer->peer != this) { - if(it->peer_pointer == dst_client) + IPACMDBG_H("Delete routing rules for inter interface communication.\n"); + + num_rules = client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4]; + for(i = 0; i < num_rules; i++) { - res_src = IPACM_SUCCESS; - IPACMDBG_H("Find dst client entry in src link list\n"); - res_src = del_offload_link(iptype, src_client->p_iface, dst_client->p_iface, &(*it)); - src_client->link.erase(it); - break; + m_p_iface->eth_bridge_del_rt_rule(client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4][i], IPA_IP_v4); + IPACMDBG_H("IPv4 rt rule %d is deleted.\n", client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4][i]); } - } + client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4] = 0; - for(it = dst_client->link.begin(); it != dst_client->link.end(); it++) - { - if(it->peer_pointer == src_client) + num_rules = client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6]; + for(i = 0; i < num_rules; i++) { - res_dst = IPACM_SUCCESS; - IPACMDBG_H("Find src client entry in dst link list\n"); - res_dst = del_offload_link(iptype, dst_client->p_iface, src_client->p_iface, &(*it)); - dst_client->link.erase(it); - break; + m_p_iface->eth_bridge_del_rt_rule(client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6][i], IPA_IP_v6); + IPACMDBG_H("IPv6 rt rule %d is deleted.\n", client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6][i]); } + client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6] = 0; } - - if(res_src == IPACM_SUCCESS && res_dst == IPACM_SUCCESS) + else { - if(iptype == IPA_IP_v4) + IPACMDBG_H("Delete routing rules for intra interface communication.\n"); + num_rules = client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]; + for(i = 0; i < num_rules; i++) { - num_offload_pair_v4_ --; - IPACMDBG_H("Decrease num of v4 offload pairs to %d\n", num_offload_pair_v4_); + m_p_iface->eth_bridge_del_rt_rule(client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][i], IPA_IP_v4); + IPACMDBG_H("IPv4 rt rule %d is deleted.\n", client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][i]); } - else + client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4] = 0; + + num_rules = client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]; + for(i = 0; i < num_rules; i++) { - num_offload_pair_v6_ --; - IPACMDBG_H("Decrease num of v6 offload pairs to %d\n", num_offload_pair_v6_); + m_p_iface->eth_bridge_del_rt_rule(client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][i], IPA_IP_v6); + IPACMDBG_H("IPv6 rt rule %d is deleted.\n", client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][i]); } + client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6] = 0; } + return; } -void IPACM_LanToLan::generate_new_connection(ipa_ip_type iptype, client_info* client) +void IPACM_LanToLan_Iface::handle_down_event() { -#ifndef CT_OPT - if(client == NULL) - { - IPACMERR("Client is NULL.\n"); - return; - } - - IPACMDBG_H("Generate new connection events for IP type %d\n", iptype); - - int num = 0; - ipacm_cmd_q_data evt; - ipacm_event_connection* new_conn; - ipacm_iface_type client_type, peer_type; - client_type = IPACM_Iface::ipacmcfg->iface_table[client->p_iface->ipa_if_num].if_cat; - - IPACMDBG_H("Client's iface type is %d.\n", client_type); - - if(iptype == IPA_IP_v4) - { - client_table_v4::iterator it; - for(it = client_info_v4_.begin(); it != client_info_v4_.end(); it++) - { - peer_type = IPACM_Iface::ipacmcfg->iface_table[it->second.p_iface->ipa_if_num].if_cat; - if(peer_type != client_type && it->second.is_active == true) - { - IPACMDBG_H("Find a qualified peer to generate new_conn event.\n"); - IPACMDBG_H("Peer's iface type is %d.\n", peer_type); - new_conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection)); - if(new_conn == NULL) - { - IPACMERR("Failed to allocate memory for new_connection event.\n"); - return; - } - memset(new_conn, 0, sizeof(ipacm_event_connection)); - new_conn->iptype = IPA_IP_v4; - new_conn->src_ipv4_addr = client->ip.ipv4_addr; - new_conn->dst_ipv4_addr = it->second.ip.ipv4_addr; - - memset(&evt, 0, sizeof(evt)); - evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION; - evt.evt_data = (void*)new_conn; - IPACM_EvtDispatcher::PostEvt(&evt); - num++; - } - } - } - else if(iptype == IPA_IP_v6) - { - client_table_v6::iterator it; - for(it = client_info_v6_.begin(); it != client_info_v6_.end(); it++) - { - peer_type = IPACM_Iface::ipacmcfg->iface_table[it->second.p_iface->ipa_if_num].if_cat; - if(peer_type != client_type && it->second.is_active == true) + list<IPACM_LanToLan_Iface>::iterator it_other_iface; + list<peer_iface_info>::iterator it_own_peer_info, it_other_iface_peer_info; + IPACM_LanToLan_Iface *other_iface; + + /* clear inter-interface rules */ + if(m_support_inter_iface_offload) + { + for(it_own_peer_info = m_peer_iface_info.begin(); it_own_peer_info != m_peer_iface_info.end(); + it_own_peer_info++) + { + /* decrement reference count of peer l2 header type on both interfaces*/ + decrement_ref_cnt_peer_l2_hdr_type(it_own_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type); + it_own_peer_info->peer->decrement_ref_cnt_peer_l2_hdr_type(m_p_iface->tx_prop->tx[0].hdr_l2_type); + + /* first clear all flt rule on target interface */ + IPACMDBG_H("Clear all flt rule on target interface.\n"); + clear_all_flt_rule_for_one_peer_iface(&(*it_own_peer_info)); + + other_iface = it_own_peer_info->peer; + /* then clear all flt/rt rule and hdr proc ctx for target interface on peer interfaces */ + IPACMDBG_H("Clear all flt/rt rules and hdr proc ctx for target interface on peer interfaces %s.\n", + it_own_peer_info->peer->get_iface_pointer()->dev_name); + for(it_other_iface_peer_info = other_iface->m_peer_iface_info.begin(); + it_other_iface_peer_info != other_iface->m_peer_iface_info.end(); + it_other_iface_peer_info++) { - IPACMDBG_H("Find a qualified peer to generate new_conn event.\n"); - IPACMDBG_H("Peer's iface type is %d.\n", peer_type); - new_conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection)); - if(new_conn == NULL) + if(it_other_iface_peer_info->peer == this) //found myself in other iface's peer info list { - IPACMERR("Failed to allocate memory for new_connection event.\n"); - return; + IPACMDBG_H("Found the right peer info on other iface.\n"); + other_iface->clear_all_flt_rule_for_one_peer_iface(&(*it_other_iface_peer_info)); + other_iface->clear_all_rt_rule_for_one_peer_iface(&(*it_other_iface_peer_info)); + /* remove the peer info from the list */ + other_iface->m_peer_iface_info.erase(it_other_iface_peer_info); + other_iface->del_hdr_proc_ctx(m_p_iface->tx_prop->tx[0].hdr_l2_type); + break; } - memset(new_conn, 0, sizeof(ipacm_event_connection)); - new_conn->iptype = IPA_IP_v6; - memcpy(new_conn->src_ipv6_addr, client->ip.ipv6_addr, sizeof(new_conn->src_ipv6_addr)); - memcpy(new_conn->dst_ipv6_addr, it->second.ip.ipv6_addr, sizeof(new_conn->dst_ipv6_addr)); - - memset(&evt, 0, sizeof(evt)); - evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION; - evt.evt_data = (void*)new_conn; - IPACM_EvtDispatcher::PostEvt(&evt); - num++; } + + /* then clear rt rule and hdr proc ctx and release rt table on target interface */ + IPACMDBG_H("Clear rt rules and hdr proc ctx and release rt table on target interface.\n"); + clear_all_rt_rule_for_one_peer_iface(&(*it_own_peer_info)); + del_hdr_proc_ctx(it_own_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type); } + m_peer_iface_info.clear(); } - else + + /* clear intra interface rules */ + if(m_support_intra_iface_offload) { - IPACMERR("IP type is not expected.\n"); + IPACMDBG_H("Clear intra interface flt/rt rules and hdr proc ctx, release rt tables.\n"); + clear_all_flt_rule_for_one_peer_iface(&m_intra_interface_info); + clear_all_rt_rule_for_one_peer_iface(&m_intra_interface_info); + m_p_iface->eth_bridge_del_hdr_proc_ctx(hdr_proc_ctx_for_intra_interface); + IPACMDBG_H("Hdr proc ctx with hdl %d is deleted.\n", hdr_proc_ctx_for_intra_interface); } - IPACMDBG_H("Generate %d new connection events in total.\n", num); -#endif + + /* then clear the client info list */ + m_client_info.clear(); + return; } -void IPACM_LanToLan::handle_client_power_recover(ipacm_event_lan_client* data) +void IPACM_LanToLan_Iface::clear_all_flt_rule_for_one_peer_iface(peer_iface_info *peer) { - if(data == NULL) - { - IPACMERR("No client info is found.\n"); - return; - } - if(data->mac_addr == NULL || data->ipv6_addr == NULL || data->p_iface == NULL) - { - IPACMERR("Event data is not populated properly.\n"); - return; - } - if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6) - { - IPACMERR("IP type is not expected: %d\n", data->iptype); - return; - } - - IPACMDBG_H("New client info: iface %s, iptype: %d, mac: 0x%02x%02x%02x%02x%02x%02x, v4_addr: 0x%08x, v6_addr: 0x%08x%08x%08x%08x \n", - data->p_iface->dev_name, data->iptype, - data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], - data->ipv4_addr, data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); + list<flt_rule_info>::iterator it; - client_info* client_ptr; - if(data->iptype == IPA_IP_v4) + for(it = peer->flt_rule.begin(); it != peer->flt_rule.end(); it++) { - if(client_info_v4_.count(data->ipv4_addr) == 0) + if(m_is_ip_addr_assigned[IPA_IP_v4]) { - IPACMERR("Client is not found.\n"); - return; + m_p_iface->eth_bridge_del_flt_rule(it->flt_rule_hdl[IPA_IP_v4], IPA_IP_v4); + IPACMDBG_H("IPv4 flt rule %d is deleted.\n", it->flt_rule_hdl[IPA_IP_v4]); } - client_info& client = client_info_v4_[data->ipv4_addr]; - client_ptr = &client; - } - else - { - uint64_t v6_addr; - memcpy(&v6_addr, &(data->ipv6_addr[2]), sizeof(uint64_t)); - if(client_info_v6_.count(v6_addr) == 0) + if(m_is_ip_addr_assigned[IPA_IP_v6]) { - IPACMERR("Client is not found.\n"); - return; + m_p_iface->eth_bridge_del_flt_rule(it->flt_rule_hdl[IPA_IP_v6], IPA_IP_v6); + IPACMDBG_H("IPv6 flt rule %d is deleted.\n", it->flt_rule_hdl[IPA_IP_v6]); } - client_info& client = client_info_v6_[v6_addr]; - client_ptr = &client; } + peer->flt_rule.clear(); + return; +} - if(client_ptr->is_active == true || client_ptr->is_powersave != true) //the client is in wrong state - { - IPACMERR("The client is in wrong state: active %d, powersave %d.\n", client_ptr->is_active, client_ptr->is_powersave); - return; - } - else +void IPACM_LanToLan_Iface::clear_all_rt_rule_for_one_peer_iface(peer_iface_info *peer) +{ + list<client_info>::iterator it; + ipa_hdr_l2_type peer_l2_type; + + peer_l2_type = peer->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type; + if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 0) { - if(add_flt_rules(data->iptype, client_ptr) == IPACM_FAILURE) + for(it = m_client_info.begin(); it != m_client_info.end(); it++) { - IPACMERR("Failed to add back flt rules when power recovery.\n"); - return; + del_client_rt_rule(peer, &(*it)); } - client_ptr->is_active = true; - client_ptr->is_powersave = false; - - check_potential_link(data->iptype, client_ptr); - generate_new_connection(data->iptype, client_ptr); } - IPACMDBG_H("There are %d clients in v4 table and %d clients in v6 table.\n", client_info_v4_.size(), client_info_v6_.size()); + return; } -//This function is called when power save: remove filtering rules only -int IPACM_LanToLan::remove_flt_rules(ipa_ip_type iptype, client_info* client) +void IPACM_LanToLan_Iface::handle_wlan_scc_mcc_switch() { - if(client == NULL) - { - IPACMERR("No client info is found.\n"); - return IPACM_FAILURE; - } - - bool err_flag; - offload_link_info_list::iterator client_it; - offload_link_info_list::iterator peer_it; - client_info* peer; + list<peer_iface_info>::iterator it_peer_info; + list<client_info>::iterator it_client; + ipa_hdr_l2_type peer_l2_hdr_type; + bool flag[IPA_HDR_L2_MAX]; + int i; - for(client_it = client->link.begin(); client_it != client->link.end(); client_it++) + /* modify inter-interface routing rules */ + if(m_support_inter_iface_offload) { - if(client->p_iface->del_lan2lan_flt_rule(iptype, client_it->flt_rule_hdl) == IPACM_FAILURE) + IPACMDBG_H("Modify rt rules for peer interfaces.\n"); + memset(flag, 0, sizeof(flag)); + for(it_peer_info = m_peer_iface_info.begin(); it_peer_info != m_peer_iface_info.end(); it_peer_info++) { - IPACMERR("Failed to delete client's filtering rule.\n"); - } - - err_flag = true; - peer = client_it->peer_pointer; - for(peer_it = peer->link.begin(); peer_it != peer->link.end(); peer_it++) - { - if(peer_it->peer_pointer == client) + peer_l2_hdr_type = it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type; + if(flag[peer_l2_hdr_type] == false) { - if(peer->p_iface->del_lan2lan_flt_rule(iptype, peer_it->flt_rule_hdl) == IPACM_FAILURE) + flag[peer_l2_hdr_type] = true; + for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) { - IPACMERR("Failed to delete peer's offload link.\n"); + m_p_iface->eth_bridge_modify_rt_rule(it_client->mac_addr, hdr_proc_ctx_for_inter_interface[peer_l2_hdr_type], + peer_l2_hdr_type, IPA_IP_v4, it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4], + it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4]); + IPACMDBG_H("The following IPv4 routing rules are modified:\n"); + for(i = 0; i < it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4]; i++) + { + IPACMDBG_H("%d\n", it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4][i]); + } + + m_p_iface->eth_bridge_modify_rt_rule(it_client->mac_addr, hdr_proc_ctx_for_inter_interface[peer_l2_hdr_type], + peer_l2_hdr_type, IPA_IP_v6, it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6], + it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6]); + IPACMDBG_H("The following IPv6 routing rules are modified:\n"); + for(i = 0; i < it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6]; i++) + { + IPACMDBG_H("%d\n", it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6][i]); + } } - err_flag = false; - break; } } - if(err_flag) - { - IPACMERR("Unable to find corresponding offload link in peer's entry.\n"); - return IPACM_FAILURE; - } } - return IPACM_SUCCESS; -} - -int IPACM_LanToLan::add_flt_rules(ipa_ip_type iptype, client_info* client) -{ - if(client == NULL) - { - IPACMERR("No client info is found.\n"); - return IPACM_FAILURE; - } - - bool err_flag; - offload_link_info_list::iterator client_it; - offload_link_info_list::iterator peer_it; - client_info* peer; - for(client_it = client->link.begin(); client_it != client->link.end(); client_it++) + /* modify routing rules for intra-interface communication */ + IPACMDBG_H("Modify rt rules for intra-interface communication.\n"); + if(m_support_intra_iface_offload) { - peer = client_it->peer_pointer; - if(client->p_iface->add_lan2lan_flt_rule(iptype, client->ip.ipv4_addr, peer->ip.ipv4_addr, - client->ip.ipv6_addr, peer->ip.ipv6_addr, &(client_it->flt_rule_hdl)) == IPACM_FAILURE) + for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) { - IPACMERR("Failed to add client's filtering rule.\n"); - return IPACM_FAILURE; - } + m_p_iface->eth_bridge_modify_rt_rule(it_client->mac_addr, hdr_proc_ctx_for_intra_interface, + m_p_iface->tx_prop->tx[0].hdr_l2_type, IPA_IP_v4, it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4], + it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]); + IPACMDBG_H("The following IPv4 routing rules are modified:\n"); + for(i = 0; i < it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]; i++) + { + IPACMDBG_H("%d\n", it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][i]); + } - err_flag = true; - for(peer_it = peer->link.begin(); peer_it != peer->link.end(); peer_it++) - { - if(peer_it->peer_pointer == client) + m_p_iface->eth_bridge_modify_rt_rule(it_client->mac_addr, hdr_proc_ctx_for_intra_interface, + m_p_iface->tx_prop->tx[0].hdr_l2_type, IPA_IP_v6, it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6], + it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]); + IPACMDBG_H("The following IPv6 routing rules are modified:\n"); + for(i = 0; i < it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]; i++) { - if(peer->p_iface->add_lan2lan_flt_rule(iptype, peer->ip.ipv4_addr, client->ip.ipv4_addr, - peer->ip.ipv6_addr, client->ip.ipv6_addr, &(peer_it->flt_rule_hdl)) == IPACM_FAILURE) - { - IPACMERR("Failed to delete peer's offload link.\n"); - return IPACM_FAILURE; - } - err_flag = false; - break; + IPACMDBG_H("%d\n", it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][i]); } } - if(err_flag) - { - IPACMERR("Unable to find corresponding offload link in peer's entry.\n"); - return IPACM_FAILURE; - } } - return IPACM_SUCCESS; + + return; } -void IPACM_LanToLan::handle_new_connection(ipacm_event_connection* new_conn) +void IPACM_LanToLan_Iface::handle_intra_interface_info() { -#ifdef CT_OPT - if(new_conn == NULL) - { - IPACMERR("No connection info is found.\n"); - return; - } - if(new_conn->iptype != IPA_IP_v4 && new_conn->iptype != IPA_IP_v6) - { - IPACMERR("IP type is not expected: %d.\n", new_conn->iptype); - return; - } + uint32_t hdr_proc_ctx_hdl; - IPACMDBG_H("New connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", new_conn->iptype, new_conn->src_ipv4_addr, new_conn->dst_ipv4_addr); - IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", new_conn->src_ipv6_addr[0], new_conn->src_ipv6_addr[1], new_conn->src_ipv6_addr[2], - new_conn->src_ipv6_addr[3], new_conn->dst_ipv6_addr[0], new_conn->dst_ipv6_addr[1], new_conn->dst_ipv6_addr[2], new_conn->dst_ipv6_addr[3]); + m_intra_interface_info.peer = this; - if(is_lan2lan_connection(new_conn) == false) - { - IPACMDBG_H("The connection is not lan2lan connection.\n"); - cache_new_connection(new_conn); - return; - } + snprintf(m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX, + "eth_v4_intra_interface"); + IPACMDBG_H("IPv4 routing table for flt name: %s\n", m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4]); + snprintf(m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX, + "eth_v6_intra_interface"); + IPACMDBG_H("IPv6 routing table for flt name: %s\n", m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v6]); - ipacm_cmd_q_data evt; - ipacm_event_connection* conn; + memcpy(m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v4], m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4], + IPA_RESOURCE_NAME_MAX); + IPACMDBG_H("IPv4 routing table for rt name: %s\n", m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v4]); + memcpy(m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v6], m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v6], + IPA_RESOURCE_NAME_MAX); + IPACMDBG_H("IPv6 routing table for rt name: %s\n", m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v6]); - conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection)); - if(conn == NULL) - { - IPACMERR("Failed to allocate memory for new_connection event.\n"); - return; - } - memcpy(conn, new_conn, sizeof(ipacm_event_connection)); + m_p_iface->eth_bridge_add_hdr_proc_ctx(m_p_iface->tx_prop->tx[0].hdr_l2_type, + &hdr_proc_ctx_hdl); + hdr_proc_ctx_for_intra_interface = hdr_proc_ctx_hdl; + IPACMDBG_H("Hdr proc ctx for intra-interface communication: hdl %d\n", hdr_proc_ctx_hdl); + + return; +} + +void IPACM_LanToLan_Iface::handle_new_iface_up(char rt_tbl_name_for_flt[][IPA_RESOURCE_NAME_MAX], char rt_tbl_name_for_rt[][IPA_RESOURCE_NAME_MAX], + IPACM_LanToLan_Iface *peer_iface) +{ + peer_iface_info new_peer; + ipa_hdr_l2_type peer_l2_hdr_type; + + new_peer.peer = peer_iface; + memcpy(new_peer.rt_tbl_name_for_rt[IPA_IP_v4], rt_tbl_name_for_rt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX); + memcpy(new_peer.rt_tbl_name_for_rt[IPA_IP_v6], rt_tbl_name_for_rt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX); + memcpy(new_peer.rt_tbl_name_for_flt[IPA_IP_v4], rt_tbl_name_for_flt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX); + memcpy(new_peer.rt_tbl_name_for_flt[IPA_IP_v6], rt_tbl_name_for_flt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX); + + peer_l2_hdr_type = peer_iface->m_p_iface->tx_prop->tx[0].hdr_l2_type; + increment_ref_cnt_peer_l2_hdr_type(peer_l2_hdr_type); + add_hdr_proc_ctx(peer_l2_hdr_type); + + /* push the new peer_iface_info into the list */ + m_peer_iface_info.push_front(new_peer); - memset(&evt, 0, sizeof(evt)); - evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION; - evt.evt_data = (void*)conn; - IPACM_EvtDispatcher::PostEvt(&evt); -#endif return; } -void IPACM_LanToLan::handle_del_connection(ipacm_event_connection* new_conn) +void IPACM_LanToLan_Iface::handle_client_add(uint8_t *mac) { -#ifdef CT_OPT - if(new_conn == NULL) + list<client_info>::iterator it_client; + list<peer_iface_info>::iterator it_peer_info; + client_info new_client; + bool flag[IPA_HDR_L2_MAX]; + + for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) { - IPACMERR("No connection info is found.\n"); - return; + if(memcmp(it_client->mac_addr, mac, sizeof(it_client->mac_addr)) == 0) + { + IPACMDBG_H("This client has been added before.\n"); + return; + } } - if(new_conn->iptype != IPA_IP_v4 && new_conn->iptype != IPA_IP_v6) + + if(m_client_info.size() == MAX_NUM_CLIENT) { - IPACMERR("IP type is not expected: %d.\n", new_conn->iptype); + IPACMDBG_H("The number of clients has reached maximum %d.\n", MAX_NUM_CLIENT); return; } - IPACMDBG_H("Del connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", new_conn->iptype, new_conn->src_ipv4_addr, new_conn->dst_ipv4_addr); - IPACMDBG_H("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", new_conn->src_ipv6_addr[0], new_conn->src_ipv6_addr[1], new_conn->src_ipv6_addr[2], - new_conn->src_ipv6_addr[3], new_conn->dst_ipv6_addr[0], new_conn->dst_ipv6_addr[1], new_conn->dst_ipv6_addr[2], new_conn->dst_ipv6_addr[3]); + memcpy(new_client.mac_addr, mac, sizeof(new_client.mac_addr)); + m_client_info.push_front(new_client); + + client_info &front_client = m_client_info.front(); - if(is_lan2lan_connection(new_conn) == false) + /* install inter-interface rules */ + if(m_support_inter_iface_offload) { - IPACMDBG_H("The connection is not lan2lan connection.\n"); - remove_cache_connection(new_conn); - return; - } + memset(flag, 0, sizeof(flag)); + for(it_peer_info = m_peer_iface_info.begin(); it_peer_info != m_peer_iface_info.end(); it_peer_info++) + { + /* make sure add routing rule only once for each peer l2 header type */ + if(flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] == false) + { + /* add client routing rule for each peer interface */ + add_client_rt_rule(&(*it_peer_info), &front_client); + flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] = true; + } - ipacm_cmd_q_data evt; - ipacm_event_connection* conn; + /* add client filtering rule on peer interfaces */ + it_peer_info->peer->add_one_client_flt_rule(this, &front_client); + } + } - conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection)); - if(conn == NULL) + /* install intra-interface rules */ + if(m_support_intra_iface_offload) { - IPACMERR("Failed to allocate memory for del_connection event.\n"); - return; + /* add routing rule first */ + add_client_rt_rule(&m_intra_interface_info, &front_client); + + /* add filtering rule */ + if(m_is_ip_addr_assigned[IPA_IP_v4]) + { + add_client_flt_rule(&m_intra_interface_info, &front_client, IPA_IP_v4); + } + if(m_is_ip_addr_assigned[IPA_IP_v6]) + { + add_client_flt_rule(&m_intra_interface_info, &front_client, IPA_IP_v6); + } } - memcpy(conn, new_conn, sizeof(ipacm_event_connection)); - memset(&evt, 0, sizeof(evt)); - evt.event = IPA_LAN_TO_LAN_DEL_CONNECTION; - evt.evt_data = (void*)conn; - IPACM_EvtDispatcher::PostEvt(&evt); -#endif return; } -bool IPACM_LanToLan::is_lan2lan_connection(ipacm_event_connection* data) +void IPACM_LanToLan_Iface::handle_client_del(uint8_t *mac) { - if(data->iptype == IPA_IP_v4) + list<client_info>::iterator it_client; + list<peer_iface_info>::iterator it_peer_info; + bool flag[IPA_HDR_L2_MAX]; + + for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) { - if(client_info_v4_.count(data->src_ipv4_addr) == 0 || client_info_v4_.count(data->dst_ipv4_addr) == 0) + if(memcmp(it_client->mac_addr, mac, sizeof(it_client->mac_addr)) == 0) //found the client { - IPACMDBG("Either source or destination is not in client table\n"); - return false; + IPACMDBG_H("Found the client.\n"); + break; } + } - ipacm_iface_type src_type, dst_type; - src_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v4_[data->src_ipv4_addr].p_iface->ipa_if_num].if_cat; - dst_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v4_[data->dst_ipv4_addr].p_iface->ipa_if_num].if_cat; + if(it_client != m_client_info.end()) //if we found the client + { + /* uninstall inter-interface rules */ + if(m_support_inter_iface_offload) + { + memset(flag, 0, sizeof(flag)); + for(it_peer_info = m_peer_iface_info.begin(); it_peer_info != m_peer_iface_info.end(); + it_peer_info++) + { + IPACMDBG_H("Delete client filtering rule on peer interface.\n"); + it_peer_info->peer->del_one_client_flt_rule(this, &(*it_client)); - return (src_type != dst_type); + /* make sure to delete routing rule only once for each peer l2 header type */ + if(flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] == false) + { + IPACMDBG_H("Delete client routing rule for peer interface.\n"); + del_client_rt_rule(&(*it_peer_info), &(*it_client)); + flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] = true; + } + } + } + + /* uninstall intra-interface rules */ + if(m_support_intra_iface_offload) + { + /* delete filtering rule first */ + IPACMDBG_H("Delete client filtering rule for intra-interface communication.\n"); + del_client_flt_rule(&m_intra_interface_info, &(*it_client)); + + /* delete routing rule */ + IPACMDBG_H("Delete client routing rule for intra-interface communication.\n"); + del_client_rt_rule(&m_intra_interface_info, &(*it_client)); + } + + /* erase the client from client info list */ + m_client_info.erase(it_client); } else { - uint64_t src_v6_addr, dst_v6_addr; - memcpy(&src_v6_addr, &(data->src_ipv6_addr[2]), sizeof(uint64_t)); - memcpy(&dst_v6_addr, &(data->dst_ipv6_addr[2]), sizeof(uint64_t)); + IPACMDBG_H("The client is not found.\n"); + } - if(client_info_v6_.count(src_v6_addr) == 0 || client_info_v6_.count(dst_v6_addr) == 0) - { - IPACMDBG("Either source or destination is not in client table\n"); - return false; - } + return; +} - ipacm_iface_type src_type, dst_type; - src_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v6_[src_v6_addr].p_iface->ipa_if_num].if_cat; - dst_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v6_[dst_v6_addr].p_iface->ipa_if_num].if_cat; +void IPACM_LanToLan_Iface::add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_type) +{ + uint32_t hdr_proc_ctx_hdl; - return (src_type != dst_type); + if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 1) + { + m_p_iface->eth_bridge_add_hdr_proc_ctx(peer_l2_type, &hdr_proc_ctx_hdl); + hdr_proc_ctx_for_inter_interface[peer_l2_type] = hdr_proc_ctx_hdl; + IPACMDBG_H("Installed inter-interface hdr proc ctx on iface %s: handle %d\n", m_p_iface->dev_name, hdr_proc_ctx_hdl); } + return; } -IPACM_LanToLan* IPACM_LanToLan::getLan2LanInstance() +void IPACM_LanToLan_Iface::del_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_type) { - return p_instance; + if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 0) + { + m_p_iface->eth_bridge_del_hdr_proc_ctx(hdr_proc_ctx_for_inter_interface[peer_l2_type]); + IPACMDBG_H("Hdr proc ctx with hdl %d is deleted.\n", hdr_proc_ctx_for_inter_interface[peer_l2_type]); + } + return; } -bool IPACM_LanToLan::is_potential_lan2lan_connection(ipacm_event_connection* new_conn) +void IPACM_LanToLan_Iface::print_data_structure_info() { - int i, num_private_subnet; - bool src_is_valid = false; - bool dst_is_valid = false; + list<peer_iface_info>::iterator it_peer; + list<client_info>::iterator it_client; + int i, j, k; + + IPACMDBG_H("\n"); + IPACMDBG_H("Interface %s:\n", m_p_iface->dev_name); + IPACMDBG_H("Is IPv4 addr assigned? %d\n", m_is_ip_addr_assigned[IPA_IP_v4]); + IPACMDBG_H("Is IPv6 addr assigned? %d\n", m_is_ip_addr_assigned[IPA_IP_v6]); + IPACMDBG_H("Support inter interface offload? %d\n", m_support_inter_iface_offload); + IPACMDBG_H("Support intra interface offload? %d\n", m_support_intra_iface_offload); - if(new_conn->iptype == IPA_IP_v4) + if(m_support_inter_iface_offload) { - num_private_subnet = IPACM_Iface::ipacmcfg->ipa_num_private_subnet; - for(i=0; i<num_private_subnet; i++) + for(i = 0; i < IPA_HDR_L2_MAX; i++) { - if( (new_conn->src_ipv4_addr & IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask) - == (IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr & IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask) ) - { - src_is_valid = true; - } - if( (new_conn->dst_ipv4_addr & IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask) - == (IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr & IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask) ) + IPACMDBG_H("Ref_cnt of peer l2 type %s is %d.\n", ipa_l2_hdr_type[i], ref_cnt_peer_l2_hdr_type[i]); + if(ref_cnt_peer_l2_hdr_type[i] > 0) { - dst_is_valid = true; + IPACMDBG_H("Hdr proc ctx for peer l2 type %s: %d\n", ipa_l2_hdr_type[i], hdr_proc_ctx_for_inter_interface[i]); } } - - if(src_is_valid && dst_is_valid) - { - IPACMDBG("Both src and dst are potentially in subnet.\n"); - return true; - } } - else - { - if( (new_conn->src_ipv6_addr[0] & ipv6_multicast_mask) != (ipv6_multicast_addr & ipv6_multicast_mask) ) - { - src_is_valid = true; - } - if( (new_conn->dst_ipv6_addr[0] & ipv6_multicast_mask) != (ipv6_multicast_addr & ipv6_multicast_mask) ) - { - dst_is_valid = true; - } - if(src_is_valid && dst_is_valid) - { - IPACMDBG("Both src and dst are potentially in subnet.\n"); - return true; - } + if(m_support_intra_iface_offload) + { + IPACMDBG_H("Hdr proc ctx for intra-interface: %d\n", hdr_proc_ctx_for_intra_interface); } - IPACMDBG("This connection is not a lan2lan connection potentially.\n"); - return false; -} - -void IPACM_LanToLan::cache_new_connection(ipacm_event_connection* new_conn) -{ - if(is_potential_lan2lan_connection(new_conn) == true) + i = 1; + IPACMDBG_H("There are %d clients in total.\n", m_client_info.size()); + for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) { - if(new_conn->iptype == IPA_IP_v4) + IPACMDBG_H("Client %d MAC: 0x%02x%02x%02x%02x%02x%02x Pointer: 0x%08x\n", i, it_client->mac_addr[0], it_client->mac_addr[1], + it_client->mac_addr[2], it_client->mac_addr[3], it_client->mac_addr[4], it_client->mac_addr[5], &(*it_client)); + + if(m_support_inter_iface_offload) { - if(connection_v4_.size() == max_cache_connection) + for(j = 0; j < IPA_HDR_L2_MAX; j++) { - IPACMDBG_H("Cached ipv4 connections already reach maximum, clear up the list.\n"); - connection_v4_.clear(); + if(ref_cnt_peer_l2_hdr_type[j] > 0) + { + IPACMDBG_H("Printing routing rule info for inter-interface communication for peer l2 type %s.\n", + ipa_l2_hdr_type[j]); + IPACMDBG_H("Number of IPv4 routing rules is %d, handles:\n", it_client->inter_iface_rt_rule_hdl[j].num_hdl[IPA_IP_v4]); + for(k = 0; k < it_client->inter_iface_rt_rule_hdl[j].num_hdl[IPA_IP_v4]; k++) + { + IPACMDBG_H("%d\n", it_client->inter_iface_rt_rule_hdl[j].rule_hdl[IPA_IP_v4][k]); + } + + IPACMDBG_H("Number of IPv6 routing rules is %d, handles:\n", it_client->inter_iface_rt_rule_hdl[j].num_hdl[IPA_IP_v6]); + for(k = 0; k < it_client->inter_iface_rt_rule_hdl[j].num_hdl[IPA_IP_v6]; k++) + { + IPACMDBG_H("%d\n", it_client->inter_iface_rt_rule_hdl[j].rule_hdl[IPA_IP_v6][k]); + } + } } - - connection_v4_.push_back(*new_conn); - IPACMDBG_H("Cache an ipv4 connection, now the number of ipv4 cache connection is %d.\n", connection_v4_.size()); } - else + + if(m_support_intra_iface_offload) { - if(connection_v6_.size() == max_cache_connection) + IPACMDBG_H("Printing routing rule info for intra-interface communication.\n"); + IPACMDBG_H("Number of IPv4 routing rules is %d, handles:\n", it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]); + for(j = 0; j < it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]; j++) { - IPACMDBG_H("Cached ipv6 connections already reach maximum, clear up the list.\n"); - connection_v6_.clear(); + IPACMDBG_H("%d\n", it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][j]); } - connection_v6_.push_back(*new_conn); - IPACMDBG_H("Cache an ipv6 connection, now the number of ipv6 cache connection is %d.\n", connection_v6_.size()); + IPACMDBG_H("Number of IPv6 routing rules is %d, handles:\n", it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]); + for(j = 0; j < it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]; j++) + { + IPACMDBG_H("%d\n", it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][j]); + } } + i++; + } + + IPACMDBG_H("There are %d peer interfaces in total.\n", m_peer_iface_info.size()); + for(it_peer = m_peer_iface_info.begin(); it_peer != m_peer_iface_info.end(); it_peer++) + { + print_peer_info(&(*it_peer)); + } + + if(m_support_intra_iface_offload) + { + IPACMDBG_H("This interface supports intra-interface communication, printing info:\n"); + print_peer_info(&m_intra_interface_info); } + return; } -void IPACM_LanToLan::remove_cache_connection(ipacm_event_connection* del_conn) +void IPACM_LanToLan_Iface::print_peer_info(peer_iface_info *peer_info) { - connection_list::iterator it; - if(is_potential_lan2lan_connection(del_conn) == true) + list<flt_rule_info>::iterator it_flt; + list<rt_rule_info>::iterator it_rt; + + IPACMDBG_H("Printing peer info for iface %s:\n", peer_info->peer->m_p_iface->dev_name); + + IPACMDBG_H("There are %d flt info in total.\n", peer_info->flt_rule.size()); + for(it_flt = peer_info->flt_rule.begin(); it_flt != peer_info->flt_rule.end(); it_flt++) { - if(del_conn->iptype == IPA_IP_v4) + IPACMDBG_H("Flt rule handle for client 0x%08x:\n", it_flt->p_client); + if(m_is_ip_addr_assigned[IPA_IP_v4]) { - for(it = connection_v4_.begin(); it != connection_v4_.end(); it++) - { - if(it->src_ipv4_addr == del_conn->src_ipv4_addr && it->dst_ipv4_addr == del_conn->dst_ipv4_addr) - { - IPACMDBG("Find the cached ipv4 connection, remove it from list.\n"); - connection_v4_.erase(it); - IPACMDBG_H("Now the number of ipv4 cache connection is %d.\n", connection_v4_.size()); - return; - } - } - IPACMDBG_H("Do not find the cached ipv4 connection, do nothing.\n"); + IPACMDBG_H("IPv4 %d\n", it_flt->flt_rule_hdl[IPA_IP_v4]); } - else + if(m_is_ip_addr_assigned[IPA_IP_v6]) { - for(it = connection_v6_.begin(); it != connection_v6_.end(); it++) - { - if(memcmp(it->src_ipv6_addr, del_conn->src_ipv6_addr, 4*sizeof(uint32_t)) == 0 - && memcmp(it->dst_ipv6_addr, del_conn->dst_ipv6_addr, 4*sizeof(uint32_t)) == 0 ) - { - IPACMDBG("Find the cached ipv6 connection, remove it from list.\n"); - connection_v6_.erase(it); - IPACMDBG_H("Now the number of ipv6 cache connection is %d.\n", connection_v6_.size()); - return; - } - } - IPACMDBG_H("Do not find the cached ipv6 connection, do nothing.\n"); + IPACMDBG_H("IPv6 %d\n", it_flt->flt_rule_hdl[IPA_IP_v6]); } } + return; } -void IPACM_LanToLan::check_cache_connection(ipa_ip_type iptype, client_info* client) +IPACM_Lan* IPACM_LanToLan_Iface::get_iface_pointer() { -#ifdef CT_OPT - connection_list::iterator it; - if(iptype == IPA_IP_v4) - { - it = connection_v4_.begin(); - while(it != connection_v4_.end()) - { - if( (it->src_ipv4_addr == client->ip.ipv4_addr && client_info_v4_.count(it->dst_ipv4_addr) > 0) - || (it->dst_ipv4_addr == client->ip.ipv4_addr && client_info_v4_.count(it->src_ipv4_addr) > 0) ) - { - IPACMDBG("Found a cache connection for src client 0x%08x and dst client 0x%08x.\n", it->src_ipv4_addr, it->dst_ipv4_addr); - ipacm_cmd_q_data evt; - ipacm_event_connection* conn; + return m_p_iface; +} - conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection)); - if(conn == NULL) - { - IPACMERR("Failed to allocate memory for new_connection event.\n"); - return; - } - memcpy(conn, &(*it), sizeof(ipacm_event_connection)); +bool IPACM_LanToLan_Iface::get_m_is_ip_addr_assigned(ipa_ip_type iptype) +{ + IPACMDBG_H("Has IP address been assigned to interface %s for IP type %d? %d\n", + m_p_iface->dev_name, iptype, m_is_ip_addr_assigned[iptype]); + return m_is_ip_addr_assigned[iptype]; +} - memset(&evt, 0, sizeof(evt)); - evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION; - evt.evt_data = (void*)conn; - IPACM_EvtDispatcher::PostEvt(&evt); +void IPACM_LanToLan_Iface::set_m_is_ip_addr_assigned(ipa_ip_type iptype, bool value) +{ + IPACMDBG_H("Is IP address of IP type %d assigned to interface %s? %d\n", iptype, + m_p_iface->dev_name, value); + m_is_ip_addr_assigned[iptype] = value; +} - it = connection_v4_.erase(it); - IPACMDBG_H("Now the number of cache connections is %d.\n", connection_v4_.size()); - } - else - { - it++; - } - } - } - else - { - uint64_t src_v6_addr, dst_v6_addr; - it = connection_v6_.begin(); - while(it != connection_v6_.end()) - { - memcpy(&src_v6_addr, &(it->src_ipv6_addr[2]), sizeof(uint64_t)); - memcpy(&dst_v6_addr, &(it->dst_ipv6_addr[2]), sizeof(uint64_t)); - if( (memcmp(it->src_ipv6_addr, client->ip.ipv6_addr, 4*sizeof(uint32_t)) == 0 && client_info_v6_.count(dst_v6_addr) > 0) - || (memcmp(it->dst_ipv6_addr, client->ip.ipv6_addr, 4*sizeof(uint32_t)) == 0 && client_info_v6_.count(src_v6_addr) > 0) ) - { - IPACMDBG("Found a cache connection with src client 0x%08x%08x%08x%08x and dst client 0x%08x%08x%08x%08x.\n", it->src_ipv6_addr[0], - it->src_ipv6_addr[1], it->src_ipv6_addr[2], it->src_ipv6_addr[3], it->dst_ipv6_addr[0], it->dst_ipv6_addr[1], - it->dst_ipv6_addr[2], it->dst_ipv6_addr[3]); - ipacm_cmd_q_data evt; - ipacm_event_connection* conn; - - conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection)); - if(conn == NULL) - { - IPACMERR("Failed to allocate memory for new_connection event.\n"); - return; - } - memcpy(conn, &(*it), sizeof(ipacm_event_connection)); +bool IPACM_LanToLan_Iface::get_m_support_inter_iface_offload() +{ + IPACMDBG_H("Support inter interface offload on %s? %d\n", m_p_iface->dev_name, + m_support_inter_iface_offload); + return m_support_inter_iface_offload; +} - memset(&evt, 0, sizeof(evt)); - evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION; - evt.evt_data = (void*)conn; - IPACM_EvtDispatcher::PostEvt(&evt); +bool IPACM_LanToLan_Iface::get_m_support_intra_iface_offload() +{ + IPACMDBG_H("Support intra interface offload on %s? %d\n", m_p_iface->dev_name, + m_support_intra_iface_offload); + return m_support_intra_iface_offload; +} + +void IPACM_LanToLan_Iface::increment_ref_cnt_peer_l2_hdr_type(ipa_hdr_l2_type peer_l2_type) +{ + ref_cnt_peer_l2_hdr_type[peer_l2_type]++; + IPACMDBG_H("Now the ref_cnt of peer l2 hdr type %s is %d.\n", ipa_l2_hdr_type[peer_l2_type], + ref_cnt_peer_l2_hdr_type[peer_l2_type]); + + return; +} + +void IPACM_LanToLan_Iface::decrement_ref_cnt_peer_l2_hdr_type(ipa_hdr_l2_type peer_l2_type) +{ + ref_cnt_peer_l2_hdr_type[peer_l2_type]--; + IPACMDBG_H("Now the ref_cnt of peer l2 hdr type %s is %d.\n", ipa_l2_hdr_type[peer_l2_type], + ref_cnt_peer_l2_hdr_type[peer_l2_type]); - it = connection_v6_.erase(it); - IPACMDBG_H("Now the number of cache connections is %d.\n", connection_v6_.size()); - } - else - { - it++; - } - } - } -#endif return; } diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp index fa8756e..fe13e67 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -57,9 +57,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <signal.h> #include "linux/ipa_qmi_service_v01.h" -#define __stringify_1(x...) #x -#define __stringify(x...) __stringify_1(x) - #include "IPACM_CmdQueue.h" #include "IPACM_EvtDispatcher.h" #include "IPACM_Defs.h" @@ -76,53 +73,6 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "IPACM_LanToLan.h" #endif - -const char *ipacm_event_name[] = { - __stringify(IPA_CFG_CHANGE_EVENT), /* 1 NULL */ - __stringify(IPA_LINK_UP_EVENT), /* 2 ipacm_event_data_fid */ - __stringify(IPA_LINK_DOWN_EVENT), /* 3 ipacm_event_data_fid */ - __stringify(IPA_ADDR_ADD_EVENT), /* 4 ipacm_event_data_addr */ - __stringify(IPA_ADDR_DEL_EVENT), /* 5 no use */ - __stringify(IPA_ROUTE_ADD_EVENT), /* 6 ipacm_event_data_addr */ - __stringify(IPA_ROUTE_DEL_EVENT), /* 7 ipacm_event_data_addr */ - __stringify(IPA_FIREWALL_CHANGE_EVENT), /* 8 NULL */ - __stringify(IPA_WLAN_AP_LINK_UP_EVENT), /* 9 ipacm_event_data_mac */ - __stringify(IPA_WLAN_STA_LINK_UP_EVENT), /* 10 ipacm_event_data_mac */ - __stringify(IPA_WLAN_CLIENT_ADD_EVENT), /* 11 ipacm_event_data_mac */ - __stringify(IPA_WLAN_CLIENT_DEL_EVENT), /* 12 ipacm_event_data_mac */ - __stringify(IPA_WLAN_CLIENT_POWER_SAVE_EVENT), /* 13 ipacm_event_data_mac */ - __stringify(IPA_WLAN_CLIENT_RECOVER_EVENT), /* 14 ipacm_event_data_mac */ - __stringify(IPA_NEW_NEIGH_EVENT), /* 15 ipacm_event_data_all */ - __stringify(IPA_DEL_NEIGH_EVENT), /* 16 ipacm_event_data_all */ - __stringify(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT), /* 17 ipacm_event_data_all */ - __stringify(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT), /* 18 ipacm_event_data_all */ - __stringify(IPA_SW_ROUTING_ENABLE), /* 19 NULL */ - __stringify(IPA_SW_ROUTING_DISABLE), /* 20 NULL */ - __stringify(IPA_PROCESS_CT_MESSAGE), /* 21 ipacm_ct_evt_data */ - __stringify(IPA_HANDLE_WAN_UP), /* 22 ipacm_event_iface_up */ - __stringify(IPA_HANDLE_WAN_DOWN), /* 23 ipacm_event_iface_up */ - __stringify(IPA_HANDLE_WLAN_UP), /* 24 ipacm_event_iface_up */ - __stringify(IPA_HANDLE_LAN_UP), /* 25 ipacm_event_iface_up */ - __stringify(IPA_WLAN_CLIENT_ADD_EVENT_EX), /* 26 ipacm_event_data_wlan_ex */ - __stringify(IPA_HANDLE_WAN_UP_V6), /* 27 NULL */ - __stringify(IPA_HANDLE_WAN_DOWN_V6), /* 28 NULL */ - __stringify(IPA_LAN_CLIENT_ACTIVE), /* 29 ipacm_event_lan_client*/ - __stringify(IPA_LAN_CLIENT_INACTIVE), /* 30 ipacm_event_lan_client*/ - __stringify(IPA_LAN_CLIENT_DISCONNECT), /* 31 ipacm_event_lan_client*/ - __stringify(IPA_LAN_CLIENT_POWER_SAVE), /* 32 ipacm_event_lan_client*/ - __stringify(IPA_LAN_CLIENT_POWER_RECOVER), /* 33 ipacm_event_lan_client*/ - __stringify(IPA_LAN_TO_LAN_NEW_CONNECTION), /* 34 ipacm_event_connection */ - __stringify(IPA_LAN_TO_LAN_DEL_CONNECTION), /* 35 ipacm_event_connection */ - __stringify(IPA_LAN_DELETE_SELF), /* 36 ipacm_event_data_fid */ - __stringify(IPA_WLAN_LINK_DOWN_EVENT), /* 37 ipacm_event_data_mac */ - __stringify(IPA_USB_LINK_UP_EVENT), /* 38 ipacm_event_data_fid */ - __stringify(IPA_PROCESS_CT_MESSAGE_V6), /* 39 ipacm_ct_evt_data */ - __stringify(IPA_PRIVATE_SUBNET_CHANGE_EVENT), /* 40 ipacm_event_data_fid */ - __stringify(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT), /* 41 ipacm_event_data_fid */ - __stringify(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT), /* 42 ipacm_event_data_fid */ - __stringify(IPA_WAN_XLAT_CONNECT_EVENT), /* 43 ipacm_event_data_fid */ -}; - #define IPA_DRIVER "/dev/ipa" #define IPACM_FIREWALL_FILE_NAME "mobileap_firewall.xml" @@ -780,11 +730,11 @@ int main(int argc, char **argv) IPACMDBG_H("In main()\n"); IPACM_Neighbor *neigh = new IPACM_Neighbor(); IPACM_IfaceManager *ifacemgr = new IPACM_IfaceManager(); -#ifndef FEATURE_ETH_BRIDGE_LE -#ifndef FEATURE_IPA_ANDROID + +#ifdef FEATURE_ETH_BRIDGE_LE IPACM_LanToLan* lan2lan = new IPACM_LanToLan(); -#endif /* defined(FEATURE_IPA_ANDROID)*/ #endif + IPACM_ConntrackClient *cc = IPACM_ConntrackClient::GetInstance(); CtList = new IPACM_ConntrackListener(); @@ -963,7 +913,7 @@ int ipa_get_if_index memset(&ifr, 0, sizeof(struct ifreq)); - (void)strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name)); + (void)strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp index 7ae6131..2a2555a 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp @@ -176,8 +176,10 @@ bool IPACM_Routing::GetRoutingTable(struct ipa_ioc_get_rt_tbl *routingTable) 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; } diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp index c30a81b..02f36a6 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp @@ -55,6 +55,7 @@ bool IPACM_Wan::wan_up = false; bool IPACM_Wan::wan_up_v6 = false; uint8_t IPACM_Wan::xlat_mux_id = 0; +uint32_t IPACM_Wan::curr_wan_ip = 0; int IPACM_Wan::num_v4_flt_rule = 0; int IPACM_Wan::num_v6_flt_rule = 0; @@ -124,6 +125,8 @@ IPACM_Wan::IPACM_Wan(int iface_index, memset(invalid_mac, 0, sizeof(invalid_mac)); is_xlat = false; + hdr_hdl_dummy_v6 = 0; + hdr_proc_hdl_dummy_v6 = 0; if(iface_query != NULL) { @@ -149,12 +152,6 @@ IPACM_Wan::IPACM_Wan(int iface_index, IPACMDBG_H("The new WAN interface is WLAN STA.\n"); } - if(m_is_sta_mode == WLAN_WAN) - { - memcpy(ext_router_mac_addr, mac_addr, - sizeof(ext_router_mac_addr)); - } - m_fd_ipa = open(IPA_DEVICE_NAME, O_RDWR); if(0 == m_fd_ipa) { @@ -235,7 +232,7 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data) rt_rule->commit = 1; rt_rule->num_rules = NUM_RULES; rt_rule->ip = data->iptype; - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name); + strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name)); rt_rule_entry = &rt_rule->rules[0]; if(m_is_sta_mode == Q6_WAN) @@ -272,7 +269,7 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data) ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2]; ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3]; #ifdef FEATURE_IPA_V3 - rt_rule_entry->rule.hashable = IPA_RULE_NON_HASHABLE; + rt_rule_entry->rule.hashable = false; #endif if (false == m_routing.AddRoutingRule(rt_rule)) { @@ -289,7 +286,7 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data) dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl; /* setup same rule for v6_wan table*/ - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name); + strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name)); if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -357,6 +354,9 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data) 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)); flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; @@ -448,11 +448,11 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data) rt_rule_entry->at_rear = false; rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; /* still need setup v4 default routing rule to A5*/ - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name); + strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name)); rt_rule_entry->rule.attrib.u.v4.dst_addr = data->ipv4_addr; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; #ifdef FEATURE_IPA_V3 - rt_rule_entry->rule.hashable = IPA_RULE_NON_HASHABLE; + rt_rule_entry->rule.hashable = false; #endif if (false == m_routing.AddRoutingRule(rt_rule)) { @@ -492,6 +492,10 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data) wan_v4_addr = data->ipv4_addr; wan_v4_addr_set = true; + + if (m_is_sta_mode == Q6_WAN) + curr_wan_ip = data->ipv4_addr; + IPACMDBG_H("Receved wan ipv4-addr:0x%x\n",wan_v4_addr); } @@ -1218,7 +1222,6 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) if (m_is_sta_mode !=Q6_WAN) { IPACM_Wan::backhaul_is_sta_mode = true; - if((iptype==IPA_IP_v4) && (header_set_v4 != true)) { header_partial_default_wan_v4 = true; @@ -1338,12 +1341,12 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) /* use the STA-header handler */ if (iptype == IPA_IP_v4) { - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name); + strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name, sizeof(rt_rule->rt_tbl_name)); rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v4; } else { - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name); + strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name)); rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v6; } @@ -1366,6 +1369,10 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) { rt_rule_entry->rule.attrib.u.v4.dst_addr = 0; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0; +#ifdef FEATURE_IPA_V3 + + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -1388,6 +1395,9 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -1407,7 +1417,7 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) if (iptype == IPA_IP_v6) { - strcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name); + strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name)); memset(rt_rule_entry, 0, sizeof(struct ipa_rt_rule_add)); rt_rule_entry->at_rear = true; if(m_is_sta_mode == Q6_WAN) @@ -1425,6 +1435,15 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) } else { + /* create dummy ethernet header for v6 RX path */ + IPACMDBG_H("Construct dummy ethernet_header\n"); + if (add_dummy_rx_hdr()) + { + IPACMERR("Construct dummy ethernet_header failed!\n"); + free(rt_rule); + return IPACM_FAILURE; + } + rt_rule_entry->rule.hdr_proc_ctx_hdl = hdr_proc_hdl_dummy_v6; rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; } rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; @@ -1436,6 +1455,9 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -1731,11 +1753,14 @@ int IPACM_Wan::handle_sta_header_add_evt() get_client_memptr(wan_client, index)->mac[3], get_client_memptr(wan_client, index)->mac[4], get_client_memptr(wan_client, index)->mac[5]); + if(get_client_memptr(wan_client, index)->ipv4_header_set) { hdr_hdl_sta_v4 = get_client_memptr(wan_client, index)->hdr_hdl_v4; header_set_v4 = true; IPACMDBG_H("add full ipv4 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v4); + /* store external_ap's MAC */ + memcpy(ext_router_mac_addr, get_client_memptr(wan_client, index)->mac, sizeof(ext_router_mac_addr)); } else { @@ -1776,11 +1801,14 @@ int IPACM_Wan::handle_sta_header_add_evt() get_client_memptr(wan_client, index)->mac[3], get_client_memptr(wan_client, index)->mac[4], get_client_memptr(wan_client, index)->mac[5]); + if(get_client_memptr(wan_client, index)->ipv6_header_set) { hdr_hdl_sta_v6 = get_client_memptr(wan_client, index)->hdr_hdl_v6; header_set_v6 = true; IPACMDBG_H("add full ipv6 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v6); + /* store external_ap's MAC */ + memcpy(ext_router_mac_addr, get_client_memptr(wan_client, index)->mac, sizeof(ext_router_mac_addr)); } else { @@ -1920,14 +1948,13 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) flt_rule_entry.at_rear = true; #ifdef FEATURE_IPA_V3 flt_rule_entry.at_rear = false; - flt_rule_entry.rule.hashable = IPA_RULE_NON_HASHABLE; + flt_rule_entry.rule.hashable = false; #endif flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_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)); if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) { @@ -2003,6 +2030,7 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) } #ifdef FEATURE_IPA_V3 flt_rule_entry.at_rear = true; + flt_rule_entry.rule.hashable = true; #endif flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl; memcpy(&flt_rule_entry.rule.attrib, @@ -2079,6 +2107,9 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) { 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, &firewall_config.extd_firewall_entries[i].attrib, sizeof(struct ipa_rule_attrib)); @@ -2207,6 +2238,9 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; } } +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, @@ -2256,6 +2290,9 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.eq_attrib_type = 0; 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(struct ipa_rule_attrib)); @@ -2312,6 +2349,9 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) flt_rule_entry.at_rear = true; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; } +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); @@ -2381,6 +2421,9 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) { flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; } +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.hdl; memcpy(&flt_rule_entry.rule.attrib, &firewall_config.extd_firewall_entries[i].attrib, @@ -2461,6 +2504,9 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) flt_rule_entry.rule.retain_hdr = 1; flt_rule_entry.rule.eq_attrib_type = 0; 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(struct ipa_rule_attrib)); @@ -2510,6 +2556,9 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) flt_rule_entry.at_rear = true; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; } +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); @@ -2613,7 +2662,7 @@ int IPACM_Wan::config_dft_firewall_rules_ex(struct ipa_flt_rule_add *rules, int flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; #ifdef FEATURE_IPA_V3 flt_rule_entry.at_rear = false; - flt_rule_entry.rule.hashable = IPA_RULE_NON_HASHABLE; + flt_rule_entry.rule.hashable = false; #endif memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); rt_tbl_idx.ip = IPA_IP_v6; @@ -2680,6 +2729,9 @@ int IPACM_Wan::config_dft_firewall_rules_ex(struct ipa_flt_rule_add *rules, int { flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; } +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); rt_tbl_idx.ip = iptype; if(flt_rule_entry.rule.action == IPA_PASS_TO_ROUTING) @@ -2814,6 +2866,9 @@ int IPACM_Wan::config_dft_firewall_rules_ex(struct ipa_flt_rule_add *rules, int flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; } } +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); rt_tbl_idx.ip = iptype; @@ -2886,6 +2941,9 @@ int IPACM_Wan::config_dft_firewall_rules_ex(struct ipa_flt_rule_add *rules, int flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); rt_tbl_idx.ip = iptype; @@ -2996,6 +3054,9 @@ int IPACM_Wan::config_dft_firewall_rules_ex(struct ipa_flt_rule_add *rules, int flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); rt_tbl_idx.ip = iptype; /* firewall disable, all traffic are allowed */ @@ -3190,6 +3251,9 @@ int IPACM_Wan::add_icmp_alg_rules(struct ipa_flt_rule_add *rules, int rule_offse flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; /* Configuring ICMP filtering rule */ @@ -3307,6 +3371,9 @@ int IPACM_Wan::add_icmp_alg_rules(struct ipa_flt_rule_add *rules, int rule_offse flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; /* Configuring ICMP filtering rule */ @@ -3503,6 +3570,9 @@ int IPACM_Wan::add_dft_filtering_rule(struct ipa_flt_rule_add *rules, int rule_o flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask); @@ -3583,6 +3653,9 @@ int IPACM_Wan::add_dft_filtering_rule(struct ipa_flt_rule_add *rules, int rule_o flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; /* Configuring Multicast Filtering Rule */ @@ -4141,6 +4214,9 @@ int IPACM_Wan::config_dft_embms_rules(ipa_ioc_add_flt_rule *pFilteringTable_v4, flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; memcpy(&flt_rule_entry.rule.attrib, @@ -4187,6 +4263,9 @@ int IPACM_Wan::config_dft_embms_rules(ipa_ioc_add_flt_rule *pFilteringTable_v4, flt_rule_entry.rule.to_uc = 0; flt_rule_entry.rule.eq_attrib_type = 1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; memcpy(&flt_rule_entry.rule.attrib, @@ -4393,7 +4472,24 @@ int IPACM_Wan::handle_down_evt() } IPACMDBG_H("finished delete default v6 filtering rules\n "); } - + if(hdr_proc_hdl_dummy_v6) + { + if(m_header.DeleteHeaderProcCtx(hdr_proc_hdl_dummy_v6) == false) + { + IPACMERR("Failed to delete hdr_proc_hdl_dummy_v6\n"); + res = IPACM_FAILURE; + goto fail; + } + } + if(hdr_hdl_dummy_v6) + { + if (m_header.DeleteHeaderHdl(hdr_hdl_dummy_v6) == false) + { + IPACMERR("Failed to delete hdr_hdl_dummy_v6\n"); + res = IPACM_FAILURE; + goto fail; + } + } fail: if (tx_prop != NULL) { @@ -4757,6 +4853,10 @@ int IPACM_Wan::install_wan_filtering_rule(bool is_sw_routing) flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif + flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; memcpy(&flt_rule_entry.rule.attrib, @@ -4815,6 +4915,9 @@ int IPACM_Wan::install_wan_filtering_rule(bool is_sw_routing) flt_rule_entry.flt_rule_hdl = -1; flt_rule_entry.status = -1; flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; +#ifdef FEATURE_IPA_V3 + flt_rule_entry.rule.hashable = true; +#endif flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, @@ -5041,7 +5144,6 @@ int IPACM_Wan::handle_wan_hdr_init(uint8_t *mac_addr) mac_addr, sizeof(get_client_memptr(wan_client, num_wan_client)->mac)); - IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); @@ -5488,6 +5590,9 @@ int IPACM_Wan::handle_wan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptyp rt_rule_entry->rule.hdr_hdl = get_client_memptr(wan_client, wan_index)->hdr_hdl_v4; rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wan_client, wan_index)->v4_addr; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -5535,6 +5640,9 @@ int IPACM_Wan::handle_wan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptyp rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -5923,3 +6031,138 @@ int IPACM_Wan::handle_network_stats_update(ipa_get_apn_data_stats_resp_msg_v01 * } return IPACM_SUCCESS; } + +int IPACM_Wan::add_dummy_rx_hdr() +{ + +#define IFACE_INDEX_LEN 2 + char index[IFACE_INDEX_LEN]; + struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL; + int len = 0; + struct ipa_ioc_copy_hdr sCopyHeader; + struct ipa_hdr_add *ipv6_hdr; + struct ethhdr *eth_ipv6; + struct ipa_ioc_add_hdr_proc_ctx* pHeaderProcTable = NULL; + uint32_t cnt; + + /* get netdev-mac */ + if(tx_prop != NULL) + { + /* copy partial header for v6 */ + for (cnt=0; cnt<tx_prop->num_tx_props; cnt++) + { + if(tx_prop->tx[cnt].ip==IPA_IP_v6) + { + IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt); + memset(&sCopyHeader, 0, sizeof(sCopyHeader)); + memcpy(sCopyHeader.name, + tx_prop->tx[cnt].hdr_name, + sizeof(sCopyHeader.name)); + + IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt); + if (m_header.CopyHeader(&sCopyHeader) == false) + { + PERROR("ioctl copy header failed"); + return IPACM_FAILURE; + } + + IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); + IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); + if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) + { + IPACMERR("header oversize\n"); + return IPACM_FAILURE; + } + else + { + /* copy client mac_addr to partial header */ + IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", + sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); + /* only copy 6 bytes mac-address */ + if(sCopyHeader.is_eth2_ofst_valid == false) + { + memcpy(netdev_mac, &sCopyHeader.hdr[0+IPA_MAC_ADDR_SIZE], + sizeof(netdev_mac)); + } + else + { + memcpy(netdev_mac, &sCopyHeader.hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE], + sizeof(netdev_mac)); + } + } + break; + } + } + } + + len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add)); + pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len); + if (pHeaderDescriptor == NULL) + { + IPACMERR("calloc failed to allocate pHeaderDescriptor\n"); + return IPACM_FAILURE; + } + ipv6_hdr = &pHeaderDescriptor->hdr[0]; + /* copy ethernet type to header */ + eth_ipv6 = (struct ethhdr *) (ipv6_hdr->hdr +2); + memcpy(eth_ipv6->h_dest, netdev_mac, ETH_ALEN); + memcpy(eth_ipv6->h_source, ext_router_mac_addr, ETH_ALEN); + eth_ipv6->h_proto = htons(ETH_P_IPV6); + pHeaderDescriptor->commit = true; + pHeaderDescriptor->num_hdrs = 1; + + memset(ipv6_hdr->name, 0, + sizeof(pHeaderDescriptor->hdr[0].name)); + + snprintf(index,sizeof(index), "%d", ipa_if_num); + strlcpy(ipv6_hdr->name, index, sizeof(ipv6_hdr->name)); + ipv6_hdr->name[IPA_RESOURCE_NAME_MAX-1] = '\0'; + + if (strlcat(ipv6_hdr->name, IPA_DUMMY_ETH_HDR_NAME_v6, sizeof(ipv6_hdr->name)) > IPA_RESOURCE_NAME_MAX) + { + IPACMERR(" header name construction failed exceed length (%d)\n", strlen(ipv6_hdr->name)); + return IPACM_FAILURE; + } + + ipv6_hdr->hdr_len = ETH_HLEN + 2; + ipv6_hdr->hdr_hdl = -1; + ipv6_hdr->is_partial = 0; + ipv6_hdr->status = -1; + ipv6_hdr->type = IPA_HDR_L2_ETHERNET_II; + + if (m_header.AddHeader(pHeaderDescriptor) == false || + ipv6_hdr->status != 0) + { + IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", ipv6_hdr->status); + return IPACM_FAILURE; + } + + hdr_hdl_dummy_v6 = ipv6_hdr->hdr_hdl; + IPACMDBG_H("dummy v6 full header name:%s header handle:(0x%x)\n", + ipv6_hdr->name, + hdr_hdl_dummy_v6); + /* add dummy hdr_proc_hdl */ + len = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_add); + pHeaderProcTable = (ipa_ioc_add_hdr_proc_ctx*)malloc(len); + if(pHeaderProcTable == NULL) + { + IPACMERR("Cannot allocate header processing table.\n"); + return IPACM_FAILURE; + } + + memset(pHeaderProcTable, 0, len); + pHeaderProcTable->commit = 1; + pHeaderProcTable->num_proc_ctxs = 1; + pHeaderProcTable->proc_ctx[0].hdr_hdl = hdr_hdl_dummy_v6; + if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) + { + IPACMERR("Adding dummy hhdr_proc_hdl failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); + return IPACM_FAILURE; + } + else + { + hdr_proc_hdl_dummy_v6 = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; + IPACMDBG_H("dummy hhdr_proc_hdl is added successfully. (0x%x)\n", hdr_proc_hdl_dummy_v6); + } + return IPACM_SUCCESS; +} diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp index bb70724..00754a1 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp @@ -1,5 +1,5 @@ /* -Copyright (c) 2013, The Linux Foundation. All rights reserved. +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 @@ -54,16 +54,8 @@ Skylar Chang /* static member to store the number of total wifi clients within all APs*/ int IPACM_Wlan::total_num_wifi_clients = 0; -uint32_t* IPACM_Wlan::dummy_flt_rule_hdl_v4 = NULL; -uint32_t* IPACM_Wlan::dummy_flt_rule_hdl_v6 = NULL; int IPACM_Wlan::num_wlan_ap_iface = 0; -lan2lan_flt_rule_hdl IPACM_Wlan::self_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; -lan2lan_flt_rule_hdl IPACM_Wlan::self_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_WLAN_CLIENT]; - -lan2lan_flt_rule_hdl IPACM_Wlan::lan_client_flt_rule_hdl_v4[IPA_LAN_TO_LAN_MAX_LAN_CLIENT]; -lan2lan_flt_rule_hdl IPACM_Wlan::lan_client_flt_rule_hdl_v6[IPA_LAN_TO_LAN_MAX_LAN_CLIENT]; - IPACM_Wlan::IPACM_Wlan(int iface_index) : IPACM_Lan(iface_index) { #define WLAN_AMPDU_DEFAULT_FILTER_RULES 3 @@ -110,89 +102,20 @@ IPACM_Wlan::IPACM_Wlan(int iface_index) : IPACM_Lan(iface_index) return; } -#ifdef FEATURE_ETH_BRIDGE_LE - exp_index_v4 = IPV4_DEFAULT_FILTERTING_RULES + IPACM_Iface::ipacmcfg->ipa_num_private_subnet - + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_LAN_CLIENT + NUM_IPV4_ICMP_FLT_RULE; - exp_index_v6 = IPV6_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_LAN_CLIENT - + 2 * NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_ICMP_FLT_RULE; -#else -#ifndef CT_OPT - exp_index_v4 = 2*(IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) + NUM_IPV4_ICMP_FLT_RULE; - exp_index_v6 = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_IPV6_PREFIX_FLT_RULE) + NUM_IPV6_ICMP_FLT_RULE; -#else - exp_index_v4 = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) + NUM_IPV4_ICMP_FLT_RULE; - exp_index_v6 = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + NUM_IPV6_PREFIX_FLT_RULE) + NUM_IPV6_ICMP_FLT_RULE; -#endif -#ifdef FEATURE_IPA_ANDROID - exp_index_v4 = exp_index_v4 + 2 * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet); -#endif -#endif - IPACM_Wlan::num_wlan_ap_iface++; IPACMDBG_H("Now the number of wlan AP iface is %d\n", IPACM_Wlan::num_wlan_ap_iface); - add_dummy_flt_rule(); - - is_guest_ap = false; - memset(eth_bridge_lan_client_flt_info, 0, IPA_LAN_TO_LAN_MAX_LAN_CLIENT * sizeof(eth_bridge_client_flt_info)); - lan_client_flt_info_count = 0; - eth_bridge_wlan_client_rt_from_lan_info_v4 = NULL; - eth_bridge_wlan_client_rt_from_lan_info_v6 = NULL; - eth_bridge_wlan_client_rt_from_wlan_info_v4 = NULL; - eth_bridge_wlan_client_rt_from_wlan_info_v6 = NULL; - if(tx_prop != NULL) - { -#ifdef FEATURE_ETH_BRIDGE_LE - client_rt_info_size_v4 = sizeof(eth_bridge_client_rt_info) + each_client_rt_rule_count_v4 * sizeof(uint32_t); - eth_bridge_wlan_client_rt_from_lan_info_v4 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v4); - eth_bridge_wlan_client_rt_from_wlan_info_v4 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v4); - - client_rt_info_size_v6 = sizeof(eth_bridge_client_rt_info) + each_client_rt_rule_count_v6 * sizeof(uint32_t); - eth_bridge_wlan_client_rt_from_lan_info_v6 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v6); - eth_bridge_wlan_client_rt_from_wlan_info_v6 = (eth_bridge_client_rt_info*)calloc(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, client_rt_info_size_v6); -#endif - } - wlan_client_rt_from_lan_info_count_v4 = 0; - wlan_client_rt_from_lan_info_count_v6 = 0; - wlan_client_rt_from_wlan_info_count_v4 = 0; - wlan_client_rt_from_wlan_info_count_v6 = 0; -#ifdef FEATURE_ETH_BRIDGE_LE - if(iface_query != NULL) + m_is_guest_ap = false; + if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == INTERNET) { - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF && tx_prop != NULL) - { - if(IPACM_Lan::wlan_hdr_type != IPA_HDR_L2_NONE && tx_prop->tx[0].hdr_l2_type != IPACM_Lan::wlan_hdr_type) - { - IPACMERR("The WLAN header format is not consistent! Now header format is %d.\n", tx_prop->tx[0].hdr_l2_type); - } - else - { - if(wlan_ap_index == 0) - { - if(eth_bridge_get_hdr_template_hdl(&IPACM_Lan::wlan_hdr_template_hdl) == IPACM_FAILURE) - { - IPACMERR("Failed to setup wlan hdr template.\n"); - } - else - { - IPACM_Lan::wlan_hdr_type = tx_prop->tx[0].hdr_l2_type; - add_hdr_proc_ctx(); - } - } - } - if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == INTERNET) - { - is_guest_ap = true; - } - IPACMDBG_H("%s: guest ap enable: %d \n", - IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, is_guest_ap); - } + m_is_guest_ap = true; } -#endif + IPACMDBG_H("%s: guest ap enable: %d \n", + IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, m_is_guest_ap); #ifdef FEATURE_IPA_ANDROID /* set the IPA-client pipe enum */ - if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == WLAN_IF) + if(ipa_if_cate == WLAN_IF) { handle_tethering_client(false, IPACM_CLIENT_WLAN); } @@ -234,7 +157,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) IPACMDBG_H("Received IPA_WLAN_LINK_DOWN_EVENT\n"); handle_down_evt(); /* reset the AP-iface category to unknown */ - IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat=UNKNOWN_IF; + IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat = UNKNOWN_IF; IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface IPACM_Wlan::total_num_wifi_clients = (IPACM_Wlan::total_num_wifi_clients) - \ (num_wifi_client); @@ -271,7 +194,6 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) { IPACM_Wlan::num_wlan_ap_iface--; IPACMDBG_H("Now the number of wlan AP iface is %d\n", IPACM_Wlan::num_wlan_ap_iface); - del_dummy_flt_rule(); IPACMDBG_H("Received IPA_LAN_DELETE_SELF event.\n"); IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num); @@ -300,7 +222,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) if( ((data->iptype != ip_type) && (ip_type != IPA_IP_MAX)) || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES))) { - IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6); + IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6); /* Post event to NAT */ if (data->iptype == IPA_IP_v4) { @@ -328,27 +250,17 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) info->ipv4_addr, info->addr_mask); IPACM_EvtDispatcher::PostEvt(&evt_data); } + if(handle_addr_evt(data) == IPACM_FAILURE) { return; } - if ((data->iptype == IPA_IP_v4) && (wlan_ap_index == 0)) - { - IPACM_Lan::install_ipv4_icmp_flt_rule(); - } - if ((num_dft_rt_v6 == 1) && (data->iptype == IPA_IP_v6) && (wlan_ap_index == 0)) - { - install_ipv6_icmp_flt_rule(); - } #ifdef FEATURE_IPA_ANDROID add_dummy_private_subnet_flt_rule(data->iptype); handle_private_subnet_android(data->iptype); #else - if(wlan_ap_index == 0) - { - handle_private_subnet(data->iptype); - } + handle_private_subnet(data->iptype); #endif if (IPACM_Wan::isWanUP(ipa_if_num)) @@ -372,6 +284,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) { if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1) { + memcpy(ipv6_prefix, IPACM_Wan::backhaul_ipv6_prefix, sizeof(ipv6_prefix)); install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); if(IPACM_Wan::backhaul_is_sta_mode == false) @@ -444,6 +357,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) { if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { + memcpy(ipv6_prefix, data_wan_tether->ipv6_prefix, sizeof(ipv6_prefix)); install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix); if(data_wan_tether->is_sta == false) @@ -551,6 +465,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { + memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix)); install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix); if(data_wan->is_sta == false) @@ -574,11 +489,6 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) return; } IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); - if(data_wan->is_sta == false && wlan_ap_index > 0) - { - IPACMDBG_H("This is not the first AP instance and not STA mode, ignore WAN_DOWN event.\n"); - return; - } if (rx_prop != NULL) { if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) @@ -617,39 +527,15 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) ipa_interface_index = iface_ipa_index_query(data->if_index); if (ipa_interface_index == ipa_if_num) { -#ifdef FEATURE_ETH_BRIDGE_LE int i; for(i=0; i<data->num_of_attribs; i++) { if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR) { - if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true) - { - eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_WLAN, IPA_IP_v4); - eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_WLAN, IPA_IP_v6); - } - if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) - { - eth_bridge_add_self_client_flt_rule(data->attribs[i].u.mac_addr, IPA_IP_v4); - } - if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) - { - eth_bridge_add_self_client_flt_rule(data->attribs[i].u.mac_addr, IPA_IP_v6); - } - if (is_guest_ap == false) - { - if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true) - { - eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_LAN, IPA_IP_v4); - eth_bridge_add_wlan_client_rt_rule(data->attribs[i].u.mac_addr, SRC_LAN, IPA_IP_v6); - } - eth_bridge_post_lan_client_event(data->attribs[i].u.mac_addr, IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT); - } - eth_bridge_add_wlan_client(data->attribs[i].u.mac_addr, ipa_if_num); + eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->attribs[i].u.mac_addr); break; } } -#endif IPACMDBG_H("Received IPA_WLAN_CLIENT_ADD_EVENT\n"); handle_wlan_client_init_ex(data); } @@ -663,22 +549,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_WLAN_CLIENT_DEL_EVENT\n"); -#ifdef FEATURE_ETH_BRIDGE_LE - eth_bridge_del_self_client_flt_rule(data->mac_addr); - eth_bridge_del_wlan_client_rt_rule(data->mac_addr, SRC_WLAN); - if (is_guest_ap == false) - { - if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true) - { - eth_bridge_del_wlan_client_rt_rule(data->mac_addr, SRC_LAN); - } - eth_bridge_post_lan_client_event(data->mac_addr, IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT); - } - eth_bridge_del_wlan_client(data->mac_addr); -#endif - /* support lan2lan ipa-HW feature*/ - handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v4); - handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v6); + eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_DEL, IPA_IP_MAX, data->mac_addr); handle_wlan_client_down_evt(data->mac_addr); } } @@ -691,9 +562,6 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_WLAN_CLIENT_POWER_SAVE_EVENT\n"); - /* support lan2lan ipa-HW feature*/ - handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_SAVE, IPA_IP_v4); - handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_SAVE, IPA_IP_v6); handle_wlan_client_pwrsave(data->mac_addr); } } @@ -706,9 +574,6 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) if (ipa_interface_index == ipa_if_num) { IPACMDBG_H("Received IPA_WLAN_CLIENT_RECOVER_EVENT\n"); - /* support lan2lan ipa-HW feature*/ - handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_RECOVER, IPA_IP_v4); - handle_lan2lan_msg_post(data->mac_addr, IPA_LAN_CLIENT_POWER_RECOVER, IPA_IP_v6); wlan_index = get_wlan_client_index(data->mac_addr); if ((wlan_index != IPACM_INVALID_INDEX) && @@ -751,8 +616,6 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) { return; } - /* support lan2lan ipa-hw feature */ - handle_lan2lan_client_active(data, IPA_LAN_CLIENT_ACTIVE); handle_wlan_client_route_rule(data->mac_addr, data->iptype); if (data->iptype == IPA_IP_v4) @@ -777,124 +640,18 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) IPACM_Iface::handle_software_routing_disable(); break; - case IPA_ETH_BRIDGE_LAN_CLIENT_ADD_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_LAN_CLIENT_ADD_EVENT event.\n"); - ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param; - if(mac != NULL) - { - if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) - { - eth_bridge_add_lan_client_flt_rule(mac->mac_addr, IPA_IP_v4); - } - if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) - { - eth_bridge_add_lan_client_flt_rule(mac->mac_addr, IPA_IP_v6); - } - } - else - { - IPACMERR("Event MAC is empty.\n"); - } - } - break; - - case IPA_ETH_BRIDGE_LAN_CLIENT_DEL_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_LAN_CLIENT_DEL_EVENT event.\n"); - ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param; - if(mac != NULL) - { - if(wlan_ap_index == 0) - { - if(eth_bridge_del_lan_client_flt_rule(mac->mac_addr) == IPACM_FAILURE) - { - IPACMDBG_H("Failed to delete lan client MAC based flt rule.\n"); - } - } - } - else - { - IPACMERR("Event MAC is empty.\n"); - } - } - break; - - case IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT event.\n"); - int i; - ipacm_event_data_if_cat* cat = (ipacm_event_data_if_cat*)param; - if(cat == NULL) - { - IPACMERR("Event data is empty.\n"); - return; - } - if(cat->if_cat != LAN_IF && cat->if_cat != ODU_IF) - { - IPACMDBG_H("The event was not sent by LAN interface, ignore.\n"); - return; - } - if (IPACM_Lan::is_usb_up == true && IPACM_Lan::is_cpe_up == true) - { - IPACMDBG_H("USB and CPE both are up, lan-wlan routing rules are already installed. \n"); - return; - } - for(i=0; i<IPACM_Lan::num_wlan_client; i++) - { - if(IPACM_Lan::eth_bridge_wlan_client[i].ipa_if_num == ipa_if_num) - { - eth_bridge_add_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_LAN, IPA_IP_v4); - eth_bridge_add_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_LAN, IPA_IP_v6); - } - } - } - break; - - case IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT event.\n"); - int i; - ipacm_event_data_if_cat* cat = (ipacm_event_data_if_cat*)param; - if(cat == NULL) - { - IPACMERR("Event data is empty.\n"); - return; - } - if(cat->if_cat != LAN_IF && cat->if_cat != ODU_IF) - { - IPACMDBG_H("The event was not sent by LAN interface, ignore.\n"); - return; - } - if (IPACM_Lan::is_usb_up == true || IPACM_Lan::is_cpe_up == true) - { - IPACMDBG_H("USB or CPE is still up, so keep lan-wlan routing rule. \n"); - return; - } - for(i=0; i<IPACM_Lan::num_wlan_client; i++) - { - if(IPACM_Lan::eth_bridge_wlan_client[i].ipa_if_num == ipa_if_num) - { - eth_bridge_del_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_LAN); - } - } - } - break; - case IPA_WLAN_SWITCH_TO_SCC: IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_SCC\n"); if(ip_type == IPA_IP_MAX) { handle_SCC_MCC_switch(IPA_IP_v4); handle_SCC_MCC_switch(IPA_IP_v6); - eth_bridge_handle_wlan_SCC_MCC_switch(IPA_IP_v4); - eth_bridge_handle_wlan_SCC_MCC_switch(IPA_IP_v6); } else { handle_SCC_MCC_switch(ip_type); - eth_bridge_handle_wlan_SCC_MCC_switch(ip_type); } + eth_bridge_post_event(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, IPA_IP_MAX, NULL); break; case IPA_WLAN_SWITCH_TO_MCC: @@ -903,14 +660,12 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) { handle_SCC_MCC_switch(IPA_IP_v4); handle_SCC_MCC_switch(IPA_IP_v6); - eth_bridge_handle_wlan_SCC_MCC_switch(IPA_IP_v4); - eth_bridge_handle_wlan_SCC_MCC_switch(IPA_IP_v6); } else { handle_SCC_MCC_switch(ip_type); - eth_bridge_handle_wlan_SCC_MCC_switch(ip_type); } + eth_bridge_post_event(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, IPA_IP_MAX, NULL); break; case IPA_CRADLE_WAN_MODE_SWITCH: @@ -935,11 +690,10 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) break; case IPA_CFG_CHANGE_EVENT: { - int i; - IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT event for %s with new wlan-mode: %s old wlan-mode: %s", + IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT event for %s with new wlan-mode: %s old wlan-mode: %s\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == 0) ? "full" : "internet", - (is_guest_ap == true) ? "internet" : "full"); + (m_is_guest_ap == true) ? "internet" : "full"); /* Add Natting iface to IPACM_Config if there is Rx/Tx property */ if (rx_prop != NULL || tx_prop != NULL) { @@ -947,15 +701,15 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name); } - if (is_guest_ap == true && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == FULL)) + if (m_is_guest_ap == true && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == FULL)) { - is_guest_ap = false; + m_is_guest_ap = false; IPACMDBG_H("wlan mode is switched to full access mode. \n"); eth_bridge_handle_wlan_mode_switch(); } - else if (is_guest_ap == false && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == INTERNET)) + else if (m_is_guest_ap == false && (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == INTERNET)) { - is_guest_ap = true; + m_is_guest_ap = true; IPACMDBG_H("wlan mode is switched to internet only access mode. \n"); eth_bridge_handle_wlan_mode_switch(); } @@ -963,27 +717,6 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) { IPACMDBG_H("No change in %s access mode. \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); - - /* Handle the WLAN filtering rule */ - for (i=0; i<IPACM_Lan::num_wlan_client; i++) - { - if (IPACM_Lan::eth_bridge_wlan_client[i].ipa_if_num == ipa_if_num) - { - eth_bridge_modify_wlan_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, DST_WLAN, IPA_IP_v4); - eth_bridge_modify_wlan_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, DST_WLAN, IPA_IP_v6); - } - } - /* Handle the LAN filtering rule */ - if (wlan_ap_index == 0 && is_guest_ap == false) - { - IPACMDBG_H("Modify LAN clients filtering rules. \n"); - for (i=0; i<IPACM_Lan::num_lan_client; i++) - { - eth_bridge_modify_wlan_client_flt_rule(IPACM_Lan::eth_bridge_lan_client[i].mac, DST_LAN, IPA_IP_v4); - eth_bridge_modify_wlan_client_flt_rule(IPACM_Lan::eth_bridge_lan_client[i].mac, DST_LAN, IPA_IP_v6); - } - } - IPACMDBG_H("wlan access mode switch is successful. \n"); } } break; @@ -1011,694 +744,6 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) return; } -/*Configure the initial filter rules */ -int IPACM_Wlan::init_fl_rule(ipa_ip_type iptype) -{ - int res = IPACM_SUCCESS, len, offset; - struct ipa_flt_rule_mdfy flt_rule; - struct ipa_ioc_mdfy_flt_rule* pFilteringTable; - - /* 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 res; - } - - 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 res; - } - - 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); - } - - /* ADD corresponding ipa_rm_resource_name of RX-endpoint before adding all IPV4V6 FT-rules */ - 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); - IPACMDBG_H("Add producer dependency from %s with registered rx-prop\n", dev_name); - } - else - { - /* Adding the check if no Rx property registered, no filter rules will be added */ - IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); - return IPACM_SUCCESS; - } -#ifdef FEATURE_ETH_BRIDGE_LE - if(wlan_ap_index != 0) - { - IPACMDBG_H("Install frag/multicast/broadcast rules only for the first AP.\n"); - return IPACM_SUCCESS; - } -#endif - - /* construct ipa_ioc_add_flt_rule with default filter rules */ - if (iptype == IPA_IP_v4) - { - if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) - { - IPACMERR("Dummy ipv4 flt rule has not been installed.\n"); - return IPACM_FAILURE; - } -#ifdef FEATURE_ETH_BRIDGE_LE - offset = 0; -#else -#ifndef CT_OPT - offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); -#else - offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) - + NUM_TCP_CTL_FLT_RULE; -#endif -#endif - -#ifdef FEATURE_IPA_ANDROID - offset = offset + wlan_ap_index * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet); -#endif - len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPV4_DEFAULT_FILTERTING_RULES * sizeof(struct ipa_flt_rule_mdfy)); - pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len); - if (!pFilteringTable) - { - IPACMERR("Error Locate ipa_ioc_mdfy_flt_rule memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - pFilteringTable->commit = 1; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = (uint8_t)IPV4_DEFAULT_FILTERTING_RULES; - - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); - - flt_rule.status = -1; - - flt_rule.rule.retain_hdr = 1; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; - flt_rule.rule.eq_attrib_type = 0; - - /* Configuring Fragment Filtering Rule */ - IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask); - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); -#ifdef FEATURE_ETH_BRIDGE_LE - /* remove meta data mask */ - flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); -#endif - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT; - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset]; - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - - /* Configuring Multicast Filtering Rule */ - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); -#ifdef FEATURE_ETH_BRIDGE_LE - /* remove meta data mask */ - flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); -#endif - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v4.dst_addr_mask = 0xF0000000; - flt_rule.rule.attrib.u.v4.dst_addr = 0xE0000000; - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+1]; - memcpy(&(pFilteringTable->rules[1]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - - /* Configuring Broadcast Filtering Rule */ - flt_rule.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; - flt_rule.rule.attrib.u.v4.dst_addr = 0xFFFFFFFF; - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+2]; - memcpy(&(pFilteringTable->rules[2]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) - { - IPACMERR("Failed to modify default ipv4 filtering rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - /* copy filter hdls */ - for (int i = 0; i < IPV4_DEFAULT_FILTERTING_RULES; i++) - { - if (pFilteringTable->rules[i].status == 0) - { - dft_v4fl_rule_hdl[i] = pFilteringTable->rules[i].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 - { - if(IPACM_Wlan::dummy_flt_rule_hdl_v6 == NULL) - { - IPACMERR("Dummy ipv6 flt rule has not been installed.\n"); - return IPACM_FAILURE; - } -#ifdef FEATURE_ETH_BRIDGE_LE - offset = IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_LAN_CLIENT; -#else -#ifndef CT_OPT - offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR) + MAX_OFFLOAD_PAIR; -#else - offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR) - + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR; -#endif -#endif - - len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPV6_DEFAULT_FILTERTING_RULES * sizeof(struct ipa_flt_rule_mdfy)); - pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len); - if (!pFilteringTable) - { - IPACMERR("Error Locate ipa_ioc_mdfy_flt_rule memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - pFilteringTable->commit = 1; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = (uint8_t)IPV6_DEFAULT_FILTERTING_RULES; - - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); - - flt_rule.status = -1; - - flt_rule.rule.retain_hdr = 1; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; - flt_rule.rule.eq_attrib_type = 0; - - /* Configuring Multicast Filtering Rule */ - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); -#ifdef FEATURE_ETH_BRIDGE_LE - /* remove meta data mask */ - flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); -#endif - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = 0xFF000000; - flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr[0] = 0XFF000000; - flt_rule.rule.attrib.u.v6.dst_addr[1] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr[2] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr[3] = 0X00000000; - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset]; - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - - /* Configuring fe80::/10 Link-Scoped Unicast Filtering Rule */ - flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = 0XFFC00000; - flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr[0] = 0xFE800000; - flt_rule.rule.attrib.u.v6.dst_addr[1] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr[2] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr[3] = 0X00000000; - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+1]; - memcpy(&(pFilteringTable->rules[1]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - - /* Configuring fec0::/10 Reserved by IETF Filtering Rule */ - flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = 0XFFC00000; - flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr[0] = 0xFEC00000; - flt_rule.rule.attrib.u.v6.dst_addr[1] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr[2] = 0x00000000; - flt_rule.rule.attrib.u.v6.dst_addr[3] = 0X00000000; - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+2]; - memcpy(&(pFilteringTable->rules[2]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - -#ifdef FEATURE_IPA_ANDROID - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); - - flt_rule.status = -1; - - flt_rule.rule.retain_hdr = 1; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; - flt_rule.rule.eq_attrib_type = 1; - - flt_rule.rule.eq_attrib.rule_eq_bitmap = 0; - - if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA) - { - flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<14); - flt_rule.rule.eq_attrib.metadata_meq32_present = 1; - flt_rule.rule.eq_attrib.metadata_meq32.offset = 0; - flt_rule.rule.eq_attrib.metadata_meq32.value = rx_prop->rx[0].attrib.meta_data; - flt_rule.rule.eq_attrib.metadata_meq32.mask = rx_prop->rx[0].attrib.meta_data_mask; - } - - flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<1); - flt_rule.rule.eq_attrib.protocol_eq_present = 1; - flt_rule.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP; - - flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<8); - flt_rule.rule.eq_attrib.num_ihl_offset_meq_32 = 1; - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12; - - /* add TCP FIN rule*/ - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_FIN_SHIFT); - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_FIN_SHIFT); - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+3]; - memcpy(&(pFilteringTable->rules[3]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - - /* add TCP SYN rule*/ - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_SYN_SHIFT); - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_SYN_SHIFT); - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+4]; - memcpy(&(pFilteringTable->rules[4]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - - /* add TCP RST rule*/ - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_RST_SHIFT); - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_RST_SHIFT); - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+5]; - memcpy(&(pFilteringTable->rules[5]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); -#endif - - if (m_filtering.ModifyFilteringRule(pFilteringTable) == false) - { - IPACMERR("Failed to modify default ipv6 filtering rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - for (int i = 0; i < IPV6_DEFAULT_FILTERTING_RULES; i++) - { - if (pFilteringTable->rules[i].status == 0) - { - dft_v6fl_rule_hdl[i] = pFilteringTable->rules[i].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(pFilteringTable); - return res; -} - -int IPACM_Wlan::add_dummy_lan2lan_flt_rule(ipa_ip_type iptype) -{ - if(rx_prop == NULL) - { - IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy lan2lan filtering rule.\n", dev_name); - return IPACM_FAILURE; - } - - int offset; - if(iptype == IPA_IP_v4) - { - if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) - { - IPACMERR("Dummy ipv4 flt rule has not been installed.\n"); - return IPACM_FAILURE; - } - -#ifndef CT_OPT - offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) - + IPV4_DEFAULT_FILTERTING_RULES; -#else - offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) - + NUM_TCP_CTL_FLT_RULE + IPV4_DEFAULT_FILTERTING_RULES; -#endif - -#ifdef FEATURE_IPA_ANDROID - offset = offset + wlan_ap_index * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet); -#endif - for (int i = 0; i < MAX_OFFLOAD_PAIR; i++) - { - lan2lan_flt_rule_hdl_v4[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i]; - lan2lan_flt_rule_hdl_v4[i].valid = false; - IPACMDBG_H("Lan2lan v4 flt rule %d hdl:0x%x\n", i, lan2lan_flt_rule_hdl_v4[i].rule_hdl); - } - } - else if(iptype == IPA_IP_v6) - { - if(IPACM_Wlan::dummy_flt_rule_hdl_v6 == NULL) - { - IPACMERR("Dummy ipv6 flt rule has not been installed.\n"); - return IPACM_FAILURE; - } - -#ifndef CT_OPT - offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR); -#else - offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR) - + NUM_TCP_CTL_FLT_RULE; -#endif - - for (int i = 0; i < MAX_OFFLOAD_PAIR; i++) - { - lan2lan_flt_rule_hdl_v6[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+i]; - lan2lan_flt_rule_hdl_v6[i].valid = false; - IPACMDBG_H("Lan2lan v6 flt rule %d hdl:0x%x\n", i, lan2lan_flt_rule_hdl_v6[i].rule_hdl); - } - } - else - { - IPACMERR("IP type is not expected.\n"); - return IPACM_FAILURE; - } - - return IPACM_SUCCESS; -} - -/* configure private subnet filter rules*/ -int IPACM_Wlan::handle_private_subnet(ipa_ip_type iptype) -{ - int i, len, res = IPACM_SUCCESS, offset; - struct ipa_flt_rule_mdfy flt_rule; - struct ipa_ioc_mdfy_flt_rule* pFilteringTable; - - if (rx_prop == NULL) - { - IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); - return IPACM_SUCCESS; - } - - if (iptype == IPA_IP_v4) - { - if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) - { - IPACMERR("Dummy ipv4 flt rule has not been installed.\n"); - return IPACM_FAILURE; - } -#ifdef FEATURE_ETH_BRIDGE_LE - offset = IPV4_DEFAULT_FILTERTING_RULES + IPACM_Iface::ipacmcfg->ipa_num_private_subnet + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_LAN_CLIENT; -#else -#ifndef CT_OPT - offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) - + IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR; -#else - offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) - + IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR; -#endif -#endif - - len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_mdfy); - pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); - if (!pFilteringTable) - { - IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - pFilteringTable->commit = 1; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet; - - /* Make LAN-traffic always go A5, use default IPA-RT table */ - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); - flt_rule.status = -1; - - flt_rule.rule.retain_hdr = 1; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_ROUTING; - flt_rule.rule.eq_attrib_type = 0; - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl; - IPACMDBG_H("Private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name); - - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; -#ifdef FEATURE_ETH_BRIDGE_LE - /* remove meta data mask */ - flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); -#endif - - for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++) - { - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i]; - flt_rule.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask; - flt_rule.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr; - memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - } - - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) - { - IPACMERR("Failed to modify private subnet filtering rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - - /* copy filter rule hdls */ - for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++) - { - private_fl_rule_hdl[i] = pFilteringTable->rules[i].rule_hdl; - } - } - else - { - return IPACM_SUCCESS; - } -fail: - free(pFilteringTable); - return res; -} - -/* install UL filter rule from Q6 */ -int IPACM_Wlan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptype, uint8_t xlat_mux_id) -{ - ipa_flt_rule_add flt_rule_entry; - int len = 0, cnt, ret = IPACM_SUCCESS, index; - ipa_ioc_add_flt_rule *pFilteringTable; - ipa_fltr_installed_notif_req_msg_v01 flt_index; - int fd, i; - uint32_t value = 0; - - IPACMDBG_H("Set extended property rules in WLAN\n"); - - if (rx_prop == NULL) - { - IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); - return IPACM_SUCCESS; - } - - if(prop == NULL || prop->num_ext_props <= 0) - { - IPACMDBG_H("No extended property.\n"); - return IPACM_SUCCESS; - } - - if(wlan_ap_index > 0) - { - IPACMDBG_H("This is not the first WLAN AP, do not install modem UL rules.\n"); - return IPACM_SUCCESS; - } - - fd = open(IPA_DEVICE_NAME, O_RDWR); - if (0 == fd) - { - IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); - return IPACM_FAILURE; - } - if (prop->num_ext_props > MAX_WAN_UL_FILTER_RULES) - { - IPACMERR("number of modem UL rules > MAX_WAN_UL_FILTER_RULES, aborting...\n"); - close(fd); - return IPACM_FAILURE; - } - - memset(&flt_index, 0, sizeof(flt_index)); - flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe); - flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01; -#ifndef FEATURE_IPA_V3 - flt_index.filter_index_list_len = prop->num_ext_props; -#else /* defined (FEATURE_IPA_V3) */ - flt_index.rule_id_valid = 1; - flt_index.rule_id_len = prop->num_ext_props; -#endif - flt_index.embedded_pipe_index_valid = 1; - flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD); - flt_index.retain_header_valid = 1; - flt_index.retain_header = 0; - flt_index.embedded_call_mux_id_valid = 1; - flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId(); -#ifndef FEATURE_IPA_V3 - IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d\n", - flt_index.source_pipe_index, flt_index.filter_index_list_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id); -#else /* defined (FEATURE_IPA_V3) */ - IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d\n", - flt_index.source_pipe_index, flt_index.rule_id_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id); -#endif - len = sizeof(struct ipa_ioc_add_flt_rule) + prop->num_ext_props * sizeof(struct ipa_flt_rule_add); - pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len); - if (pFilteringTable == NULL) - { - IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); - close(fd); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - pFilteringTable->commit = 1; - pFilteringTable->ep = rx_prop->rx[0].src_pipe; - pFilteringTable->global = false; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = prop->num_ext_props; - - memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); // Zero All Fields - flt_rule_entry.at_rear = 1; -#ifdef FEATURE_IPA_V3 - if (flt_rule_entry.rule.eq_attrib.ipv4_frag_eq_present) - flt_rule_entry.at_rear = 0; -#endif - flt_rule_entry.flt_rule_hdl = -1; - flt_rule_entry.status = -1; - - flt_rule_entry.rule.retain_hdr = 0; - flt_rule_entry.rule.to_uc = 0; - flt_rule_entry.rule.eq_attrib_type = 1; - if(iptype == IPA_IP_v4) - flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; - else if(iptype == IPA_IP_v6) - flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; - else - { - IPACMERR("IP type is not expected.\n"); - ret = IPACM_FAILURE; - goto fail; - } - - index = IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, iptype); - -#ifndef FEATURE_IPA_ANDROID - if(iptype == IPA_IP_v4 && index != exp_index_v4) - { - IPACMDBG_DMESG("### WARNING ### num flt rules for IPv4 on client %d is not expected: %d expected value: %d", - rx_prop->rx[0].src_pipe, index, exp_index_v4); - } - if(iptype == IPA_IP_v6 && index != exp_index_v6) - { - IPACMDBG_DMESG("### WARNING ### num flt rules for IPv6 on client %d is not expected: %d expected value: %d", - rx_prop->rx[0].src_pipe, index, exp_index_v6); - } -#endif - - for(cnt=0; cnt<prop->num_ext_props; cnt++) - { - memcpy(&flt_rule_entry.rule.eq_attrib, - &prop->prop[cnt].eq_attrib, - sizeof(prop->prop[cnt].eq_attrib)); - flt_rule_entry.rule.rt_tbl_idx = prop->prop[cnt].rt_tbl_idx; - - /* Handle XLAT configuration */ - if ((iptype == IPA_IP_v4) && prop->prop[cnt].is_xlat_rule && (xlat_mux_id != 0)) - { - /* fill the value of meta-data */ - value = xlat_mux_id; - 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 = (value & 0xFF) << 16; - flt_rule_entry.rule.eq_attrib.metadata_meq32.mask = 0x00FF0000; - IPACMDBG_H("xlat meta-data is modified for rule: %d has index: %d with xlat_mux_id: %d\n", - cnt, index, xlat_mux_id); - } -#ifdef FEATURE_IPA_V3 - flt_rule_entry.rule.hashable = prop->prop[cnt].is_rule_hashable; - flt_rule_entry.rule.rule_id = prop->prop[cnt].rule_id; -#endif - memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry)); - - IPACMDBG_H("Modem UL filtering rule %d has index %d\n", cnt, index); -#ifndef FEATURE_IPA_V3 - flt_index.filter_index_list[cnt].filter_index = index; - flt_index.filter_index_list[cnt].filter_handle = prop->prop[cnt].filter_hdl; -#else /* defined (FEATURE_IPA_V3) */ - flt_index.rule_id[cnt] = prop->prop[cnt].rule_id; -#endif - index++; - } - - if(false == m_filtering.SendFilteringRuleIndex(&flt_index)) - { - IPACMERR("Error sending filtering rule index, aborting...\n"); - ret = IPACM_FAILURE; - goto fail; - } - - if(false == m_filtering.AddFilteringRule(pFilteringTable)) - { - IPACMERR("Error Adding RuleTable to Filtering, aborting...\n"); - ret = IPACM_FAILURE; - goto fail; - } - else - { - if(iptype == IPA_IP_v4) - { - for(i=0; i<pFilteringTable->num_rules; i++) - { - wan_ul_fl_rule_hdl_v4[num_wan_ul_fl_rule_v4] = pFilteringTable->rules[i].flt_rule_hdl; - num_wan_ul_fl_rule_v4++; - } - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules); - } - else if(iptype == IPA_IP_v6) - { - for(i=0; i<pFilteringTable->num_rules; i++) - { - wan_ul_fl_rule_hdl_v6[num_wan_ul_fl_rule_v6] = pFilteringTable->rules[i].flt_rule_hdl; - num_wan_ul_fl_rule_v6++; - } - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules); - } - else - { - IPACMERR("IP type is not expected.\n"); - goto fail; - } - } - -fail: - free(pFilteringTable); - close(fd); - return ret; -} - /* handle wifi client initial,copy all partial headers (tx property) */ int IPACM_Wlan::handle_wlan_client_init_ex(ipacm_event_data_wlan_ex *data) { @@ -1996,6 +1041,8 @@ int IPACM_Wlan::handle_wlan_client_ipaddr(ipacm_event_data_all *data) { int clnt_indx; int v6_num; + uint32_t ipv6_link_local_prefix = 0xFE800000; + uint32_t ipv6_link_local_prefix_mask = 0xFFC00000; IPACMDBG_H("number of wifi clients: %d\n", num_wifi_client); IPACMDBG_H(" event MAC %02x:%02x:%02x:%02x:%02x:%02x\n", @@ -2055,22 +1102,29 @@ int IPACM_Wlan::handle_wlan_client_ipaddr(ipacm_event_data_all *data) if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) || (data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] || 0)) /* check if all 0 not valid ipv6 address */ { - IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); - if(get_client_memptr(wlan_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR) - { + IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); + if( (data->ipv6_addr[0] & ipv6_link_local_prefix_mask) != (ipv6_link_local_prefix & ipv6_link_local_prefix_mask) && + memcmp(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)) != 0) + { + IPACMDBG_H("This IPv6 address is not global IPv6 address with correct prefix, ignore.\n"); + return IPACM_FAILURE; + } + + if(get_client_memptr(wlan_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR) + { for(v6_num=0;v6_num < get_client_memptr(wlan_client, clnt_indx)->ipv6_set;v6_num++) - { - if( data->ipv6_addr[0] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][0] && + { + if( data->ipv6_addr[0] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][0] && data->ipv6_addr[1] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][1] && data->ipv6_addr[2]== get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][2] && data->ipv6_addr[3] == get_client_memptr(wlan_client, clnt_indx)->v6_addr[v6_num][3]) - { + { IPACMDBG_H("Already see this ipv6 addr for client:%d\n", clnt_indx); return IPACM_FAILURE; /* not setup the RT rules*/ break; - } - } + } + } /* not see this ipv6 before for wifi client*/ get_client_memptr(wlan_client, clnt_indx)->v6_addr[get_client_memptr(wlan_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0]; @@ -2081,8 +1135,8 @@ int IPACM_Wlan::handle_wlan_client_ipaddr(ipacm_event_data_all *data) } else { - IPACMDBG_H("Already got 3 ipv6 addr for client:%d\n", clnt_indx); - return IPACM_FAILURE; /* not setup the RT rules*/ + IPACMDBG_H("Already got %d ipv6 addr for client:%d\n", IPV6_NUM_ADDR, clnt_indx); + return IPACM_FAILURE; /* not setup the RT rules*/ } } } @@ -2204,6 +1258,9 @@ int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type ipt rt_rule_entry->rule.hdr_hdl = get_client_memptr(wlan_client, wlan_index)->hdr_hdl_v4; rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wlan_client, wlan_index)->v4_addr; rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -2243,6 +1300,9 @@ int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type ipt rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -2283,6 +1343,9 @@ int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type ipt rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; +#ifdef FEATURE_IPA_V3 + rt_rule_entry->rule.hashable = true; +#endif if (false == m_routing.AddRoutingRule(rt_rule)) { IPACMERR("Routing rule addition failed!\n"); @@ -2468,7 +1531,7 @@ int IPACM_Wlan::handle_wlan_client_down_evt(uint8_t *mac_addr) /*handle wlan iface down event*/ int IPACM_Wlan::handle_down_evt() { - int res = IPACM_SUCCESS, i; + int res = IPACM_SUCCESS, i, num_private_subnet_fl_rule; IPACMDBG_H("WLAN ip-type: %d \n", ip_type); /* no iface address up, directly close iface*/ @@ -2477,14 +1540,6 @@ int IPACM_Wlan::handle_down_evt() IPACMERR("Invalid iptype: 0x%x\n", ip_type); goto fail; } -#ifdef FEATURE_ETH_BRIDGE_LE - if(wlan_ap_index == 0) - { - IPACM_Lan::wlan_hdr_type = IPA_HDR_L2_NONE; - IPACM_Lan::wlan_hdr_template_hdl = 0; - del_hdr_proc_ctx(); - } -#endif /* delete wan filter rule */ if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL) @@ -2504,163 +1559,66 @@ int IPACM_Wlan::handle_down_evt() if (ip_type != IPA_IP_v6 && rx_prop != NULL) { /* delete IPv4 icmp filter rules */ - if(wlan_ap_index == 0) + if(m_filtering.DeleteFilteringHdls(ipv4_icmp_flt_rule_hdl, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE) == false) { - if(m_filtering.DeleteFilteringHdls(ipv4_icmp_flt_rule_hdl, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE) == false) - { - IPACMERR("Error Deleting ICMPv4 Filtering Rule, aborting...\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE); - } -#ifdef FEATURE_ETH_BRIDGE_LE - if(wlan_ap_index == 0) - { - /* delete default filter rules */ - for(i=0; i<IPV4_DEFAULT_FILTERTING_RULES; i++) - { - if(reset_to_dummy_flt_rule(IPA_IP_v4, dft_v4fl_rule_hdl[i]) == IPACM_FAILURE) - { - IPACMERR("Error deleting dft IPv4 flt rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - } + IPACMERR("Error Deleting ICMPv4 Filtering Rule, aborting...\n"); + res = IPACM_FAILURE; + goto fail; } -#else - /* delete default filter rules */ - for(i=0; i<IPV4_DEFAULT_FILTERTING_RULES; i++) + IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE); + + if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES) == false) { - if(reset_to_dummy_flt_rule(IPA_IP_v4, dft_v4fl_rule_hdl[i]) == IPACM_FAILURE) - { - IPACMERR("Error deleting dft IPv4 flt rules.\n"); - res = IPACM_FAILURE; - goto fail; - } + IPACMERR("Error Deleting Filtering Rule, aborting...\n"); + res = IPACM_FAILURE; + goto fail; } -#endif + IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES); IPACMDBG_H("Deleted default v4 filter rules successfully.\n"); -#ifndef FEATURE_ETH_BRIDGE_LE -#ifdef CT_OPT - IPACMDBG_H("Delete tcp control flt rules.\n"); - /* Delete tcp control flt rules */ - for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++) - { - if(reset_to_dummy_flt_rule(IPA_IP_v4, tcp_ctl_flt_rule_hdl_v4[i]) == IPACM_FAILURE) - { - res = IPACM_FAILURE; - goto fail; - } - } -#endif - IPACMDBG_H("Delete lan2lan v4 flt rules.\n"); - /* delete lan2lan ipv4 flt rules */ - for(i=0; i<MAX_OFFLOAD_PAIR; i++) - { - if(reset_to_dummy_flt_rule(IPA_IP_v4, lan2lan_flt_rule_hdl_v4[i].rule_hdl) == IPACM_FAILURE) - { - IPACMERR("Error deleting lan2lan IPv4 flt rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - } -#endif - IPACMDBG_H("Delete private v4 filter rules\n"); /* delete private-ipv4 filter rules */ #ifdef FEATURE_IPA_ANDROID - for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++) + if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES) == false) { - if(reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]) == IPACM_FAILURE) - { - IPACMERR("Error deleting private subnet IPv4 flt rules.\n"); - res = IPACM_FAILURE; - goto fail; - } + IPACMERR("Error deleting private subnet IPv4 flt rules.\n"); + res = IPACM_FAILURE; + goto fail; } + IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES); #else - if(wlan_ap_index == 0) + num_private_subnet_fl_rule = IPACM_Iface::ipacmcfg->ipa_num_private_subnet > IPA_MAX_PRIVATE_SUBNET_ENTRIES? + IPA_MAX_PRIVATE_SUBNET_ENTRIES : IPACM_Iface::ipacmcfg->ipa_num_private_subnet; + if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, num_private_subnet_fl_rule) == false) { - for(i=0; i<IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++) - { - if(reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]) == IPACM_FAILURE) - { - IPACMERR("Error deleting private subnet IPv4 flt rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - } + IPACMERR("Error deleting private subnet flt rules, aborting...\n"); + res = IPACM_FAILURE; + goto fail; } - IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n"); + IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_private_subnet_fl_rule); #endif + IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n"); } /* Delete v6 filtering rules */ if (ip_type != IPA_IP_v4 && rx_prop != NULL) { /* delete icmp filter rules */ - if(wlan_ap_index == 0) + if(m_filtering.DeleteFilteringHdls(ipv6_icmp_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE) == false) { - if(m_filtering.DeleteFilteringHdls(ipv6_icmp_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE) == false) - { - IPACMERR("Error Deleting ICMPv6 Filtering Rule, aborting...\n"); - res = IPACM_FAILURE; - goto fail; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE); - } - IPACMDBG_H("Delete default %d v6 filter rules\n", IPV6_DEFAULT_FILTERTING_RULES); - /* delete default filter rules */ -#ifdef FEATURE_ETH_BRIDGE_LE - if(wlan_ap_index == 0) - { - for(i=0; i<IPV6_DEFAULT_FILTERTING_RULES; i++) - { - if(reset_to_dummy_flt_rule(IPA_IP_v6, dft_v6fl_rule_hdl[i]) == IPACM_FAILURE) - { - res = IPACM_FAILURE; - goto fail; - } - } - } -#else - for(i=0; i<IPV6_DEFAULT_FILTERTING_RULES; i++) - { - if(reset_to_dummy_flt_rule(IPA_IP_v6, dft_v6fl_rule_hdl[i]) == IPACM_FAILURE) - { - res = IPACM_FAILURE; - goto fail; - } + IPACMERR("Error Deleting ICMPv6 Filtering Rule, aborting...\n"); + res = IPACM_FAILURE; + goto fail; } -#endif - IPACMDBG_H("Deleted default v6 filter rules successfully.\n"); + IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE); -#ifndef FEATURE_ETH_BRIDGE_LE -#ifdef CT_OPT - IPACMDBG_H("Delete tcp control flt rules.\n"); - /* Delete tcp control flt rules */ - for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++) + if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES) == false) { - if(reset_to_dummy_flt_rule(IPA_IP_v6, tcp_ctl_flt_rule_hdl_v6[i]) == IPACM_FAILURE) - { - res = IPACM_FAILURE; - goto fail; - } - } -#endif - IPACMDBG_H("Delete lan2lan v6 flt rules.\n"); - /* delete lan2lan ipv4 flt rules */ - for(i=0; i<MAX_OFFLOAD_PAIR; i++) - { - if(reset_to_dummy_flt_rule(IPA_IP_v6, lan2lan_flt_rule_hdl_v6[i].rule_hdl) == IPACM_FAILURE) - { - IPACMERR("Error deleting lan2lan IPv4 flt rules.\n"); - res = IPACM_FAILURE; - goto fail; - } + IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n"); + res = IPACM_FAILURE; + goto fail; } -#endif + IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES); + IPACMDBG_H("Deleted default v6 filter rules successfully.\n"); } IPACMDBG_H("finished delete filtering rules\n "); @@ -2708,18 +1666,10 @@ int IPACM_Wlan::handle_down_evt() /* clean wifi client rule*/ IPACMDBG_H("left %d wifi clients need to be deleted \n ", num_wifi_client); + eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL); + for (i = 0; i < num_wifi_client; i++) { -#ifdef FEATURE_ETH_BRIDGE_LE - eth_bridge_del_self_client_flt_rule(get_client_memptr(wlan_client, i)->mac); - eth_bridge_del_wlan_client_rt_rule(get_client_memptr(wlan_client, i)->mac, SRC_WLAN); - eth_bridge_del_wlan_client(get_client_memptr(wlan_client, i)->mac); - if (is_guest_ap == false) - { - eth_bridge_del_wlan_client_rt_rule(get_client_memptr(wlan_client, i)->mac, SRC_LAN); - eth_bridge_post_lan_client_event(get_client_memptr(wlan_client, i)->mac, IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT); - } -#endif /* First reset nat rules and then route rules */ if(get_client_memptr(wlan_client, i)->ipv4_set == true) { @@ -2743,9 +1693,6 @@ int IPACM_Wlan::handle_down_evt() IPACMDBG_H("Delete %d client header\n", num_wifi_client); - handle_lan2lan_msg_post(get_client_memptr(wlan_client, i)->mac, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v4); - handle_lan2lan_msg_post(get_client_memptr(wlan_client, i)->mac, IPA_LAN_CLIENT_DISCONNECT, IPA_IP_v6); - if(get_client_memptr(wlan_client, i)->ipv4_header_set == true) { if (m_header.DeleteHeaderHdl(get_client_memptr(wlan_client, i)->hdr_hdl_v4) @@ -2815,40 +1762,7 @@ fail: { free(iface_query); } -#ifdef FEATURE_ETH_BRIDGE_LE - if(eth_bridge_lan_client_rt_from_lan_info_v4 != NULL) - { - free(eth_bridge_lan_client_rt_from_lan_info_v4); - } - if(eth_bridge_lan_client_rt_from_lan_info_v6 != NULL) - { - free(eth_bridge_lan_client_rt_from_lan_info_v6); - } - if(eth_bridge_lan_client_rt_from_wlan_info_v4 != NULL) - { - free(eth_bridge_lan_client_rt_from_wlan_info_v4); - } - if(eth_bridge_lan_client_rt_from_wlan_info_v6 != NULL) - { - free(eth_bridge_lan_client_rt_from_wlan_info_v6); - } - if(eth_bridge_wlan_client_rt_from_lan_info_v4 != NULL) - { - free(eth_bridge_wlan_client_rt_from_lan_info_v4); - } - if(eth_bridge_wlan_client_rt_from_lan_info_v6 != NULL) - { - free(eth_bridge_wlan_client_rt_from_lan_info_v6); - } - if(eth_bridge_wlan_client_rt_from_wlan_info_v4 != NULL) - { - free(eth_bridge_wlan_client_rt_from_wlan_info_v4); - } - if(eth_bridge_wlan_client_rt_from_wlan_info_v6 != NULL) - { - free(eth_bridge_wlan_client_rt_from_wlan_info_v6); - } -#endif + is_active = false; post_del_self_evt(); @@ -2872,13 +1786,7 @@ int IPACM_Wlan::handle_wlan_client_reset_rt(ipa_ip_type iptype) IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype); return res; } - /* Pass info to LAN2LAN module */ - res = handle_lan2lan_msg_post(get_client_memptr(wlan_client, i)->mac, IPA_LAN_CLIENT_DISCONNECT, iptype); - if (res != IPACM_SUCCESS) - { - IPACMERR("Failed to posting delete old iptype(%d) address.\n", iptype); - return res; - } + /* Reset ip-address */ if(iptype == IPA_IP_v4) { @@ -2892,1942 +1800,6 @@ int IPACM_Wlan::handle_wlan_client_reset_rt(ipa_ip_type iptype) return res; } -/*handle lan2lan internal mesg posting*/ -int IPACM_Wlan::handle_lan2lan_msg_post(uint8_t *mac_addr, ipa_cm_event_id event,ipa_ip_type iptype) -{ - int client_index; - client_index = get_wlan_client_index(mac_addr); - if (client_index == IPACM_INVALID_INDEX) - { - IPACMDBG_H("wlan client not attached\n"); - return IPACM_SUCCESS; - } - - ipacm_event_lan_client* lan_client; - ipacm_cmd_q_data evt_data; - if((get_client_memptr(wlan_client, client_index)->ipv4_set == true) - && (iptype == IPA_IP_v4)) /* handle ipv4 case*/ - { - if(ip_type != IPA_IP_v4 && ip_type != IPA_IP_MAX) - { - IPACMERR("Client has IPv4 addr but iface does not have IPv4 up.\n"); - return IPACM_FAILURE; - } - - lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client)); - if(lan_client == NULL) - { - IPACMERR("Unable to allocate memory.\n"); - return IPACM_FAILURE; - } - memset(lan_client, 0, sizeof(ipacm_event_lan_client)); - - lan_client->iptype = IPA_IP_v4; - lan_client->ipv4_addr = get_client_memptr(wlan_client, client_index)->v4_addr; - lan_client->p_iface = this; - - memset(&evt_data, 0, sizeof(evt_data)); - evt_data.event = event; - evt_data.evt_data = (void*)lan_client; - - IPACMDBG_H("Posting event: %d\n",event); - IPACM_EvtDispatcher::PostEvt(&evt_data); - } - - if((get_client_memptr(wlan_client, client_index)->ipv6_set > 0) - && (iptype == IPA_IP_v6)) /* handle v6 case: may be multiple v6 addr */ - { - if(ip_type != IPA_IP_v6 && ip_type != IPA_IP_MAX) - { - IPACMERR("Client has IPv6 addr but iface does not have IPv6 up.\n"); - return IPACM_FAILURE; - } - int i; - - for(i=0; i<get_client_memptr(wlan_client, client_index)->ipv6_set; i++) - { - lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client)); - if(lan_client == NULL) - { - IPACMERR("Unable to allocate memory.\n"); - return IPACM_FAILURE; - } - memset(lan_client, 0, sizeof(ipacm_event_lan_client)); - - lan_client->iptype = IPA_IP_v6; - memcpy(lan_client->ipv6_addr, get_client_memptr(wlan_client, client_index)->v6_addr[i], 4*sizeof(uint32_t)); - lan_client->p_iface = this; - - memset(&evt_data, 0, sizeof(evt_data)); - evt_data.event = event; - evt_data.evt_data = (void*)lan_client; - - IPACMDBG_H("Posting event: %d\n",event); - IPACM_EvtDispatcher::PostEvt(&evt_data); - } - } - return IPACM_SUCCESS; -} - -int IPACM_Wlan::add_lan2lan_hdr(ipa_ip_type iptype, uint8_t* src_mac, uint8_t* dst_mac, uint32_t* hdr_hdl) -{ - if(tx_prop == NULL) - { - IPACMERR("There is no tx_prop, cannot add header.\n"); - return IPACM_FAILURE; - } - if(src_mac == NULL || dst_mac == NULL) - { - IPACMERR("Either src_mac or dst_mac is null, cannot add header.\n"); - return IPACM_FAILURE; - } - if(hdr_hdl == NULL) - { - IPACMERR("Header handle is empty.\n"); - return IPACM_FAILURE; - } - - int i, j, k, len; - int res = IPACM_SUCCESS; - char index[4]; - struct ipa_ioc_copy_hdr sCopyHeader; - struct ipa_ioc_add_hdr *pHeader; - - IPACMDBG_H("Get lan2lan header request, src_mac: 0x%02x%02x%02x%02x%02x%02x dst_mac: 0x%02x%02x%02x%02x%02x%02x\n", - src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5], dst_mac[0], dst_mac[1], - dst_mac[2], dst_mac[3], dst_mac[4], dst_mac[5]); - - len = sizeof(struct ipa_ioc_add_hdr) + sizeof(struct ipa_hdr_add); - pHeader = (struct ipa_ioc_add_hdr *)malloc(len); - if (pHeader == NULL) - { - IPACMERR("Failed to allocate header\n"); - return IPACM_FAILURE; - } - memset(pHeader, 0, len); - - if(iptype == IPA_IP_v4) - { /* copy partial header for v4*/ - for(i=0; i<tx_prop->num_tx_props; i++) - { - if(tx_prop->tx[i].ip == IPA_IP_v4) - { - IPACMDBG_H("Got v4-header name from %d tx props\n", i); - memset(&sCopyHeader, 0, sizeof(sCopyHeader)); - memcpy(sCopyHeader.name, tx_prop->tx[i].hdr_name, sizeof(sCopyHeader.name)); - - IPACMDBG_H("Header name: %s\n", sCopyHeader.name); - if(m_header.CopyHeader(&sCopyHeader) == false) - { - IPACMERR("Copy header failed\n"); - res = IPACM_FAILURE; - goto fail; - } - - IPACMDBG_H("Header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); - if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) - { - IPACMERR("Header oversize\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - memcpy(pHeader->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); - } - - for(j=0; j<num_wifi_client; j++) //Add src/dst mac to the header - { - if(memcmp(dst_mac, get_client_memptr(wlan_client, j)->mac, IPA_MAC_ADDR_SIZE) == 0) - { - break; - } - } - if(j == num_wifi_client) - { - IPACMERR("Not able to find the wifi client from mac addr.\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACMDBG_H("Find wifi client at position %d\n", j); - for(k = 0; k < get_client_memptr(wlan_client, j)->p_hdr_info->num_of_attribs; k++) - { - if(get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR) - { - memcpy(&pHeader->hdr[0].hdr[get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].offset], - dst_mac, IPA_MAC_ADDR_SIZE); - memcpy(&pHeader->hdr[0].hdr[get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].offset + IPA_MAC_ADDR_SIZE], - src_mac, IPA_MAC_ADDR_SIZE); - } - else if(get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].attrib_type == WLAN_HDR_ATTRIB_STA_ID) - { - memcpy(&pHeader->hdr[0].hdr[get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].offset], - &get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].u.sta_id, - sizeof(get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].u.sta_id)); - } - else - { - IPACMDBG_H("The attribute type is not expected!\n"); - } - } - } - - pHeader->commit = true; - pHeader->num_hdrs = 1; - - memset(pHeader->hdr[0].name, 0, sizeof(pHeader->hdr[0].name)); - strlcpy(pHeader->hdr[0].name, IPA_LAN_TO_LAN_WLAN_HDR_NAME_V4, sizeof(pHeader->hdr[0].name)); - pHeader->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0'; - for(j=0; j<MAX_OFFLOAD_PAIR; j++) - { - if( lan2lan_hdr_hdl_v4[j].valid == false) - { - IPACMDBG_H("Construct lan2lan hdr with index %d.\n", j); - break; - } - } - if(j == MAX_OFFLOAD_PAIR) - { - IPACMERR("Failed to find an available hdr index.\n"); - res = IPACM_FAILURE; - goto fail; - } - lan2lan_hdr_hdl_v4[j].valid = true; - snprintf(index,sizeof(index), "%d", j); - - if (strlcat(pHeader->hdr[0].name, index, sizeof(pHeader->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) - { - IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeader->hdr[0].name)); - res = IPACM_FAILURE; - goto fail; - } - - pHeader->hdr[0].hdr_len = sCopyHeader.hdr_len; - pHeader->hdr[0].is_partial = 0; - pHeader->hdr[0].hdr_hdl = -1; - pHeader->hdr[0].status = -1; - - if (m_header.AddHeader(pHeader) == false || pHeader->hdr[0].status != 0) - { - IPACMERR("Ioctl IPA_IOC_ADD_HDR failed with status: %d\n", pHeader->hdr[0].status); - res = IPACM_FAILURE; - goto fail; - } - IPACMDBG_H("Installed v4 full header %s header handle 0x%08x\n", pHeader->hdr[0].name, - pHeader->hdr[0].hdr_hdl); - *hdr_hdl = pHeader->hdr[0].hdr_hdl; - lan2lan_hdr_hdl_v4[j].hdr_hdl = pHeader->hdr[0].hdr_hdl; - break; - } - } - } - else if(iptype == IPA_IP_v6) - { /* copy partial header for v6*/ - for(i=0; i<tx_prop->num_tx_props; i++) - { - if(tx_prop->tx[i].ip == IPA_IP_v6) - { - IPACMDBG_H("Got v6-header name from %d tx props\n", i); - memset(&sCopyHeader, 0, sizeof(sCopyHeader)); - memcpy(sCopyHeader.name, tx_prop->tx[i].hdr_name, sizeof(sCopyHeader.name)); - - IPACMDBG_H("Header name: %s\n", sCopyHeader.name); - if(m_header.CopyHeader(&sCopyHeader) == false) - { - IPACMERR("Copy header failed\n"); - res = IPACM_FAILURE; - goto fail; - } - - IPACMDBG_H("Header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); - if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) - { - IPACMERR("Header oversize\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - memcpy(pHeader->hdr[0].hdr, sCopyHeader.hdr, sCopyHeader.hdr_len); - } - - for(j=0; j<num_wifi_client; j++) //Add src/dst mac to the header - { - if(memcmp(dst_mac, get_client_memptr(wlan_client, j)->mac, IPA_MAC_ADDR_SIZE) == 0) - { - break; - } - } - if(j == num_wifi_client) - { - IPACMERR("Not able to find the wifi client from mac addr.\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACMDBG_H("Find wifi client at position %d\n", j); - for(k = 0; k < get_client_memptr(wlan_client, j)->p_hdr_info->num_of_attribs; k++) - { - if(get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR) - { - memcpy(&pHeader->hdr[0].hdr[get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].offset], - dst_mac, IPA_MAC_ADDR_SIZE); - memcpy(&pHeader->hdr[0].hdr[get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].offset + IPA_MAC_ADDR_SIZE], - src_mac, IPA_MAC_ADDR_SIZE); - } - else if(get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].attrib_type == WLAN_HDR_ATTRIB_STA_ID) - { - memcpy(&pHeader->hdr[0].hdr[get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].offset], - &get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].u.sta_id, - sizeof(get_client_memptr(wlan_client, j)->p_hdr_info->attribs[k].u.sta_id)); - } - else - { - IPACMDBG_H("The attribute type is not expected!\n"); - } - } - } - - pHeader->commit = true; - pHeader->num_hdrs = 1; - - memset(pHeader->hdr[0].name, 0, sizeof(pHeader->hdr[0].name)); - strlcpy(pHeader->hdr[0].name, IPA_LAN_TO_LAN_WLAN_HDR_NAME_V6, sizeof(pHeader->hdr[0].name)); - pHeader->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0'; - - for(j=0; j<MAX_OFFLOAD_PAIR; j++) - { - if( lan2lan_hdr_hdl_v6[j].valid == false) - { - IPACMDBG_H("Construct lan2lan hdr with index %d.\n", j); - break; - } - } - if(j == MAX_OFFLOAD_PAIR) - { - IPACMERR("Failed to find an available hdr index.\n"); - res = IPACM_FAILURE; - goto fail; - } - lan2lan_hdr_hdl_v6[j].valid = true; - snprintf(index,sizeof(index), "%d", j); - - if (strlcat(pHeader->hdr[0].name, index, sizeof(pHeader->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) - { - IPACMERR(" header name construction failed exceed length (%d)\n", strlen(pHeader->hdr[0].name)); - res = IPACM_FAILURE; - goto fail; - } - pHeader->hdr[0].hdr_len = sCopyHeader.hdr_len; - pHeader->hdr[0].is_partial = 0; - pHeader->hdr[0].hdr_hdl = -1; - pHeader->hdr[0].status = -1; - - if (m_header.AddHeader(pHeader) == false || pHeader->hdr[0].status != 0) - { - IPACMERR("Ioctl IPA_IOC_ADD_HDR failed with status: %d\n", pHeader->hdr[0].status); - res = IPACM_FAILURE; - goto fail; - } - IPACMDBG_H("Installed v6 full header %s header handle 0x%08x\n", pHeader->hdr[0].name, - pHeader->hdr[0].hdr_hdl); - *hdr_hdl = pHeader->hdr[0].hdr_hdl; - lan2lan_hdr_hdl_v6[j].hdr_hdl = pHeader->hdr[0].hdr_hdl; - break; - } - } - } - else - { - IPACMERR("IP type is not expected.\n"); - } - -fail: - free(pHeader); - return res; -} - -/* add dummy filtering rules for WLAN AP-AP mode support */ -void IPACM_Wlan::add_dummy_flt_rule() -{ - int num_v4_dummy_rule, num_v6_dummy_rule; - - if(IPACM_Wlan::num_wlan_ap_iface == 1) - { - if(IPACM_Wlan::dummy_flt_rule_hdl_v4 != NULL || IPACM_Wlan::dummy_flt_rule_hdl_v6 != NULL) - { - IPACMERR("Either v4 or v6 dummy filtering rule handle is not empty.\n"); - return; - } -#ifdef FEATURE_ETH_BRIDGE_LE - num_v4_dummy_rule = IPV4_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_LAN_CLIENT + IPACM_Iface::ipacmcfg->ipa_num_private_subnet; - num_v6_dummy_rule = IPV6_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_LAN_CLIENT + 2 * NUM_IPV6_PREFIX_FLT_RULE; -#else -#ifndef CT_OPT - num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); - num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_IPV6_PREFIX_FLT_RULE); -#else - num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); - num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + NUM_IPV6_PREFIX_FLT_RULE); -#endif -#ifdef FEATURE_IPA_ANDROID - num_v4_dummy_rule = num_v4_dummy_rule - 2* IPACM_Iface::ipacmcfg->ipa_num_private_subnet + 2 * IPA_MAX_PRIVATE_SUBNET_ENTRIES; -#endif -#endif - - IPACM_Wlan::dummy_flt_rule_hdl_v4 = (uint32_t*)malloc(num_v4_dummy_rule * sizeof(uint32_t)); - if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) - { - IPACMERR("Failed to allocate memory.\n"); - return; - } - IPACM_Wlan::dummy_flt_rule_hdl_v6 = (uint32_t*)malloc(num_v6_dummy_rule * sizeof(uint32_t)); - if(IPACM_Wlan::dummy_flt_rule_hdl_v6 == NULL) - { - IPACMERR("Failed to allocate memory.\n"); - free(IPACM_Wlan::dummy_flt_rule_hdl_v4); - IPACM_Wlan::dummy_flt_rule_hdl_v4 = NULL; - return; - } - memset(IPACM_Wlan::dummy_flt_rule_hdl_v4, 0, num_v4_dummy_rule * sizeof(uint32_t)); - memset(IPACM_Wlan::dummy_flt_rule_hdl_v6, 0, num_v6_dummy_rule * sizeof(uint32_t)); - - install_dummy_flt_rule(IPA_IP_v4, num_v4_dummy_rule); - install_dummy_flt_rule(IPA_IP_v6, num_v6_dummy_rule); - } - return; -} - -/* install dummy filtering rules for WLAN AP-AP mode support */ -int IPACM_Wlan::install_dummy_flt_rule(ipa_ip_type iptype, int num_rule) -{ - if(rx_prop == NULL) - { - IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy filtering rule.\n", dev_name); - return IPACM_FAILURE; - } - - int i, len, res = IPACM_SUCCESS; - struct ipa_flt_rule_add flt_rule; - ipa_ioc_add_flt_rule* pFilteringTable; - - len = sizeof(struct ipa_ioc_add_flt_rule) + num_rule * sizeof(struct ipa_flt_rule_add); - - pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); - if (pFilteringTable == NULL) - { - IPACMERR("Error allocate flt table memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - pFilteringTable->commit = 1; - pFilteringTable->ep = rx_prop->rx[0].src_pipe; - pFilteringTable->global = false; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = num_rule; - - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); - - flt_rule.rule.retain_hdr = 0; - flt_rule.at_rear = true; - flt_rule.flt_rule_hdl = -1; - flt_rule.status = -1; - flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, - sizeof(flt_rule.rule.attrib)); - - if(iptype == IPA_IP_v4) - { - flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; - flt_rule.rule.attrib.u.v4.src_addr = ~0; - flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; - flt_rule.rule.attrib.u.v4.dst_addr = ~0; - - for(i=0; i<num_rule; i++) - { - memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); - } - - if (false == m_filtering.AddFilteringRule(pFilteringTable)) - { - IPACMERR("Error adding dummy ipv4 flt rule\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, num_rule); - /* copy filter rule hdls */ - for (int i = 0; i < num_rule; i++) - { - if (pFilteringTable->rules[i].status == 0) - { - IPACM_Wlan::dummy_flt_rule_hdl_v4[i] = pFilteringTable->rules[i].flt_rule_hdl; - IPACMDBG("Dummy v4 flt rule %d hdl:0x%x\n", i, IPACM_Wlan::dummy_flt_rule_hdl_v4[i]); - } - else - { - IPACMERR("Failed adding dummy v4 flt rule %d\n", i); - res = IPACM_FAILURE; - goto fail; - } - } - } - } - else if(iptype == IPA_IP_v6) - { - flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0; - flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0; - flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0; - flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[0] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[1] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[2] = ~0; - flt_rule.rule.attrib.u.v6.src_addr[3] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0; - flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0; - - for(i=0; i<num_rule; i++) - { - memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); - } - - if (false == m_filtering.AddFilteringRule(pFilteringTable)) - { - IPACMERR("Error adding dummy ipv6 flt rule\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, num_rule); - /* copy filter rule hdls */ - for (int i = 0; i < num_rule; i++) - { - if (pFilteringTable->rules[i].status == 0) - { - IPACM_Wlan::dummy_flt_rule_hdl_v6[i] = pFilteringTable->rules[i].flt_rule_hdl; - IPACMDBG("Lan2lan v6 flt rule %d hdl:0x%x\n", i, IPACM_Wlan::dummy_flt_rule_hdl_v6[i]); - } - else - { - IPACMERR("Failed adding v6 flt rule %d\n", i); - res = IPACM_FAILURE; - goto fail; - } - } - } - } - else - { - IPACMERR("IP type is not expected.\n"); - goto fail; - } - -fail: - free(pFilteringTable); - return res; -} - -/* delete dummy flt rule for WLAN AP-AP mode support*/ -void IPACM_Wlan::del_dummy_flt_rule() -{ - int num_v4_dummy_rule, num_v6_dummy_rule; - - if(IPACM_Wlan::num_wlan_ap_iface == 0) - { - if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL || IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) - { - IPACMERR("Either v4 or v6 dummy flt rule is empty.\n"); - return; - } -#ifndef CT_OPT - num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); - num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_IPV6_PREFIX_FLT_RULE); -#else - num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); - num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + NUM_IPV6_PREFIX_FLT_RULE); -#endif -#ifdef FEATURE_IPA_ANDROID - num_v4_dummy_rule = num_v4_dummy_rule - 2* IPACM_Iface::ipacmcfg->ipa_num_private_subnet + 2 * IPA_MAX_PRIVATE_SUBNET_ENTRIES; -#endif - -#ifdef FEATURE_ETH_BRIDGE_LE - num_v4_dummy_rule = IPV4_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_LAN_CLIENT + IPACM_Iface::ipacmcfg->ipa_num_private_subnet; - num_v6_dummy_rule = IPV6_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_LAN_CLIENT + 2 * NUM_IPV6_PREFIX_FLT_RULE; -#endif - - if(m_filtering.DeleteFilteringHdls(IPACM_Wlan::dummy_flt_rule_hdl_v4, IPA_IP_v4, num_v4_dummy_rule) == false) - { - IPACMERR("Failed to delete ipv4 dummy flt rules.\n"); - return; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_v4_dummy_rule); - if(m_filtering.DeleteFilteringHdls(IPACM_Wlan::dummy_flt_rule_hdl_v6, IPA_IP_v6, num_v6_dummy_rule) == false) - { - IPACMERR("Failed to delete ipv6 dummy flt rules.\n"); - return; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_v6_dummy_rule); - - free(IPACM_Wlan::dummy_flt_rule_hdl_v4); - IPACM_Wlan::dummy_flt_rule_hdl_v4 = NULL; - free(IPACM_Wlan::dummy_flt_rule_hdl_v6); - IPACM_Wlan::dummy_flt_rule_hdl_v6 = NULL; -#ifdef FEATURE_ETH_BRIDGE_LE - memset(self_client_flt_rule_hdl_v4, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(lan2lan_flt_rule_hdl)); - memset(self_client_flt_rule_hdl_v6, 0, IPA_LAN_TO_LAN_MAX_WLAN_CLIENT * sizeof(lan2lan_flt_rule_hdl)); - memset(lan_client_flt_rule_hdl_v4, 0, IPA_LAN_TO_LAN_MAX_LAN_CLIENT * sizeof(lan2lan_flt_rule_hdl)); - memset(lan_client_flt_rule_hdl_v6, 0, IPA_LAN_TO_LAN_MAX_LAN_CLIENT * sizeof(lan2lan_flt_rule_hdl)); -#endif - } - return; -} - -/* install TCP control filter rules */ -void IPACM_Wlan::install_tcp_ctl_flt_rule(ipa_ip_type iptype) -{ - if (rx_prop == NULL) - { - IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); - return; - } - - int i, len, res = IPACM_SUCCESS, offset; - struct ipa_flt_rule_mdfy flt_rule; - struct ipa_ioc_mdfy_flt_rule* pFilteringTable; - - if (iptype == IPA_IP_v4) - { - if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) - { - IPACMERR("Dummy ipv4 flt rule has not been installed.\n"); - return; - } - offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet); -#ifdef FEATURE_IPA_ANDROID - offset = offset + wlan_ap_index * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet); -#endif - } - else - { - if(IPACM_Wlan::dummy_flt_rule_hdl_v6 == NULL) - { - IPACMERR("Dummy ipv6 flt rule has not been installed.\n"); - return; - } - offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR); - } - - len = sizeof(struct ipa_ioc_mdfy_flt_rule) + NUM_TCP_CTL_FLT_RULE * sizeof(struct ipa_flt_rule_mdfy); - pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); - if (!pFilteringTable) - { - IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); - return; - } - memset(pFilteringTable, 0, len); - - pFilteringTable->commit = 1; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = NUM_TCP_CTL_FLT_RULE; - - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); - flt_rule.status = -1; - - flt_rule.rule.retain_hdr = 1; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; - flt_rule.rule.eq_attrib_type = 1; - - flt_rule.rule.eq_attrib.rule_eq_bitmap = 0; - - if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA) - { - flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<14); - flt_rule.rule.eq_attrib.metadata_meq32_present = 1; - flt_rule.rule.eq_attrib.metadata_meq32.offset = 0; - flt_rule.rule.eq_attrib.metadata_meq32.value = rx_prop->rx[0].attrib.meta_data; - flt_rule.rule.eq_attrib.metadata_meq32.mask = rx_prop->rx[0].attrib.meta_data_mask; - } - - flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<1); - flt_rule.rule.eq_attrib.protocol_eq_present = 1; - flt_rule.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP; - - /* add TCP FIN rule*/ - flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<8); - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12; - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_FIN_SHIFT); - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_FIN_SHIFT); - flt_rule.rule.eq_attrib.num_ihl_offset_meq_32 = 1; - if(iptype == IPA_IP_v4) - { - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset]; - } - else - { - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset]; - } - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - - /* add TCP SYN rule*/ - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_SYN_SHIFT); - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_SYN_SHIFT); - if(iptype == IPA_IP_v4) - { - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+1]; - } - else - { - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+1]; - } - memcpy(&(pFilteringTable->rules[1]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - - /* add TCP RST rule*/ - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_RST_SHIFT); - flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_RST_SHIFT); - if(iptype == IPA_IP_v4) - { - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+2]; - } - else - { - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+2]; - } - memcpy(&(pFilteringTable->rules[2]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) - { - IPACMERR("Failed to modify tcp control filtering rules.\n"); - goto fail; - } - else - { - if(iptype == IPA_IP_v4) - { - for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++) - { - tcp_ctl_flt_rule_hdl_v4[i] = pFilteringTable->rules[i].rule_hdl; - } - } - else - { - for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++) - { - tcp_ctl_flt_rule_hdl_v6[i] = pFilteringTable->rules[i].rule_hdl; - } - } - } - -fail: - free(pFilteringTable); - return; -} - -int IPACM_Wlan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype) -{ - if(rx_prop == NULL) - { - IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy lan2lan filtering rule.\n", dev_name); - return IPACM_FAILURE; - } - - int offset; - if(iptype == IPA_IP_v4) - { - if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL) - { - IPACMERR("Dummy ipv4 flt rule has not been installed.\n"); - return IPACM_FAILURE; - } - -#ifndef CT_OPT - offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) - + IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR; -#else - offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet) - + IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + NUM_TCP_CTL_FLT_RULE; -#endif - -#ifdef FEATURE_IPA_ANDROID - offset = offset + wlan_ap_index * (IPA_MAX_PRIVATE_SUBNET_ENTRIES - IPACM_Iface::ipacmcfg->ipa_num_private_subnet); -#endif - for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++) - { - private_fl_rule_hdl[i] = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i]; - IPACMDBG_H("Private subnet v4 flt rule %d hdl:0x%x\n", i, private_fl_rule_hdl[i]); - } - } - return IPACM_SUCCESS; -} - -int IPACM_Wlan::eth_bridge_handle_dummy_wlan_client_flt_rule(ipa_ip_type iptype) -{ - int i, offset; - if(wlan_ap_index == 0) - { - if(iptype == IPA_IP_v4) - { - offset = IPV4_DEFAULT_FILTERTING_RULES; - for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) - { - self_client_flt_rule_hdl_v4[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i]; - self_client_flt_rule_hdl_v4[i].valid = true; - } - } - else - { - offset = 0; - for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) - { - self_client_flt_rule_hdl_v6[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+i]; - self_client_flt_rule_hdl_v6[i].valid = true; - } - } - IPACMDBG_H("Get %d flt rule hdls for wlan clients ip type: %d.\n", IPA_LAN_TO_LAN_MAX_WLAN_CLIENT, iptype); - } - return IPACM_SUCCESS; -} - -int IPACM_Wlan::eth_bridge_handle_dummy_lan_client_flt_rule(ipa_ip_type iptype) -{ - int i, offset; - if(wlan_ap_index == 0) - { - if(iptype == IPA_IP_v4) - { - offset = IPV4_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; - for(i=0; i<IPA_LAN_TO_LAN_MAX_LAN_CLIENT; i++) - { - lan_client_flt_rule_hdl_v4[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i]; - lan_client_flt_rule_hdl_v4[i].valid = true; - } - } - else - { - offset = IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; - for(i=0; i<IPA_LAN_TO_LAN_MAX_LAN_CLIENT; i++) - { - lan_client_flt_rule_hdl_v6[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+i]; - lan_client_flt_rule_hdl_v6[i].valid = true; - } - } - IPACMDBG_H("Get %d flt rule hdls for lan clients ip type: %d.\n", IPA_LAN_TO_LAN_MAX_LAN_CLIENT, iptype); - } - return IPACM_SUCCESS; -} - -int IPACM_Wlan::eth_bridge_add_lan_client_flt_rule(uint8_t* mac, ipa_ip_type iptype) -{ - int i, len, res = IPACM_SUCCESS, client_position; - struct ipa_flt_rule_mdfy flt_rule; - struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL; - bool client_is_found = false; - - if (rx_prop == NULL) - { - IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); - return IPACM_FAILURE; - } - if(mac == NULL) - { - IPACMERR("MAC address is empty.\n"); - return IPACM_FAILURE; - } - if(is_guest_ap) - { - IPACMDBG_H("This is guest AP WLAN interface index %d, ignore.\n", wlan_ap_index); - return IPACM_SUCCESS; - } - if(wlan_ap_index != 0) - { - IPACMDBG_H("This is WLAN interface index %d, ignore.\n", wlan_ap_index); - return IPACM_SUCCESS; - } - - for(i=0; i<lan_client_flt_info_count; i++) - { - if(memcmp(eth_bridge_lan_client_flt_info[i].mac, mac, sizeof(eth_bridge_lan_client_flt_info[i].mac)) == 0) - { - client_is_found = true; - client_position = i; - if( (iptype == IPA_IP_v4 && eth_bridge_lan_client_flt_info[i].flt_rule_set_v4 == true) - || (iptype == IPA_IP_v6 && eth_bridge_lan_client_flt_info[i].flt_rule_set_v6 == true)) - { - IPACMDBG_H("Flt rule for iptype %d has been set.\n", iptype); - return IPACM_SUCCESS; - } - break; - } - } - - if(client_is_found == false && lan_client_flt_info_count == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - { - IPACMDBG_H("The lan client flt table is already full.\n"); - return IPACM_FAILURE; - } - - len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy); - pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); - if (!pFilteringTable) - { - IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - IPACMDBG_H("Receive LAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - /* add mac based rule on flt table */ - pFilteringTable->commit = 1; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = 1; - - /* point to LAN-WLAN routing table */ - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); - flt_rule.status = -1; - - flt_rule.rule.retain_hdr = 0; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_ROUTING; - flt_rule.rule.eq_attrib_type = 0; - - if(iptype == IPA_IP_v4) - { - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4.hdl; - IPACMDBG_H("WLAN->LAN IPv4 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4.name); - } - else - { - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6.hdl; - IPACMDBG_H("WLAN->LAN IPv6 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6.name); - } - - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); - - /* Install meta-data if self or other ap is guest ap */ - if ((is_guest_ap == false && IPACM_Wlan::num_wlan_ap_iface == 1) || - IPACM_Iface::ipacmcfg->ipa_num_wlan_guest_ap == 0) - { - flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); //remove meta data mask - } - - if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II) - { - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; - } - else if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_802_3) - { - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; - } - else - { - IPACMERR("WLAN hdr type is not expected.\n"); - res = IPACM_FAILURE; - goto fail; - } - memcpy(flt_rule.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule.rule.attrib.dst_mac_addr)); - memset(flt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule.rule.attrib.dst_mac_addr_mask)); - - if(iptype == IPA_IP_v4) - { - for(i=0; i<IPA_LAN_TO_LAN_MAX_LAN_CLIENT; i++) - { - if(lan_client_flt_rule_hdl_v4[i].valid == true) - { - flt_rule.rule_hdl = lan_client_flt_rule_hdl_v4[i].rule_hdl; - lan_client_flt_rule_hdl_v4[i].valid = false; - break; - } - } - if(i == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - { - IPACMDBG_H("Cannot find a valid flt rule hdl.\n"); - res = IPACM_FAILURE; - goto fail; - } - } - else - { - for(i=0; i<IPA_LAN_TO_LAN_MAX_LAN_CLIENT; i++) - { - if(lan_client_flt_rule_hdl_v6[i].valid == true) - { - flt_rule.rule_hdl = lan_client_flt_rule_hdl_v6[i].rule_hdl; - lan_client_flt_rule_hdl_v6[i].valid = false; - break; - } - } - if(i == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - { - IPACMDBG_H("Cannot find a valid flt rule hdl.\n"); - res = IPACM_FAILURE; - goto fail; - } - } - - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) - { - IPACMERR("Failed to add wlan client filtering rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - - if(client_is_found == false) - { - client_position = lan_client_flt_info_count; - lan_client_flt_info_count++; - } - - memcpy(eth_bridge_lan_client_flt_info[client_position].mac, mac, sizeof(eth_bridge_lan_client_flt_info[client_position].mac)); - if(iptype == IPA_IP_v4) - { - eth_bridge_lan_client_flt_info[client_position].flt_rule_set_v4 = true; - eth_bridge_lan_client_flt_info[client_position].flt_rule_hdl_v4 = lan_client_flt_rule_hdl_v4[i].rule_hdl; - } - else - { - eth_bridge_lan_client_flt_info[client_position].flt_rule_set_v6 = true; - eth_bridge_lan_client_flt_info[client_position].flt_rule_hdl_v6 = lan_client_flt_rule_hdl_v6[i].rule_hdl; - } - -fail: - free(pFilteringTable); - return res; -} - -int IPACM_Wlan::eth_bridge_del_lan_client_flt_rule(uint8_t* mac) -{ - if(mac == NULL) - { - IPACMERR("Client MAC address is empty.\n"); - return IPACM_FAILURE; - } - - IPACMDBG_H("Receive LAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - int i, j, res = IPACM_SUCCESS; - for(i=0; i<lan_client_flt_info_count; i++) - { - if(memcmp(eth_bridge_lan_client_flt_info[i].mac, mac, sizeof(eth_bridge_lan_client_flt_info[i].mac)) == 0) - { - break; - } - } - - if(i == lan_client_flt_info_count) - { - IPACMERR("Do not find the lan client.\n"); - return IPACM_FAILURE; - } - - if(eth_bridge_lan_client_flt_info[i].flt_rule_set_v4 == true) - { - if(reset_to_dummy_flt_rule(IPA_IP_v4, eth_bridge_lan_client_flt_info[i].flt_rule_hdl_v4) == IPACM_SUCCESS) - { - for(j=0; j<IPA_LAN_TO_LAN_MAX_LAN_CLIENT; j++) - { - if(lan_client_flt_rule_hdl_v4[j].rule_hdl == eth_bridge_lan_client_flt_info[i].flt_rule_hdl_v4) - { - lan_client_flt_rule_hdl_v4[j].valid = true; - break; - } - } - if(j == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - { - IPACMERR("Not finding the rule handle in handle pool.\n"); - return IPACM_FAILURE; - } - } - else - { - IPACMERR("Failed to delete the lan client specific flt rule.\n"); - return IPACM_FAILURE; - } - } - if(eth_bridge_lan_client_flt_info[i].flt_rule_set_v6 == true) - { - if(reset_to_dummy_flt_rule(IPA_IP_v6, eth_bridge_lan_client_flt_info[i].flt_rule_hdl_v6) == IPACM_SUCCESS) - { - for(j=0; j<IPA_LAN_TO_LAN_MAX_LAN_CLIENT; j++) - { - if(lan_client_flt_rule_hdl_v6[j].rule_hdl == eth_bridge_lan_client_flt_info[i].flt_rule_hdl_v6) - { - lan_client_flt_rule_hdl_v6[j].valid = true; - break; - } - } - if(j == IPA_LAN_TO_LAN_MAX_LAN_CLIENT) - { - IPACMERR("Not finding the rule handle in handle pool.\n"); - return IPACM_FAILURE; - } - } - else - { - IPACMERR("Failed to delete the lan client specific flt rule.\n"); - return IPACM_FAILURE; - } - } - - for(j=i+1; j<lan_client_flt_info_count; j++) - { - memcpy(&(eth_bridge_lan_client_flt_info[j-1]), &(eth_bridge_lan_client_flt_info[j]), sizeof(eth_bridge_client_flt_info)); - } - memset(&(eth_bridge_lan_client_flt_info[lan_client_flt_info_count-1]), 0, sizeof(eth_bridge_client_flt_info)); - lan_client_flt_info_count--; - - return res; -} - -int IPACM_Wlan::eth_bridge_add_self_client_flt_rule(uint8_t* mac, ipa_ip_type iptype) -{ - int i, len, res = IPACM_SUCCESS, client_position; - struct ipa_flt_rule_mdfy flt_rule; - struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL; - bool client_is_found = false; - - if (rx_prop == NULL) - { - IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); - return IPACM_FAILURE; - } - if(mac == NULL) - { - IPACMERR("MAC address is empty.\n"); - return IPACM_FAILURE; - } - if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == false) - { - IPACMDBG_H("WLAN to WLAN hdr proc ctx has not been set, don't add WLAN client specific flt rule.\n"); - return IPACM_FAILURE; - } - - for(i=0; i<wlan_client_flt_info_count; i++) - { - if(memcmp(eth_bridge_wlan_client_flt_info[i].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[i].mac)) == 0) - { - client_is_found = true; - client_position = i; - if( (iptype == IPA_IP_v4 && eth_bridge_wlan_client_flt_info[i].flt_rule_set_v4 == true) - || (iptype == IPA_IP_v6 && eth_bridge_wlan_client_flt_info[i].flt_rule_set_v6 == true)) - { - IPACMDBG_H("Flt rule for iptype %d has been set.\n", iptype); - return IPACM_SUCCESS; - } - break; - } - } - - if(client_is_found == false && wlan_client_flt_info_count == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - { - IPACMDBG_H("The wlan client flt table is already full.\n"); - return IPACM_FAILURE; - } - - len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy); - pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); - if (!pFilteringTable) - { - IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - /* add mac based rule on IPv4 table */ - pFilteringTable->commit = 1; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = 1; - - /* point to LAN-WLAN routing table */ - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); - flt_rule.status = -1; - - flt_rule.rule.retain_hdr = 0; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_ROUTING; - flt_rule.rule.eq_attrib_type = 0; - - if(iptype == IPA_IP_v4) - { - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4.hdl; - IPACMDBG_H("WLAN->WLAN IPv4 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4.name); - } - else - { - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.hdl; - IPACMDBG_H("WLAN->WLAN IPv4 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.name); - } - - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); - - /* Install meta-data if self or other ap is guest ap */ - if ((is_guest_ap == false && IPACM_Wlan::num_wlan_ap_iface == 1) || - IPACM_Iface::ipacmcfg->ipa_num_wlan_guest_ap == 0) - { - flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); //remove meta data mask - } - - if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II) - { - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; - } - else if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_802_3) - { - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; - } - else - { - IPACMERR("WLAN hdr type is not expected.\n"); - res = IPACM_FAILURE; - goto fail; - } - memcpy(flt_rule.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule.rule.attrib.dst_mac_addr)); - memset(flt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule.rule.attrib.dst_mac_addr_mask)); - - if(iptype == IPA_IP_v4) - { - for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) - { - if(self_client_flt_rule_hdl_v4[i].valid == true) - { - flt_rule.rule_hdl = self_client_flt_rule_hdl_v4[i].rule_hdl; - self_client_flt_rule_hdl_v4[i].valid = false; - break; - } - } - if(i == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - { - IPACMDBG_H("Cannot find a valid flt rule hdl.\n"); - res = IPACM_FAILURE; - goto fail; - } - } - else - { - for(i=0; i<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; i++) - { - if(self_client_flt_rule_hdl_v6[i].valid == true) - { - flt_rule.rule_hdl = self_client_flt_rule_hdl_v6[i].rule_hdl; - self_client_flt_rule_hdl_v6[i].valid = false; - break; - } - } - if(i == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - { - IPACMDBG_H("Cannot find a valid flt rule hdl.\n"); - res = IPACM_FAILURE; - goto fail; - } - } - - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) - { - IPACMERR("Failed to add self client filtering rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - - if(client_is_found == false) - { - client_position = wlan_client_flt_info_count; - wlan_client_flt_info_count++; - } - - memcpy(eth_bridge_wlan_client_flt_info[client_position].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[client_position].mac)); - if(iptype == IPA_IP_v4) - { - eth_bridge_wlan_client_flt_info[client_position].flt_rule_set_v4 = true; - eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v4 = self_client_flt_rule_hdl_v4[i].rule_hdl; - } - else - { - eth_bridge_wlan_client_flt_info[client_position].flt_rule_set_v6 = true; - eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v6 = self_client_flt_rule_hdl_v6[i].rule_hdl; - } - -fail: - free(pFilteringTable); - return res; -} - -int IPACM_Wlan::eth_bridge_del_self_client_flt_rule(uint8_t* mac) -{ - if(mac == NULL) - { - IPACMERR("Client MAC address is empty.\n"); - return IPACM_FAILURE; - } - - IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - int i, j, res = IPACM_SUCCESS; - for(i=0; i<wlan_client_flt_info_count; i++) - { - if(memcmp(eth_bridge_wlan_client_flt_info[i].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[i].mac)) == 0) - { - break; - } - } - - if(i == wlan_client_flt_info_count) - { - IPACMERR("Do not find the wlan client.\n"); - return IPACM_FAILURE; - } - - if(eth_bridge_wlan_client_flt_info[i].flt_rule_set_v4 == true) - { - if(reset_to_dummy_flt_rule(IPA_IP_v4, eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v4) == IPACM_SUCCESS) - { - for(j=0; j<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; j++) - { - if(self_client_flt_rule_hdl_v4[j].rule_hdl == eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v4) - { - self_client_flt_rule_hdl_v4[j].valid = true; - break; - } - } - if(j == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - { - IPACMERR("Not finding the rule handle in handle pool.\n"); - return IPACM_FAILURE; - } - } - else - { - IPACMERR("Failed to delete the wlan client specific flt rule.\n"); - return IPACM_FAILURE; - } - } - if(eth_bridge_wlan_client_flt_info[i].flt_rule_set_v6 == true) - { - if(reset_to_dummy_flt_rule(IPA_IP_v6, eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v6) == IPACM_SUCCESS) - { - for(j=0; j<IPA_LAN_TO_LAN_MAX_WLAN_CLIENT; j++) - { - if(self_client_flt_rule_hdl_v6[j].rule_hdl == eth_bridge_wlan_client_flt_info[i].flt_rule_hdl_v6) - { - self_client_flt_rule_hdl_v6[j].valid = true; - break; - } - } - if(j == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - { - IPACMERR("Not finding the rule handle in handle pool.\n"); - return IPACM_FAILURE; - } - } - else - { - IPACMERR("Failed to delete the wlan client specific flt rule.\n"); - return IPACM_FAILURE; - } - } - - for(j=i+1; j<wlan_client_flt_info_count; j++) - { - memcpy(&(eth_bridge_wlan_client_flt_info[j-1]), &(eth_bridge_wlan_client_flt_info[j]), sizeof(eth_bridge_client_flt_info)); - } - memset(&(eth_bridge_wlan_client_flt_info[wlan_client_flt_info_count-1]), 0, sizeof(eth_bridge_client_flt_info)); - wlan_client_flt_info_count--; - - return res; -} - -int IPACM_Wlan::eth_bridge_install_cache_lan_client_flt_rule(ipa_ip_type iptype) -{ - int i; - - IPACMDBG_H("There are %d lan clients cached.\n", IPACM_Lan::num_lan_client); - for(i=0; i<IPACM_Lan::num_lan_client; i++) - { - eth_bridge_add_lan_client_flt_rule(IPACM_Lan::eth_bridge_lan_client[i].mac, iptype); - } - return IPACM_SUCCESS; -} - -int IPACM_Wlan::eth_bridge_install_cache_wlan_client_flt_rule(ipa_ip_type iptype) -{ - int i; - - IPACMDBG_H("There are %d wlan clients cached.\n", IPACM_Lan::num_wlan_client); - for(i=0; i<IPACM_Lan::num_wlan_client; i++) - { - eth_bridge_add_self_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, iptype); - } - return IPACM_SUCCESS; -} - -int IPACM_Wlan::eth_bridge_add_wlan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src, ipa_ip_type iptype) -{ - if(tx_prop == NULL) - { - IPACMDBG_H("Tx prop is empty, not adding routing rule.\n"); - return IPACM_SUCCESS; - } - if(mac == NULL) - { - IPACMERR("Client MAC address is empty.\n"); - return IPACM_FAILURE; - } - - IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x src_iface: %d .\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], src); - - if(iptype == IPA_IP_v4) - { - if( (src == SRC_WLAN && wlan_client_rt_from_wlan_info_count_v4 == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - || (src == SRC_LAN && wlan_client_rt_from_lan_info_count_v4 == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)) - { - IPACMDBG_H("WLAN client number has reached maximum.\n"); - return IPACM_FAILURE; - } - } - else - { - if( (src == SRC_WLAN && wlan_client_rt_from_wlan_info_count_v6 == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - || (src == SRC_LAN && wlan_client_rt_from_lan_info_count_v6 == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT)) - { - IPACMDBG_H("WLAN client number has reached maximum.\n"); - return IPACM_FAILURE; - } - } - if( (src == SRC_WLAN && IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == false) - || (src == SRC_LAN && IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == false) ) - { - IPACMDBG_H("Hdr proc ctx has not been set for source %d, don't add WLAN client routing rule.\n", src); - return IPACM_FAILURE; - } - - int i, len, res = IPACM_SUCCESS; - struct ipa_ioc_add_rt_rule* rt_rule_table = NULL; - struct ipa_rt_rule_add rt_rule; - int position, num_rt_rule; - - if(src == SRC_WLAN) - { - if(iptype == IPA_IP_v4) - { - for(i=0; i<wlan_client_rt_from_wlan_info_count_v4; i++) - { - if(memcmp(eth_bridge_get_client_rt_info_ptr(i, SRC_WLAN, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, SRC_WLAN, iptype)->mac)) == 0) - { - IPACMDBG_H("The client's routing rule was added before.\n"); - return IPACM_SUCCESS; - } - } - memcpy(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v4, src, iptype)->mac, mac, - sizeof(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v4, src, iptype)->mac)); - } - else - { - for(i=0; i<wlan_client_rt_from_wlan_info_count_v6; i++) - { - if(memcmp(eth_bridge_get_client_rt_info_ptr(i, SRC_WLAN, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, SRC_WLAN, iptype)->mac)) == 0) - { - IPACMDBG_H("The client's routing rule was added before.\n"); - return IPACM_SUCCESS; - } - } - memcpy(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v6, src, iptype)->mac, mac, - sizeof(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v6, src, iptype)->mac)); - } - } - else - { - if(iptype == IPA_IP_v4) - { - for(i=0; i<wlan_client_rt_from_lan_info_count_v4; i++) - { - if(memcmp(eth_bridge_get_client_rt_info_ptr(i, SRC_LAN, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, SRC_LAN, iptype)->mac)) == 0) - { - IPACMDBG_H("The client's routing rule was added before.\n"); - return IPACM_SUCCESS; - } - } - memcpy(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_lan_info_count_v4, src, iptype)->mac, mac, - sizeof(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_lan_info_count_v4, src, iptype)->mac)); - } - else - { - for(i=0; i<wlan_client_rt_from_lan_info_count_v6; i++) - { - if(memcmp(eth_bridge_get_client_rt_info_ptr(i, SRC_LAN, iptype)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, SRC_LAN, iptype)->mac)) == 0) - { - IPACMDBG_H("The client's routing rule was added before.\n"); - return IPACM_SUCCESS; - } - } - memcpy(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_lan_info_count_v6, src, iptype)->mac, mac, - sizeof(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_lan_info_count_v6, src, iptype)->mac)); - } - } - - if(iptype == IPA_IP_v4) - { - num_rt_rule = each_client_rt_rule_count_v4; - } - else - { - num_rt_rule = each_client_rt_rule_count_v6; - } - - len = sizeof(ipa_ioc_add_rt_rule) + num_rt_rule * sizeof(ipa_rt_rule_add); - rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(len); - if(rt_rule_table == NULL) - { - IPACMERR("Failed to allocate memory.\n"); - return IPACM_FAILURE; - } - memset(rt_rule_table, 0, len); - - rt_rule_table->commit = 1; - rt_rule_table->ip = iptype; - rt_rule_table->num_rules = num_rt_rule; - if(src == SRC_WLAN) - { - if(iptype == IPA_IP_v4) - { - strlcpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4.name, sizeof(rt_rule_table->rt_tbl_name)); - } - else - { - strlcpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.name, sizeof(rt_rule_table->rt_tbl_name)); - } - } - else - { - if(iptype == IPA_IP_v4) - { - strlcpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4.name, sizeof(rt_rule_table->rt_tbl_name)); - } - else - { - strlcpy(rt_rule_table->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6.name, sizeof(rt_rule_table->rt_tbl_name)); - } - } - rt_rule_table->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0'; - memset(&rt_rule, 0, sizeof(ipa_rt_rule_add)); - rt_rule.at_rear = false; - rt_rule.status = -1; - rt_rule.rt_rule_hdl = -1; - - rt_rule.rule.hdr_hdl = 0; - if(src == SRC_WLAN) - { - rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.proc_ctx_hdl; - } - else - { - rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::lan_to_wlan_hdr_proc_ctx.proc_ctx_hdl; - } - position = 0; - for(i=0; i<iface_query->num_tx_props; i++) - { - if(tx_prop->tx[i].ip == iptype) - { - if(position >= num_rt_rule) - { - IPACMERR("Number of routing rules already exceeds limit.\n"); - res = IPACM_FAILURE; - goto fail; - } - /* Handle MCC Mode case */ - if (IPACM_Iface::ipacmcfg->isMCC_Mode == true) - { - IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n", - tx_prop->tx[i].alt_dst_pipe); - rt_rule.rule.dst = tx_prop->tx[i].alt_dst_pipe; - } - else - { - rt_rule.rule.dst = tx_prop->tx[i].dst_pipe; - } - - memcpy(&rt_rule.rule.attrib, &tx_prop->tx[i].attrib, sizeof(rt_rule.rule.attrib)); - if(src == SRC_WLAN) //src is WLAN means packet is from WLAN - { - if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II) - { - rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; - } - else - { - rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; - } - } - else //packet is from LAN - { - if(IPACM_Lan::lan_hdr_type == IPA_HDR_L2_ETHERNET_II) - { - rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; - } - else - { - rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; - } - } - memcpy(rt_rule.rule.attrib.dst_mac_addr, mac, sizeof(rt_rule.rule.attrib.dst_mac_addr)); - memset(rt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule.rule.attrib.dst_mac_addr_mask)); - - memcpy(&(rt_rule_table->rules[position]), &rt_rule, sizeof(rt_rule_table->rules[position])); - position++; - } - } - if(false == m_routing.AddRoutingRule(rt_rule_table)) - { - IPACMERR("Routing rule addition failed!\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - if(src == SRC_WLAN) - { - for(i=0; i<num_rt_rule; i++) - { - if(iptype == IPA_IP_v4) - { - eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v4, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; - } - else - { - eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v6, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; - } - } - if(iptype == IPA_IP_v4) - { - wlan_client_rt_from_wlan_info_count_v4++; - IPACMDBG_H("Now the number of IPv4 rt rule on wlan-wlan rt table is %d.\n", wlan_client_rt_from_wlan_info_count_v4); - } - else - { - wlan_client_rt_from_wlan_info_count_v6++; - IPACMDBG_H("Now the number of IPv6 rt rule on wlan-wlan rt table is %d.\n", wlan_client_rt_from_wlan_info_count_v6); - } - } - else - { - for(i=0; i<num_rt_rule; i++) - { - if(iptype == IPA_IP_v4) - { - eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_lan_info_count_v4, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; - } - else - { - eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_lan_info_count_v6, src, iptype)->rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; - } - } - if(iptype == IPA_IP_v4) - { - wlan_client_rt_from_lan_info_count_v4++; - IPACMDBG_H("Now the number of IPv4 rt rule on lan-wlan rt table is %d.\n", wlan_client_rt_from_lan_info_count_v4); - } - else - { - wlan_client_rt_from_lan_info_count_v6++; - IPACMDBG_H("Now the number of IPv6 rt rule on lan-wlan rt table is %d.\n", wlan_client_rt_from_lan_info_count_v6); - } - } - } - -fail: - if(rt_rule_table != NULL) - { - free(rt_rule_table); - } - return res; -} - -int IPACM_Wlan::eth_bridge_del_wlan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src) -{ - if(tx_prop == NULL) - { - IPACMDBG_H("Tx prop is empty, not deleting routing rule.\n"); - return IPACM_SUCCESS; - } - if(mac == NULL) - { - IPACMERR("Client MAC address is empty.\n"); - return IPACM_FAILURE; - } - - IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - int i, position; - - /* first delete the rt rules from IPv4 rt table*/ - if(src == SRC_WLAN) - { - for(i=0; i<wlan_client_rt_from_wlan_info_count_v4; i++) - { - if(memcmp(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac)) == 0) - { - position = i; - IPACMDBG_H("The client is found at position %d.\n", position); - break; - } - } - if(i == wlan_client_rt_from_wlan_info_count_v4) - { - IPACMERR("The client is not found.\n"); - return IPACM_FAILURE; - } - } - else - { - for(i=0; i<wlan_client_rt_from_lan_info_count_v4; i++) - { - if(memcmp(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4)->mac)) == 0) - { - position = i; - IPACMDBG_H("The client is found at position %d.\n", position); - break; - } - } - if(i == wlan_client_rt_from_lan_info_count_v4) - { - IPACMERR("The client is not found.\n"); - return IPACM_FAILURE; - } - } - - for(i=0; i<each_client_rt_rule_count_v4; i++) - { - if(m_routing.DeleteRoutingHdl(eth_bridge_get_client_rt_info_ptr(position, src, IPA_IP_v4)->rt_rule_hdl[i], IPA_IP_v4) == false) - { - IPACMERR("Failed to delete routing rule %d.\n", i); - return IPACM_FAILURE; - } - } - - if(src == SRC_WLAN) - { - for(i=position+1; i<wlan_client_rt_from_wlan_info_count_v4; i++) - { - memcpy(eth_bridge_get_client_rt_info_ptr(i-1, src, IPA_IP_v4), eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4), client_rt_info_size_v4); - } - memset(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v4-1, src, IPA_IP_v4), 0, client_rt_info_size_v4); - wlan_client_rt_from_wlan_info_count_v4--; - IPACMDBG_H("Now the number of IPv4 rt rule from wlan info is %d.\n", wlan_client_rt_from_wlan_info_count_v4); - } - else - { - for(i=position+1; i<wlan_client_rt_from_lan_info_count_v4; i++) - { - memcpy(eth_bridge_get_client_rt_info_ptr(i-1, src, IPA_IP_v4), eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v4), client_rt_info_size_v4); - } - memset(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_lan_info_count_v4-1, src, IPA_IP_v4), 0, client_rt_info_size_v4); - wlan_client_rt_from_lan_info_count_v4--; - IPACMDBG_H("Now the number of IPv4 rt rule from lan info is %d.\n", wlan_client_rt_from_lan_info_count_v4); - } - - /*delete rt rules from IPv6 rt table */ - if(src == SRC_WLAN) - { - for(i=0; i<wlan_client_rt_from_wlan_info_count_v6; i++) - { - if(memcmp(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac)) == 0) - { - position = i; - IPACMDBG_H("The client is found at position %d.\n", position); - break; - } - } - if(i == wlan_client_rt_from_wlan_info_count_v6) - { - IPACMERR("The client is not found.\n"); - return IPACM_FAILURE; - } - } - else - { - for(i=0; i<wlan_client_rt_from_lan_info_count_v6; i++) - { - if(memcmp(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac, mac, sizeof(eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6)->mac)) == 0) - { - position = i; - IPACMDBG_H("The client is found at position %d.\n", position); - break; - } - } - if(i == wlan_client_rt_from_lan_info_count_v6) - { - IPACMERR("The client is not found.\n"); - return IPACM_FAILURE; - } - } - - for(i=0; i<each_client_rt_rule_count_v6; i++) - { - if(m_routing.DeleteRoutingHdl(eth_bridge_get_client_rt_info_ptr(position, src, IPA_IP_v6)->rt_rule_hdl[i], IPA_IP_v6) == false) - { - IPACMERR("Failed to delete routing rule %d.\n", i); - return IPACM_FAILURE; - } - } - - if(src == SRC_WLAN) - { - for(i=position+1; i<wlan_client_rt_from_wlan_info_count_v6; i++) - { - memcpy(eth_bridge_get_client_rt_info_ptr(i-1, src, IPA_IP_v6), eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6), client_rt_info_size_v6); - } - memset(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_wlan_info_count_v6-1, src, IPA_IP_v6), 0, client_rt_info_size_v6); - wlan_client_rt_from_wlan_info_count_v6--; - IPACMDBG_H("Now the number of IPv6 rt rule from wlan info is %d.\n", wlan_client_rt_from_wlan_info_count_v6); - } - else - { - for(i=position+1; i<wlan_client_rt_from_lan_info_count_v6; i++) - { - memcpy(eth_bridge_get_client_rt_info_ptr(i-1, src, IPA_IP_v6), eth_bridge_get_client_rt_info_ptr(i, src, IPA_IP_v6), client_rt_info_size_v6); - } - memset(eth_bridge_get_client_rt_info_ptr(wlan_client_rt_from_lan_info_count_v6-1, src, IPA_IP_v6), 0, client_rt_info_size_v6); - wlan_client_rt_from_lan_info_count_v6--; - IPACMDBG_H("Now the number of IPv6 rt rule from lan info is %d.\n", wlan_client_rt_from_lan_info_count_v6); - } - - return IPACM_SUCCESS; -} - -eth_bridge_client_rt_info* IPACM_Wlan::eth_bridge_get_client_rt_info_ptr(uint8_t index, eth_bridge_src_iface src, ipa_ip_type iptype) -{ - void* result; - if(src == SRC_WLAN) - { - if(iptype == IPA_IP_v4) - { - result = (void*)((void*)eth_bridge_wlan_client_rt_from_wlan_info_v4 + index * client_rt_info_size_v4); - } - else - { - result = (void*)((void*)eth_bridge_wlan_client_rt_from_wlan_info_v6 + index * client_rt_info_size_v6); - } - } - else - { - if(iptype == IPA_IP_v4) - { - result = (void*)((void*)eth_bridge_wlan_client_rt_from_lan_info_v4 + index * client_rt_info_size_v4); - } - else - { - result = (void*)((void*)eth_bridge_wlan_client_rt_from_lan_info_v6 + index * client_rt_info_size_v6); - } - } - return (eth_bridge_client_rt_info*)result; -} - -void IPACM_Wlan::eth_bridge_add_wlan_client(uint8_t* mac, int if_num) -{ - if(IPACM_Lan::num_wlan_client == IPA_LAN_TO_LAN_MAX_WLAN_CLIENT) - { - IPACMDBG_H("WLAN client table is already full.\n"); - return; - } - - if(mac == NULL) - { - IPACMERR("Mac address is empty.\n"); - return; - } - - int i; - for(i=0; i<IPACM_Lan::num_wlan_client; i++) - { - if(memcmp(IPACM_Lan::eth_bridge_wlan_client[i].mac, mac, sizeof(IPACM_Lan::eth_bridge_wlan_client[i].mac)) == 0) - { - IPACMDBG_H("The wlan client mac has been added before at position %d.\n", i); - return; - } - } - - memcpy(IPACM_Lan::eth_bridge_wlan_client[IPACM_Lan::num_wlan_client].mac, mac, sizeof(IPACM_Lan::eth_bridge_wlan_client[IPACM_Lan::num_wlan_client].mac)); - IPACM_Lan::eth_bridge_wlan_client[IPACM_Lan::num_wlan_client].ipa_if_num = if_num; - IPACM_Lan::num_wlan_client++; - IPACMDBG_H("Now the total num of wlan clients is %d", IPACM_Lan::num_wlan_client); - return; -} - -void IPACM_Wlan::eth_bridge_del_wlan_client(uint8_t* mac) -{ - if(mac == NULL) - { - IPACMERR("Mac address is empty.\n"); - return; - } - - int i, j; - for(i=0; i<IPACM_Lan::num_wlan_client; i++) - { - if(memcmp(IPACM_Lan::eth_bridge_wlan_client[i].mac, mac, sizeof(IPACM_Lan::eth_bridge_wlan_client[i].mac)) == 0) - { - IPACMDBG_H("Found WLAN client at position %d.\n", i); - break; - } - } - - if(i == IPACM_Lan::num_wlan_client) - { - IPACMDBG_H("Not finding the WLAN client.\n"); - return; - } - - for(j=i+1; j<IPACM_Lan::num_wlan_client; j++) - { - memcpy(IPACM_Lan::eth_bridge_wlan_client[j-1].mac, IPACM_Lan::eth_bridge_wlan_client[j].mac, sizeof(IPACM_Lan::eth_bridge_wlan_client[j].mac)); - IPACM_Lan::eth_bridge_wlan_client[j-1].ipa_if_num = IPACM_Lan::eth_bridge_wlan_client[j].ipa_if_num; - } - IPACM_Lan::num_wlan_client--; - IPACMDBG_H("Now the total num of wlan clients is %d", IPACM_Lan::num_wlan_client); - return; -} - void IPACM_Wlan::handle_SCC_MCC_switch(ipa_ip_type iptype) { struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL; @@ -5035,576 +2007,36 @@ void IPACM_Wlan::handle_SCC_MCC_switch(ipa_ip_type iptype) return; } -void IPACM_Wlan::eth_bridge_handle_wlan_SCC_MCC_switch(ipa_ip_type iptype) -{ - - for (int i= 0; i < IPACM_Lan::num_wlan_client; i++) - { - if (IPACM_Lan::eth_bridge_wlan_client[i].ipa_if_num == ipa_if_num) - { - if (IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true) - { - if (eth_bridge_modify_wlan_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_WLAN, iptype) == IPACM_FAILURE) - { - IPACMDBG_H("SCC/MCC switch is failed for iptype: %d src_iface: %d \n", iptype, SRC_WLAN); - return; - } - } - if (IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true) - { - if (eth_bridge_modify_wlan_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_LAN, iptype) == IPACM_FAILURE) - { - IPACMDBG_H("SCC/MCC switch is failed for iptype: %d src_iface: %d \n", iptype, SRC_LAN); - return; - } - } - } - } - - IPACMDBG_H("SCC/MCC switch is successful for iptype: %d\n", iptype); -} - -int IPACM_Wlan::eth_bridge_modify_wlan_rt_rule(uint8_t* mac, eth_bridge_src_iface src_iface, ipa_ip_type iptype) -{ - struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL; - struct ipa_rt_rule_mdfy *rt_rule_entry; - uint32_t index = 0, num_rt_rule = 0, position; - - if (tx_prop == NULL) - { - IPACMDBG_H("No tx properties \n"); - return IPACM_FAILURE; - } - - if (mac == NULL) - { - IPACMERR("Client MAC address is empty.\n"); - return IPACM_FAILURE; - } - - IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x. src_iface: %d\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], src_iface); - - if (iptype == IPA_IP_v4) - { - num_rt_rule = each_client_rt_rule_count_v4; - } - else - { - num_rt_rule = each_client_rt_rule_count_v6; - } - - if (src_iface == SRC_WLAN) - { - if (iptype == IPA_IP_v4) - { - for (index = 0; index < wlan_client_rt_from_wlan_info_count_v4; index++) - { - if (memcmp(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v4)->mac, mac, - sizeof(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v4)->mac)) == 0) - { - position = index; - IPACMDBG_H("The client is found at position %d.\n", position); - break; - } - } - if (index == wlan_client_rt_from_wlan_info_count_v4) - { - IPACMERR("The client is not found.\n"); - return IPACM_FAILURE; - } - } - else - { - for (index =0 ; index < wlan_client_rt_from_wlan_info_count_v6; index++) - { - if (memcmp(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v6)->mac, mac, - sizeof(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v6)->mac)) == 0) - { - position = index; - IPACMDBG_H("The client is found at position %d.\n", position); - break; - } - } - if (index == wlan_client_rt_from_wlan_info_count_v6) - { - IPACMERR("The client is not found.\n"); - return IPACM_FAILURE; - } - } - } - else - { - if (iptype == IPA_IP_v4) - { - for (index = 0; index < wlan_client_rt_from_lan_info_count_v4; index++) - { - if (memcmp(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v4)->mac, mac, - sizeof(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v4)->mac)) == 0) - { - position = index; - IPACMDBG_H("The client is found at position %d.\n", position); - break; - } - } - if (index == wlan_client_rt_from_lan_info_count_v4) - { - IPACMERR("The client is not found.\n"); - return IPACM_FAILURE; - } - } - else - { - for (index = 0; index < wlan_client_rt_from_lan_info_count_v6; index++) - { - if (memcmp(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v6)->mac, mac, - sizeof(eth_bridge_get_client_rt_info_ptr(index, src_iface, IPA_IP_v6)->mac)) == 0) - { - position = index; - IPACMDBG_H("The client is found at position %d.\n", position); - break; - } - } - if (index == wlan_client_rt_from_lan_info_count_v6) - { - IPACMERR("The client is not found.\n"); - return IPACM_FAILURE; - } - } - } - - rt_rule = (struct ipa_ioc_mdfy_rt_rule *) - calloc(1, sizeof(struct ipa_ioc_mdfy_rt_rule) + - (num_rt_rule) * sizeof(struct ipa_rt_rule_mdfy)); - - if (rt_rule == NULL) - { - IPACMERR("Unable to allocate memory for modify rt rule\n"); - return IPACM_FAILURE; - } - IPACMDBG("Allocated memory for %d rules successfully\n", num_rt_rule); - - rt_rule->commit = 1; - rt_rule->num_rules = 0; - rt_rule->ip = iptype; - - for (index = 0; index < tx_prop->num_tx_props; index++) - { - if (tx_prop->tx[index].ip == iptype) - { - if (rt_rule->num_rules >= num_rt_rule) - { - IPACMERR("Number of routing rules exceeds limit.\n"); - free(rt_rule); - return IPACM_FAILURE; - } - - rt_rule_entry = &rt_rule->rules[rt_rule->num_rules]; - - if (IPACM_Iface::ipacmcfg->isMCC_Mode) - { - IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n", - tx_prop->tx[index].alt_dst_pipe); - rt_rule_entry->rule.dst = tx_prop->tx[index].alt_dst_pipe; - } - else - { - rt_rule_entry->rule.dst = tx_prop->tx[index].dst_pipe; - } - - rt_rule_entry->rule.hdr_hdl = 0; - - if (src_iface == SRC_WLAN) - { - rt_rule_entry->rule.hdr_proc_ctx_hdl = - IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.proc_ctx_hdl; - } - else - { - rt_rule_entry->rule.hdr_proc_ctx_hdl = - IPACM_Lan::lan_to_wlan_hdr_proc_ctx.proc_ctx_hdl; - } - - memcpy(&rt_rule_entry->rule.attrib, - &tx_prop->tx[index].attrib, - sizeof(rt_rule_entry->rule.attrib)); - - if (src_iface == SRC_WLAN) //src is WLAN means packet is from WLAN - { - if (IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II) - { - rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; - } - else - { - rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; - } - } - else //packet is from LAN - { - if (IPACM_Lan::lan_hdr_type == IPA_HDR_L2_ETHERNET_II) - { - rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; - } - else - { - rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; - } - } - memcpy(rt_rule_entry->rule.attrib.dst_mac_addr, mac, - sizeof(rt_rule_entry->rule.attrib.dst_mac_addr)); - memset(rt_rule_entry->rule.attrib.dst_mac_addr_mask, 0xFF, - sizeof(rt_rule_entry->rule.attrib.dst_mac_addr_mask)); - - rt_rule_entry->rt_rule_hdl = - eth_bridge_get_client_rt_info_ptr(position, src_iface, iptype)->rt_rule_hdl[rt_rule->num_rules]; - IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", index, - eth_bridge_get_client_rt_info_ptr(position, src_iface, iptype)->rt_rule_hdl[rt_rule->num_rules], iptype); - - rt_rule->num_rules++; - } - } - - if (rt_rule->num_rules > 0) - { - if (false == m_routing.ModifyRoutingRule(rt_rule)) - { - IPACMERR("Routing rule modify failed!\n"); - free(rt_rule); - return IPACM_FAILURE; - } - if (false == m_routing.Commit(iptype)) - { - IPACMERR("Routing rule modify commit failed!\n"); - free(rt_rule); - return IPACM_FAILURE; - } - IPACMDBG("Routing rule modified successfully \n"); - } - - if (rt_rule) - { - free(rt_rule); - } - return IPACM_SUCCESS; -} - void IPACM_Wlan::eth_bridge_handle_wlan_mode_switch() { int i; - for (i=0; i<IPACM_Lan::num_wlan_client; i++) - { - if (IPACM_Lan::eth_bridge_wlan_client[i].ipa_if_num == ipa_if_num) - { - eth_bridge_modify_wlan_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, DST_WLAN, IPA_IP_v4); - eth_bridge_modify_wlan_client_flt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, DST_WLAN, IPA_IP_v6); - - if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true) - { - if (is_guest_ap == true) - { - eth_bridge_del_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_LAN); - eth_bridge_post_lan_client_event(IPACM_Lan::eth_bridge_wlan_client[i].mac, IPA_ETH_BRIDGE_WLAN_CLIENT_DEL_EVENT); - } - else - { - eth_bridge_add_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_LAN, IPA_IP_v4); - eth_bridge_add_wlan_client_rt_rule(IPACM_Lan::eth_bridge_wlan_client[i].mac, SRC_LAN, IPA_IP_v6); - eth_bridge_post_lan_client_event(IPACM_Lan::eth_bridge_wlan_client[i].mac, IPA_ETH_BRIDGE_WLAN_CLIENT_ADD_EVENT); - } - } - } - } -} + /* ====== post events to mimic WLAN interface goes down/up when AP mode is changing ====== */ + /* first post IFACE_DOWN event */ + eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL); -int IPACM_Wlan::eth_bridge_modify_wlan_client_flt_rule(uint8_t* mac, eth_bridge_dst_iface dst_iface, ipa_ip_type iptype) -{ - - int index, len, res = IPACM_SUCCESS, client_position; - struct ipa_flt_rule_mdfy flt_rule; - struct ipa_ioc_mdfy_flt_rule* pFilteringTable = NULL; - - if (rx_prop == NULL) + /* then post IFACE_UP event */ + if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { - IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); - return IPACM_FAILURE; + eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v4, NULL); } - if (mac == NULL) + if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { - IPACMERR("MAC address is empty.\n"); - return IPACM_FAILURE; + eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v6, NULL); } - IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x. dst_iface: %d \n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], dst_iface); - if (dst_iface == DST_WLAN && IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == false) - { - IPACMDBG_H("WLAN to WLAN hdr proc ctx has not been set, don't modify client specific flt rule.\n"); - return IPACM_FAILURE; - } - if (dst_iface == DST_LAN && IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == false) + /* at last post CLIENT_ADD event */ + for(i = 0; i < num_wifi_client; i++) { - IPACMDBG_H("WLAN to LAN hdr proc ctx has not been set, don't modify client specific flt rule.\n"); - return IPACM_FAILURE; + eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, + get_client_memptr(wlan_client, i)->mac); } - if (dst_iface == DST_WLAN) - { - for (index=0; index<wlan_client_flt_info_count; index++) - { - if(memcmp(eth_bridge_wlan_client_flt_info[index].mac, mac, sizeof(eth_bridge_wlan_client_flt_info[index].mac)) == 0) - { - client_position = index; - IPACMDBG_H("The client is found at position %d.\n", client_position); - break; - } - } - if(index == wlan_client_flt_info_count) - { - IPACMDBG_H("The wlan client is not found.\n"); - return IPACM_FAILURE; - } - } - else - { - for(index=0; index<lan_client_flt_info_count; index++) - { - if(memcmp(eth_bridge_lan_client_flt_info[index].mac, mac, sizeof(eth_bridge_lan_client_flt_info[index].mac)) == 0) - { - client_position = index; - IPACMDBG_H("The client is found at position %d.\n", client_position); - break; - } - } - if(index == lan_client_flt_info_count) - { - IPACMDBG_H("The lan client is not found.\n"); - return IPACM_FAILURE; - } - } - - len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy); - pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); - if (!pFilteringTable) - { - IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - /* add mac based rule on IPv4 table */ - pFilteringTable->commit = 1; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = 1; - - /* point to WLAN-WLAN routing table */ - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); - flt_rule.status = -1; - flt_rule.rule.retain_hdr = 0; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_ROUTING; - flt_rule.rule.eq_attrib_type = 0; - - if (dst_iface == DST_WLAN) - { - if(iptype == IPA_IP_v4) - { - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4.hdl; - IPACMDBG_H("WLAN->WLAN IPv4 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4.name); - } - else - { - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.hdl; - IPACMDBG_H("WLAN->WLAN IPv6 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.name); - } - } - else - { - if(iptype == IPA_IP_v4) - { - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - goto fail; - } - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4.hdl; - IPACMDBG_H("WLAN->LAN IPv4 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4.name); - } - else - { - if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6)) - { - IPACMERR("Failed to get routing table handle.\n"); - res = IPACM_FAILURE; - } - flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6.hdl; - IPACMDBG_H("WLAN->LAN IPv6 filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6.name); - } - } - - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); - - /* Install meta-data if self or other ap is guest ap */ - if ((is_guest_ap == false && IPACM_Wlan::num_wlan_ap_iface == 1) || - IPACM_Iface::ipacmcfg->ipa_num_wlan_guest_ap == 0) - { - flt_rule.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); //remove meta data mask - } - - if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_ETHERNET_II) - { - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; - } - else if(IPACM_Lan::wlan_hdr_type == IPA_HDR_L2_802_3) - { - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; - } - else - { - IPACMERR("WLAN hdr type is not expected.\n"); - res = IPACM_FAILURE; - goto fail; - } - memcpy(flt_rule.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule.rule.attrib.dst_mac_addr)); - memset(flt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule.rule.attrib.dst_mac_addr_mask)); - - if (dst_iface == DST_WLAN) - { - if(iptype == IPA_IP_v4) - { - flt_rule.rule_hdl = eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v4; - } - else - { - flt_rule.rule_hdl = eth_bridge_wlan_client_flt_info[client_position].flt_rule_hdl_v6; - } - } - else - { - if(iptype == IPA_IP_v4) - { - flt_rule.rule_hdl = eth_bridge_lan_client_flt_info[client_position].flt_rule_hdl_v4; - } - else - { - flt_rule.rule_hdl = eth_bridge_lan_client_flt_info[client_position].flt_rule_hdl_v6; - } - } - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) - { - IPACMERR("Failed to modify wlan client filtering rule.\n"); - res = IPACM_FAILURE; - goto fail; - } -fail: - free(pFilteringTable); - return res; -} - -int IPACM_Wlan::install_ipv6_prefix_flt_rule(uint32_t* prefix) -{ - int i, len, res = IPACM_SUCCESS, offset; - struct ipa_flt_rule_mdfy flt_rule; - struct ipa_ioc_mdfy_flt_rule* pFilteringTable; - - if (rx_prop == NULL) - { - IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); - return IPACM_SUCCESS; - } - - if(IPACM_Wlan::dummy_flt_rule_hdl_v6 == NULL) - { - IPACMERR("Dummy ipv6 flt rule has not been installed.\n"); - return IPACM_FAILURE; - } - if(wlan_ap_index >= 2) - { - IPACMERR("Cannot support more than 2 WLAN AP, abort.\n"); - return IPACM_FAILURE; - } - -#ifdef FEATURE_ETH_BRIDGE_LE - offset = IPV6_DEFAULT_FILTERTING_RULES + IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_LAN_CLIENT + wlan_ap_index; -#else -#ifndef CT_OPT - offset = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR) + wlan_ap_index; -#else - offset = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR) + wlan_ap_index; -#endif -#endif - - len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy); - pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); - if (!pFilteringTable) - { - IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); - return IPACM_FAILURE; - } - memset(pFilteringTable, 0, len); - - pFilteringTable->commit = 1; - pFilteringTable->ip = IPA_IP_v6; - pFilteringTable->num_rules = 1; - - memset(&flt_rule, 0, sizeof(flt_rule)); - flt_rule.status = -1; - flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset]; - - flt_rule.rule.retain_hdr = 1; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; - flt_rule.rule.eq_attrib_type = 0; - - memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); - flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v6.dst_addr[0] = prefix[0]; - flt_rule.rule.attrib.u.v6.dst_addr[1] = prefix[1]; - flt_rule.rule.attrib.u.v6.dst_addr[2] = 0x0; - flt_rule.rule.attrib.u.v6.dst_addr[3] = 0x0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; - flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; - flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = 0x0; - flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = 0x0; - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(flt_rule)); - - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) - { - IPACMERR("Failed to modify tcp control filtering rules.\n"); - free(pFilteringTable); - return IPACM_FAILURE; - } - else - { - ipv6_prefix_flt_rule_hdl[0] = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset]; - IPACMDBG_H("IPv6 prefix filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[0]); - } - - free(pFilteringTable); - return IPACM_SUCCESS; + return; } -void IPACM_Wlan::delete_ipv6_prefix_flt_rule() +bool IPACM_Wlan::is_guest_ap() { - if(reset_to_dummy_flt_rule(IPA_IP_v6, ipv6_prefix_flt_rule_hdl[0]) == IPACM_FAILURE) - { - IPACMERR("Failed to delete ipv6 prefix flt rule.\n"); - } - return; + return m_is_guest_ap; } diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Xml.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Xml.cpp index bcb5b6b..073dc98 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Xml.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Xml.cpp @@ -174,7 +174,8 @@ static int ipacm_cfg_xml_parse_tree IPACM_util_icmp_string((char*)xml_node->name, SUBNET_TAG) == 0 || IPACM_util_icmp_string((char*)xml_node->name, IPACMALG_TAG) == 0 || IPACM_util_icmp_string((char*)xml_node->name, ALG_TAG) == 0 || - IPACM_util_icmp_string((char*)xml_node->name, IPACMNat_TAG) == 0) + IPACM_util_icmp_string((char*)xml_node->name, IPACMNat_TAG) == 0 || + IPACM_util_icmp_string((char*)xml_node->name, IP_PassthroughFlag_TAG) == 0) { if (0 == IPACM_util_icmp_string((char*)xml_node->name, IFACE_TAG)) { @@ -196,6 +197,27 @@ static int ipacm_cfg_xml_parse_tree /* go to child */ ret_val = ipacm_cfg_xml_parse_tree(xml_node->children, config); } + else if (IPACM_util_icmp_string((char*)xml_node->name, IP_PassthroughMode_TAG) == 0) + { + IPACMDBG_H("inside IP Passthrough\n"); + content = IPACM_read_content_element(xml_node); + if (content) + { + str_size = strlen(content); + memset(content_buf, 0, sizeof(content_buf)); + memcpy(content_buf, (void *)content, str_size); + if (atoi(content_buf)) + { + config->ip_passthrough_mode = true; + IPACMDBG_H("Passthrough enable %d buf(%d)\n", config->ip_passthrough_mode, atoi(content_buf)); + } + else + { + config->ip_passthrough_mode = false; + IPACMDBG_H("Passthrough enable %d buf(%d)\n", config->ip_passthrough_mode, atoi(content_buf)); + } + } + } else if (IPACM_util_icmp_string((char*)xml_node->name, ODUMODE_TAG) == 0) { IPACMDBG_H("inside ODU-XML\n"); @@ -246,7 +268,7 @@ static int ipacm_cfg_xml_parse_tree str_size = strlen(content); memset(content_buf, 0, sizeof(content_buf)); memcpy(content_buf, (void *)content, str_size); - strncpy(config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].iface_name, content_buf, str_size); + strlcpy(config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].iface_name, content_buf, str_size+1); IPACMDBG_H("Name %s\n", config->iface_config.iface_entries[config->iface_config.num_iface_entries - 1].iface_name); } } diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_cfg.xml b/data-ipa-cfg-mgr/ipacm/src/IPACM_cfg.xml index d16d2ed..ca99d86 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_cfg.xml +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_cfg.xml @@ -67,6 +67,9 @@ <Category>VIRTUAL</Category> </Iface> </IPACMIface> + <IPPassthroughFlag> + <IPPassthroughMode>0</IPPassthroughMode> + </IPPassthroughFlag> <IPACMPrivateSubnet> <Subnet> <SubnetAddress>192.168.225.0</SubnetAddress> diff --git a/data-ipa-cfg-mgr/ipacm/src/Makefile.am b/data-ipa-cfg-mgr/ipacm/src/Makefile.am index 2fdb3f8..7a62a75 100644 --- a/data-ipa-cfg-mgr/ipacm/src/Makefile.am +++ b/data-ipa-cfg-mgr/ipacm/src/Makefile.am @@ -31,10 +31,19 @@ bin_PROGRAMS = ipacm requiredlibs = ${LIBXML_LIB} -lxml2 -lpthread -lnetfilter_conntrack -lnfnetlink\ ../../ipanat/src/libipanat.la -ipacm_LDADD = $(requiredlibs) - 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) diff --git a/data-ipa-cfg-mgr/ipanat/Android.mk b/data-ipa-cfg-mgr/ipanat/Android.mk deleted file mode 100644 index 5053e7d..0000000 --- a/data-ipa-cfg-mgr/ipanat/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(call all-subdir-makefiles) diff --git a/data-ipa-cfg-mgr/ipanat/src/Android.mk b/data-ipa-cfg-mgr/ipanat/src/Android.mk index ecc64c4..ea14920 100644 --- a/data-ipa-cfg-mgr/ipanat/src/Android.mk +++ b/data-ipa-cfg-mgr/ipanat/src/Android.mk @@ -1,3 +1,9 @@ +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) @@ -16,3 +22,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_PRELINK_MODULE := false include $(BUILD_SHARED_LIBRARY) + +endif # $(TARGET_ARCH) +endif +endif
\ No newline at end of file |