From 1dd3bf8eddf212d2fca6dc0bf1aec1ba7d3bbf86 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Sun, 19 Jun 2016 09:05:02 -1000 Subject: [PATCH] Revert "ether: Update ipacm to latest from upstream" * Roll back due to kernel rebase. This reverts commit af5b79d98017da49d6fa5500acd73182f0bcf0d3. Change-Id: Icb067e57a653a32491b6bde42f3eb147d5848c92 --- data-ipa-cfg-mgr/ipacm/inc/IPACM_Config.h | 7 +- data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h | 55 +- data-ipa-cfg-mgr/ipacm/inc/IPACM_Iface.h | 6 - data-ipa-cfg-mgr/ipacm/inc/IPACM_Lan.h | 175 +- data-ipa-cfg-mgr/ipacm/inc/IPACM_LanToLan.h | 169 +- data-ipa-cfg-mgr/ipacm/inc/IPACM_Log.h | 10 +- data-ipa-cfg-mgr/ipacm/inc/IPACM_Routing.h | 3 +- data-ipa-cfg-mgr/ipacm/inc/IPACM_Wan.h | 6 + data-ipa-cfg-mgr/ipacm/inc/IPACM_Wlan.h | 42 +- data-ipa-cfg-mgr/ipacm/inc/IPACM_Xml.h | 4 + data-ipa-cfg-mgr/ipacm/src/Android.mk | 5 +- data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp | 55 +- .../ipacm/src/IPACM_ConntrackListener.cpp | 14 + data-ipa-cfg-mgr/ipacm/src/IPACM_Header.cpp | 11 +- data-ipa-cfg-mgr/ipacm/src/IPACM_Iface.cpp | 45 - .../ipacm/src/IPACM_IfaceManager.cpp | 18 +- data-ipa-cfg-mgr/ipacm/src/IPACM_Lan.cpp | 3895 ++++------------- data-ipa-cfg-mgr/ipacm/src/IPACM_LanToLan.cpp | 1999 ++++----- data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp | 9 +- data-ipa-cfg-mgr/ipacm/src/IPACM_Routing.cpp | 4 +- data-ipa-cfg-mgr/ipacm/src/IPACM_Wan.cpp | 59 +- data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp | 1823 +------- data-ipa-cfg-mgr/ipacm/src/IPACM_Xml.cpp | 26 +- data-ipa-cfg-mgr/ipacm/src/IPACM_cfg.xml | 3 + data-ipa-cfg-mgr/ipacm/src/Makefile.am | 13 +- data-ipa-cfg-mgr/ipanat/src/.Android.mk.swp | Bin 4096 -> 0 bytes data-ipa-cfg-mgr/ipanat/src/Android.mk | 5 +- 27 files changed, 2023 insertions(+), 6438 deletions(-) delete mode 100644 data-ipa-cfg-mgr/ipanat/src/.Android.mk.swp diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Config.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Config.h index 0f58018..5bcb4eb 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Config.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Config.h @@ -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 @@ class IPACM_Config 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,10 +141,7 @@ class IPACM_Config /* 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; diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h index 7f743ba..a6e76d1 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Defs.h @@ -45,6 +45,12 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "IPACM_Log.h" +#ifdef USE_GLIB +#include +#define strlcpy g_strlcpy +#define strlcat g_strlcat +#endif + extern "C" { #include @@ -83,37 +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 IPA_LAN_TO_LAN_MAX_CLIENT (IPA_LAN_TO_LAN_MAX_LAN_CLIENT + IPA_LAN_TO_LAN_MAX_WLAN_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 /*--------------------------------------------------------------------------- @@ -137,7 +122,7 @@ extern "C" ===========================================================================*/ typedef enum { - IPA_CFG_CHANGE_EVENT = 1, /* NULL */ + 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 */ @@ -176,7 +161,7 @@ typedef enum IPA_TETHERING_STATS_UPDATE_EVENT, /* ipacm_event_data_fid */ IPA_NETWORK_STATS_UPDATE_EVENT, /* ipacm_event_data_fid */ - IPA_EXTERNAL_EVENT_MAX = 500, + IPA_EXTERNAL_EVENT_MAX, IPA_HANDLE_WAN_UP, /* ipacm_event_iface_up */ IPA_HANDLE_WAN_DOWN, /* ipacm_event_iface_up */ @@ -188,16 +173,12 @@ typedef enum 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_LAN_CLIENT_ACTIVE, /* ipacm_event_lan_client*/ - IPA_LAN_CLIENT_INACTIVE, /* ipacm_event_lan_client*/ - IPA_LAN_CLIENT_DISCONNECT, /* ipacm_event_lan_client*/ - IPA_LAN_CLIENT_POWER_SAVE, /* ipacm_event_lan_client*/ - IPA_LAN_CLIENT_POWER_RECOVER, /* ipacm_event_lan_client*/ + 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 */ - IPA_ETH_BRIDGE_CLIENT_ADD_EVENT, /* ipacm_event_data_mac */ - IPA_ETH_BRIDGE_CLIENT_DEL_EVENT, /* ipacm_event_data_mac */ - IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT, /* ipacm_event_data_if_cat */ - IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT, /* ipacm_event_data_if_cat */ IPACM_EVENT_MAX } ipa_cm_event_id; @@ -271,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 { diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Iface.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Iface.h index f510561..89bb26f 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Iface.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Iface.h @@ -126,12 +126,6 @@ class IPACM_Iface :public IPACM_Listener /*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_Lan.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Lan.h index 7a93b12..6c54f5e 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Lan.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Lan.h @@ -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,45 +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_subnet_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; - int ipa_if_cate; -}; /* lan iface */ class IPACM_Lan : public IPACM_Iface @@ -192,99 +141,46 @@ class IPACM_Lan : public IPACM_Iface /* 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; - - 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; - - static eth_bridge_subnet_client_info eth_bridge_client[IPA_LAN_TO_LAN_MAX_CLIENT]; - - static int eth_bridge_num_client; - - static bool is_usb_up; - static bool is_cpe_up; - -protected: - - eth_bridge_subnet_client_flt_info eth_bridge_client_flt_info[IPA_LAN_TO_LAN_MAX_CLIENT]; - - int 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; - - int eth_bridge_add_client_flt_rule(uint8_t* mac, ipa_ip_type iptype, int dest_if_cate); - - int eth_bridge_del_client_flt_rule(uint8_t* mac); - int eth_bridge_post_lan_client_event(uint8_t* mac_addr, ipa_cm_event_id evt); + /* 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); - int add_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); - int del_hdr_proc_ctx(); + /* 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); - ipa_hdr_proc_type get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2); + /* 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); - virtual int eth_bridge_install_cache_client_flt_rule(ipa_ip_type iptype); + /* delete filtering rule */ + int eth_bridge_del_flt_rule(uint32_t flt_rule_hdl, ipa_ip_type iptype); - int eth_bridge_add_lan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src, ipa_ip_type iptype); + /* delete routing rule */ + int eth_bridge_del_rt_rule(uint32_t rt_rule_hdl, ipa_ip_type iptype); - int eth_bridge_del_lan_client_rt_rule(uint8_t* mac, eth_bridge_src_iface src); + /* delete header processing context */ + int eth_bridge_del_hdr_proc_ctx(uint32_t hdr_proc_ctx_hdl); - 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_client(uint8_t* mac); - void eth_bridge_del_client(uint8_t* mac); - - int eth_bridge_remove_all_client_flt_rule(ipa_ip_type iptype); - - int eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl); - - bool eth_bridge_is_lan_client(int ipa_if_cate); +protected: - enum ipa_hdr_l2_type eth_bridge_get_l2_hdr_type(); + int each_client_rt_rule_count[IPA_IP_MAX]; - void eth_bridge_get_rt_tbl_name(ipa_ip_type iptype, struct ipa_ioc_get_rt_tbl *rt_tbl, int dest_if_cate); + 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); @@ -292,9 +188,6 @@ class IPACM_Lan : public IPACM_Iface 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(); @@ -309,26 +202,13 @@ class IPACM_Lan : public IPACM_Iface /* 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]; @@ -342,11 +222,17 @@ class IPACM_Lan : public IPACM_Iface uint32_t if_ipv4_subnet; - uint32_t eth_bridge_flt_rule_offset_v4; - uint32_t eth_bridge_flt_rule_offset_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 */ @@ -497,9 +383,6 @@ class IPACM_Lan : public IPACM_Iface /*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 #ifdef FEATURE_IPA_ANDROID #include @@ -50,125 +49,153 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #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_list; -typedef list offload_link_info_list; -typedef list 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; }; -typedef unordered_map client_table_v4; -typedef unordered_map 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 m_client_info; /* client list */ + list 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 m_iface; - void handle_new_lan2lan_connection(ipacm_event_connection* data); + list 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 @@ class IPACM_Routing 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 @@ class IPACM_Routing 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 b4bf50e..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 @@ class IPACM_Wan : public IPACM_Iface 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 @@ class IPACM_Wan : public IPACM_Iface #endif } + static uint32_t getWANIP() + { + return curr_wan_ip; + } + static bool getXlat_Mux_Id() { return xlat_mux_id; diff --git a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Wlan.h b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Wlan.h index c1fce13..eb911ac 100644 --- a/data-ipa-cfg-mgr/ipacm/inc/IPACM_Wlan.h +++ b/data-ipa-cfg-mgr/ipacm/inc/IPACM_Wlan.h @@ -85,38 +85,15 @@ class IPACM_Wlan : public IPACM_Lan 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: - bool is_guest_ap; + bool m_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; - - virtual int eth_bridge_install_cache_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_handle_wlan_SCC_MCC_switch(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 */ + /* handle wlan access mode switch in ethernet bridging*/ void eth_bridge_handle_wlan_mode_switch(); @@ -128,9 +105,6 @@ class IPACM_Wlan : public IPACM_Lan 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; @@ -240,9 +214,6 @@ class IPACM_Wlan : public IPACM_Lan /* 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); @@ -258,11 +229,6 @@ class IPACM_Wlan : public IPACM_Lan /*handle wlan iface down event*/ int handle_down_evt(); - virtual int add_dummy_lan2lan_flt_rule(ipa_ip_type iptype); - - /* 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); 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 6cb5cc8..c7c879b 100644 --- a/data-ipa-cfg-mgr/ipacm/src/Android.mk +++ b/data-ipa-cfg-mgr/ipacm/src/Android.mk @@ -1,5 +1,6 @@ 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))) @@ -27,6 +28,9 @@ LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr LOCAL_CFLAGS := -v LOCAL_CFLAGS += -DFEATURE_IPA_ANDROID +ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT))) +LOCAL_CFLAGS += -DDEBUG +endif ifeq ($(TARGET_BOARD_PLATFORM),msm8998) LOCAL_CFLAGS += -DFEATURE_IPA_V3 @@ -66,7 +70,6 @@ LOCAL_SHARED_LIBRARIES += libxml2 LOCAL_SHARED_LIBRARIES += libnfnetlink LOCAL_SHARED_LIBRARIES += libnetfilter_conntrack LOCAL_SHARED_LIBRARIES += libdhcpcd -LOCAL_CLANG := true include $(BUILD_EXECUTABLE) ################################################################################ diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp index e511eee..df6c888 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Config.cpp @@ -99,16 +99,12 @@ const char *ipacm_event_name[] = { __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_LAN_CLIENT_ACTIVE), /* ipacm_event_lan_client*/ - __stringify(IPA_LAN_CLIENT_INACTIVE), /* ipacm_event_lan_client*/ - __stringify(IPA_LAN_CLIENT_DISCONNECT), /* ipacm_event_lan_client*/ - __stringify(IPA_LAN_CLIENT_POWER_SAVE), /* ipacm_event_lan_client*/ - __stringify(IPA_LAN_CLIENT_POWER_RECOVER), /* ipacm_event_lan_client*/ + __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(IPA_ETH_BRIDGE_CLIENT_ADD_EVENT), /* ipacm_event_data_mac */ - __stringify(IPA_ETH_BRIDGE_CLIENT_DEL_EVENT), /* ipacm_event_data_mac */ - __stringify(IPA_ETH_BRIDGE_HDR_PROC_CTX_SET_EVENT), /* ipacm_event_data_if_cat */ - __stringify(IPA_ETH_BRIDGE_HDR_PROC_CTX_UNSET_EVENT), /* ipacm_event_data_if_cat */ __stringify(IPACM_EVENT_MAX), }; @@ -145,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)); @@ -295,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); @@ -341,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; @@ -784,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)); @@ -794,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)); @@ -842,9 +813,9 @@ int IPACM_Config::DelExtProp(ipa_ip_type ip_type) const char* IPACM_Config::getEventName(ipa_cm_event_id event_id) { - if(event_id >= IPACM_EVENT_MAX) + if(event_id >= sizeof(ipacm_event_name)/sizeof(ipacm_event_name[0])) { - IPACMERR("ERROR: Event name array is not consistent with event array! (id=%d)\n", event_id); + IPACMERR("Event name array is not consistent with event array!\n"); return NULL; } diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp index 33023cb..5e8fb22 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_ConntrackListener.cpp @@ -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() { @@ -700,6 +702,18 @@ bool IPACM_ConntrackListener::AddIface( 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++) { 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 b07cf10..04cb162 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Iface.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Iface.cpp @@ -991,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 259532d..d6ad9a5 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_IfaceManager.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_IfaceManager.cpp @@ -245,12 +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_CLIENT_ADD_EVENT, lan); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_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 @@ -301,12 +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_CLIENT_ADD_EVENT, odu); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_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); @@ -360,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_CLIENT_ADD_EVENT, wl); - IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_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); @@ -417,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 b7eb87a..eadf159 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Lan.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Lan.cpp @@ -55,26 +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_client[IPA_LAN_TO_LAN_MAX_CLIENT]; - -int IPACM_Lan::eth_bridge_num_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; @@ -85,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) @@ -111,39 +90,7 @@ 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((ipa_if_cate == LAN_IF || ipa_if_cate == 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(ipa_if_cate == 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(ipa_if_cate == ODU_IF) { @@ -163,19 +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)); - 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)); @@ -183,11 +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; + memset(ipv6_prefix, 0, sizeof(ipv6_prefix)); /* ODU routing table initilization */ 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) { @@ -220,47 +157,14 @@ 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; inum_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_client_flt_info, 0, IPA_LAN_TO_LAN_MAX_CLIENT * sizeof(eth_bridge_subnet_client_flt_info)); - - 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 */ @@ -476,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) { @@ -578,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) { @@ -673,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; @@ -760,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) @@ -773,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 (ipa_if_cate == 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 (ipa_if_cate == 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_CLIENT_ADD_EVENT); - eth_bridge_add_client(data->mac_addr); -#endif + eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->mac_addr); return; } } @@ -829,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 (ipa_if_cate == 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 (ipa_if_cate == 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_CLIENT_DEL_EVENT); - eth_bridge_del_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; } } @@ -875,124 +728,6 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) handle_software_routing_disable(); break; - case IPA_ETH_BRIDGE_CLIENT_ADD_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_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_client_flt_rule(mac->mac_addr, IPA_IP_v4, mac->ipa_if_cate); - } - if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) - { - eth_bridge_add_client_flt_rule(mac->mac_addr, IPA_IP_v6, mac->ipa_if_cate); - } - } - else - { - IPACMERR("Event MAC is empty.\n"); - } - } - break; - - case IPA_ETH_BRIDGE_CLIENT_DEL_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_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_client_flt_rule(mac->mac_addr) == IPACM_FAILURE) - { - IPACMDBG_H("Failed to delete 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 == ipa_if_cate) - { - IPACMDBG_H("The event was sent by same interface, if_cat: %d ignore. \n", cat->if_cat); - return; - } - - for(i=0; iif_cat == WLAN_IF) - { - eth_bridge_add_lan_client_rt_rule(IPACM_Lan::eth_bridge_client[i].mac, SRC_WLAN, IPA_IP_v4); - eth_bridge_add_lan_client_rt_rule(IPACM_Lan::eth_bridge_client[i].mac, SRC_WLAN, IPA_IP_v6); - } - else - { - eth_bridge_add_lan_client_rt_rule(IPACM_Lan::eth_bridge_client[i].mac, SRC_LAN, IPA_IP_v4); - eth_bridge_add_lan_client_rt_rule(IPACM_Lan::eth_bridge_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 == ipa_if_cate) - { - IPACMDBG_H("The event was sent by same interface, if_cat: %d ignore.\n", cat->if_cat); - return; - } - - for(i=0; iif_cat == WLAN_IF) - { - eth_bridge_del_lan_client_rt_rule(IPACM_Lan::eth_bridge_client[i].mac, SRC_WLAN); - } - else - { - eth_bridge_del_lan_client_rt_rule(IPACM_Lan::eth_bridge_client[i].mac, SRC_LAN); - } - } - } - } - break; - case IPA_CRADLE_WAN_MODE_SWITCH: { IPACMDBG_H("Received IPA_CRADLE_WAN_MODE_SWITCH event.\n"); @@ -1260,11 +995,10 @@ int IPACM_Lan::handle_addr_evt(ipacm_event_data_addr *data) init_fl_rule(data->iptype); install_ipv4_icmp_flt_rule(); -#ifdef FEATURE_ETH_BRIDGE_LE + /* populate the flt rule offset for eth bridge */ - eth_bridge_flt_rule_offset_v4 = ipv4_icmp_flt_rule_hdl[0]; - eth_bridge_install_cache_client_flt_rule(data->iptype); -#endif + 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 { @@ -1352,10 +1086,11 @@ int IPACM_Lan::handle_addr_evt(ipacm_event_data_addr *data) if (num_dft_rt_v6 == 0) { install_ipv6_icmp_flt_rule(); -#ifdef FEATURE_ETH_BRIDGE_LE - eth_bridge_flt_rule_offset_v6 = ipv6_icmp_flt_rule_hdl[0]; - eth_bridge_install_cache_client_flt_rule(data->iptype); -#endif + + /* 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); } num_dft_rt_v6++; @@ -1404,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)) { @@ -1954,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", @@ -2000,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; } @@ -2013,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]; @@ -2038,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*/ } } } @@ -2752,28 +2489,6 @@ int IPACM_Lan::handle_down_evt() goto fail; } -#ifdef FEATURE_ETH_BRIDGE_LE - if(ipa_if_cate == 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(ipa_if_cate == 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) { @@ -2806,10 +2521,6 @@ int IPACM_Lan::handle_down_evt() } IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES); -#ifdef FEATURE_ETH_BRIDGE_LE - eth_bridge_remove_all_client_flt_rule(IPA_IP_v4); -#endif - /* free private-subnet ipv4 filter rules */ if (IPACM_Iface::ipacmcfg->ipa_num_private_subnet > IPA_PRIV_SUBNET_FILTER_RULE_HANDLES) { @@ -2856,9 +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 - eth_bridge_remove_all_client_flt_rule(IPA_IP_v6); -#endif } IPACMDBG_H("Finished delete default iface ipv6 filtering rules \n "); @@ -2895,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_CLIENT_DEL_EVENT); - eth_bridge_del_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) { @@ -2963,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 @@ -3017,24 +2716,7 @@ int IPACM_Lan::handle_down_evt() { 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(); @@ -3255,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) @@ -3319,84 +3003,19 @@ 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) +int IPACM_Lan::reset_to_dummy_flt_rule(ipa_ip_type iptype, 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; + int len, res = IPACM_SUCCESS; struct ipa_flt_rule_mdfy flt_rule; struct ipa_ioc_mdfy_flt_rule* pFilteringTable; + IPACMDBG_H("Reset flt rule to dummy, IP type: %d, hdl: %d\n", iptype, rule_hdl); 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"); + IPACMERR("Error allocate flt rule memory...\n"); return IPACM_FAILURE; } memset(pFilteringTable, 0, len); @@ -3406,60 +3025,57 @@ int IPACM_Lan::add_lan2lan_flt_rule(ipa_ip_type iptype, uint32_t src_v4_addr, ui pFilteringTable->num_rules = 1; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); + flt_rule.status = -1; + flt_rule.rule_hdl = rule_hdl; + + flt_rule.rule.retain_hdr = 0; + flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; if(iptype == IPA_IP_v4) { - IPACMDBG_H("src_v4_addr: %d dst_v4_addr: %d\n", src_v4_addr, dst_v4_addr); + IPACMDBG_H("Reset IPv4 flt rule to dummy\n"); - if(num_lan2lan_flt_rule_v4 >= MAX_OFFLOAD_PAIR) + flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; + flt_rule.rule.attrib.u.v4.dst_addr = ~0; + flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; + flt_rule.rule.attrib.u.v4.src_addr = ~0; + flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; + + memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); + if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { - 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); + IPACMERR("Error modifying filtering rule.\n"); 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; irules[0].rule_hdl, + pFilteringTable->rules[0].status); } + } + else if(iptype == IPA_IP_v6) + { + IPACMDBG_H("Reset IPv6 flt rule to dummy\n"); - 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_SRC_ADDR | IPA_FLT_DST_ADDR; + 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.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.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; + 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.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)) @@ -3470,127 +3086,210 @@ int IPACM_Lan::add_lan2lan_flt_rule(ipa_ip_type iptype, uint32_t src_v4_addr, ui } 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, + IPACMDBG_H("Flt rule reset to dummy, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl, pFilteringTable->rules[0].status); } } - else if(iptype == IPA_IP_v6) + else + { + IPACMERR("IP type is not expected.\n"); + res = IPACM_FAILURE; + goto fail; + } + +fail: + free(pFilteringTable); + return res; +} + +void IPACM_Lan::post_del_self_evt() +{ + ipacm_cmd_q_data evt; + ipacm_event_data_fid* fid; + fid = (ipacm_event_data_fid*)malloc(sizeof(ipacm_event_data_fid)); + if(fid == NULL) + { + IPACMERR("Failed to allocate fid memory.\n"); + return; + } + memset(fid, 0, sizeof(ipacm_event_data_fid)); + memset(&evt, 0, sizeof(ipacm_cmd_q_data)); + + fid->if_index = ipa_if_num; + + evt.evt_data = (void*)fid; + evt.event = IPA_LAN_DELETE_SELF; + + IPACMDBG_H("Posting event IPA_LAN_DELETE_SELF\n"); + IPACM_EvtDispatcher::PostEvt(&evt); +} + +/*handle reset usb-client rt-rules */ +int IPACM_Lan::handle_lan_client_reset_rt(ipa_ip_type iptype) +{ + int i, res = IPACM_SUCCESS; + + /* clean eth-client routing rules */ + IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client); + for (i = 0; i < num_eth_client; i++) { - if(num_lan2lan_flt_rule_v6 >= MAX_OFFLOAD_PAIR) + res = delete_eth_rtrules(i, iptype); + if (res != IPACM_SUCCESS) { - IPACMERR("Lan2lan flt rule table is full, not able to add.\n"); - res = IPACM_FAILURE; - goto fail; + IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype); + return res; + } + } /* end of for loop */ + + /* Reset ip-address */ + for (i = 0; i < num_eth_client; i++) + { + if(iptype == IPA_IP_v4) + { + get_client_memptr(eth_client, i)->ipv4_set = false; } - if(src_v6_addr == NULL || dst_v6_addr == NULL) + else { - IPACMERR("Got IPv6 flt rule but without IPv6 src/dst addr.\n"); - res = IPACM_FAILURE; - goto fail; + get_client_memptr(eth_client, i)->ipv6_set = 0; } - 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]); + } /* end of for loop */ + return res; +} + +int IPACM_Lan::install_ipv4_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); - if(false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6)) + flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len); + if (!flt_rule) { - IPACMERR("Failed to get routing table %s handle.\n", IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6.name); - res = IPACM_FAILURE; - goto fail; + IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); + return IPACM_FAILURE; } - 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; icommit = 1; + flt_rule->ep = rx_prop->rx[0].src_pipe; + flt_rule->global = false; + flt_rule->ip = IPA_IP_v4; + 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 = 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_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)); + + if (m_filtering.AddFilteringRule(flt_rule) == false) { - if(lan2lan_flt_rule_hdl_v6[i].valid == false) - { - flt_rule.rule_hdl = lan2lan_flt_rule_hdl_v6[i].rule_hdl; - break; - } + IPACMERR("Error Adding Filtering rule, aborting...\n"); + free(flt_rule); + return IPACM_FAILURE; } - if(i == MAX_OFFLOAD_PAIR) + else { - IPACMERR("Failed to find a filtering rule handle.\n"); - res = IPACM_FAILURE; - goto fail; + IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1); + ipv4_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl; + IPACMDBG_H("IPv4 icmp filter rule HDL:0x%x\n", ipv4_icmp_flt_rule_hdl[0]); + free(flt_rule); } + } + return IPACM_SUCCESS; +} - 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; +int IPACM_Lan::install_ipv6_icmp_flt_rule() +{ - 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); + int len; + struct ipa_ioc_add_flt_rule* flt_rule; + struct ipa_flt_rule_add flt_rule_entry; - 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; + 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.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; + 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; - memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) + 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 = 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 |= 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 modifying filtering rule.\n"); - res = IPACM_FAILURE; - goto fail; + IPACMERR("Error Adding Filtering rule, aborting...\n"); + free(flt_rule); + return IPACM_FAILURE; } 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); + 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); } } - else - { - IPACMERR("IP type is not expected.\n"); - res = IPACM_FAILURE; - goto fail; - } - -fail: - free(pFilteringTable); - return res; + return IPACM_SUCCESS; } -int IPACM_Lan::add_dummy_lan2lan_flt_rule(ipa_ip_type iptype) +int IPACM_Lan::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); + IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy private subnet filtering rule.\n", dev_name); return 0; } + if(iptype == IPA_IP_v6) + { + IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\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); + len = sizeof(struct ipa_ioc_add_flt_rule) + IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(struct ipa_flt_rule_add); pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); if (pFilteringTable == NULL) @@ -3604,7 +3303,7 @@ int IPACM_Lan::add_dummy_lan2lan_flt_rule(ipa_ip_type iptype) pFilteringTable->ep = rx_prop->rx[0].src_pipe; pFilteringTable->global = false; pFilteringTable->ip = iptype; - pFilteringTable->num_rules = MAX_OFFLOAD_PAIR; + pFilteringTable->num_rules = IPA_MAX_PRIVATE_SUBNET_ENTRIES; memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); @@ -3627,27 +3326,27 @@ int IPACM_Lan::add_dummy_lan2lan_flt_rule(ipa_ip_type iptype) flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; flt_rule.rule.attrib.u.v4.dst_addr = ~0; - for(i=0; irules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); } if (false == m_filtering.AddFilteringRule(pFilteringTable)) { - IPACMERR("Error adding dummy lan2lan v4 flt rule\n"); + IPACMERR("Error adding dummy private subnet 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); + IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES); /* copy filter rule hdls */ - for (int i = 0; i < MAX_OFFLOAD_PAIR; i++) + for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES; 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); + private_fl_rule_hdl[i] = pFilteringTable->rules[i].flt_rule_hdl; + IPACMDBG_H("Private subnet v4 flt rule %d hdl:0x%x\n", i, private_fl_rule_hdl[i]); } else { @@ -3658,2611 +3357,257 @@ int IPACM_Lan::add_dummy_lan2lan_flt_rule(ipa_ip_type iptype) } } } - 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; irules[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; icommit = 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_hdl = rule_hdl; - - flt_rule.rule.retain_hdr = 0; - flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; - - if(iptype == IPA_IP_v4) - { - IPACMDBG_H("Reset IPv4 flt rule to dummy\n"); - - flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; - flt_rule.rule.attrib.u.v4.dst_addr = ~0; - flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; - flt_rule.rule.attrib.u.v4.src_addr = ~0; - flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; - - 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 - { - IPACMDBG_H("Flt rule reset to dummy, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl, - pFilteringTable->rules[0].status); - } - } - else if(iptype == IPA_IP_v6) - { - IPACMDBG_H("Reset IPv6 flt rule to dummy\n"); - - flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; - 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.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.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; - 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; - - - 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 - { - IPACMDBG_H("Flt rule reset to dummy, 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_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; inum_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; jhdr[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; inum_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; jhdr[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; icommit = 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); - - strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v4.name, sizeof(rt_rule->rt_tbl_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_indexnum_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; -#ifdef FEATURE_IPA_V3 - rt_rule_entry->rule.hashable = true; -#endif - 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]); - - strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan2lan_v6.name, sizeof(rt_rule->rt_tbl_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_indexnum_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; -#ifdef FEATURE_IPA_V3 - rt_rule_entry->rule.hashable = true; -#endif - 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; iif_index = ipa_if_num; - - evt.evt_data = (void*)fid; - evt.event = IPA_LAN_DELETE_SELF; - - IPACMDBG_H("Posting event IPA_LAN_DELETE_SELF\n"); - IPACM_EvtDispatcher::PostEvt(&evt); -} - -/*handle reset usb-client rt-rules */ -int IPACM_Lan::handle_lan_client_reset_rt(ipa_ip_type iptype) -{ - int i, res = IPACM_SUCCESS; - - /* clean eth-client routing rules */ - IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client); - for (i = 0; i < num_eth_client; i++) - { - res = delete_eth_rtrules(i, iptype); - if (res != IPACM_SUCCESS) - { - IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype); - return res; - } - } /* 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++) - { - if(iptype == IPA_IP_v4) - { - get_client_memptr(eth_client, i)->ipv4_set = false; - } - else - { - get_client_memptr(eth_client, i)->ipv6_set = 0; - } - } /* end of for loop */ - 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; - 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_v4; - 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 = 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_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)); - - 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_v4, 1); - ipv4_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl; - IPACMDBG_H("IPv4 icmp filter rule HDL:0x%x\n", ipv4_icmp_flt_rule_hdl[0]); - free(flt_rule); - } - } - return IPACM_SUCCESS; -} - -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 = 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 |= 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; -} - -void IPACM_Lan::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 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); - - pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); - if (pFilteringTable == NULL) - { - IPACMERR("Error allocate flt table memory...\n"); - return; - } - memset(pFilteringTable, 0, len); - - 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; - - memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); - - flt_rule.at_rear = true; - flt_rule.flt_rule_hdl = -1; - flt_rule.status = -1; - - flt_rule.rule.retain_hdr = 1; - flt_rule.rule.to_uc = 0; - flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; -#ifdef FEATURE_IPA_V3 - flt_rule.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)<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)<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)<rules[2]), &flt_rule, 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) - { - for(i=0; irules[i].flt_rule_hdl; - } - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, NUM_TCP_CTL_FLT_RULE); - } - else - { - for(i=0; irules[i].flt_rule_hdl; - } - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, NUM_TCP_CTL_FLT_RULE); - } - } - -fail: - free(pFilteringTable); - return; -} - -int IPACM_Lan::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 private subnet filtering rule.\n", dev_name); - return 0; - } - - if(iptype == IPA_IP_v6) - { - IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\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_MAX_PRIVATE_SUBNET_ENTRIES * 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_MAX_PRIVATE_SUBNET_ENTRIES; - - 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; -#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)); - - 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; irules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); - } - - if (false == m_filtering.AddFilteringRule(pFilteringTable)) - { - IPACMERR("Error adding dummy private subnet v4 flt rule\n"); - res = IPACM_FAILURE; - goto fail; - } - else - { - IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES); - /* copy filter rule hdls */ - for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++) - { - if (pFilteringTable->rules[i].status == 0) - { - private_fl_rule_hdl[i] = pFilteringTable->rules[i].flt_rule_hdl; - IPACMDBG_H("Private subnet v4 flt rule %d hdl:0x%x\n", i, private_fl_rule_hdl[i]); - } - else - { - IPACMERR("Failed adding lan2lan v4 flt rule %d\n", i); - res = IPACM_FAILURE; - goto fail; - } - } - } - } -fail: - free(pFilteringTable); - return res; -} - -int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype) -{ - int i, len, res = IPACM_SUCCESS; - 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_v6) - { - IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\n", dev_name); - return 0; - } - else - { - for(i=0; iipa_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; - - for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++) - { - flt_rule.rule_hdl = private_fl_rule_hdl[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)); - IPACMDBG_H(" IPACM private subnet_addr as: 0x%x entry(%d)\n", flt_rule.rule.attrib.u.v4.dst_addr, i); - } - - if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) - { - IPACMERR("Failed to modify private subnet filtering rules.\n"); - res = IPACM_FAILURE; - goto fail; - } - } -fail: - if(pFilteringTable != NULL) - { - free(pFilteringTable); - } - return res; -} - -int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) -{ - if(prefix == NULL) - { - IPACMERR("IPv6 prefix is empty.\n"); - return IPACM_FAILURE; - } - IPACMDBG_H("Receive IPv6 prefix: 0x%08x%08x.\n", prefix[0], prefix[1]); - - 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 = 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 |= IPA_FLT_DST_ADDR; - flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = prefix[0]; - flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = prefix[1]; - flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x0; - flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x0; - flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; - flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; - flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x0; - flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x0; - memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_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_prefix_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl; - IPACMDBG_H("IPv6 prefix filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[0]); - free(flt_rule); - } - } - return IPACM_SUCCESS; -} - -void IPACM_Lan::delete_ipv6_prefix_flt_rule() -{ - if(m_filtering.DeleteFilteringHdls(ipv6_prefix_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE) == false) - { - IPACMERR("Failed to delete ipv6 prefix flt rule.\n"); - return; - } - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE); - return; -} - -int IPACM_Lan::handle_addr_evt_odu_bridge(ipacm_event_data_addr* data) -{ - int fd, res = IPACM_SUCCESS; - struct in6_addr ipv6_addr; - if(data == NULL) - { - IPACMERR("Failed to get interface IP address.\n"); - return IPACM_FAILURE; - } - - if(data->iptype == IPA_IP_v6) - { - fd = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR); - if(fd == 0) - { - IPACMERR("Failed to open %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU); - return IPACM_FAILURE; - } - - memcpy(&ipv6_addr, data->ipv6_addr, sizeof(struct in6_addr)); - - if( ioctl(fd, ODU_BRIDGE_IOC_SET_LLV6_ADDR, &ipv6_addr) ) - { - IPACMERR("Failed to write IPv6 address to odu driver.\n"); - res = IPACM_FAILURE; - } - num_dft_rt_v6++; - close(fd); - } - - 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; - mac->ipa_if_cate = ipa_if_cate; - - evt_data.event = evt; - evt_data.evt_data = (void*)mac; - IPACMDBG_H("Posting event: %d if_index: %d if_cate: %d\n", evt, mac->if_index, mac->ipa_if_cate); - IPACM_EvtDispatcher::PostEvt(&evt_data); - return IPACM_SUCCESS; -} - -int IPACM_Lan::eth_bridge_add_client_flt_rule(uint8_t* mac, ipa_ip_type iptype, int dest_if_cate) -{ - int i, len, res = IPACM_SUCCESS, client_position; - struct ipa_flt_rule_add flt_rule_entry; - struct ipa_ioc_add_flt_rule_after *pFilteringTable = NULL; - struct ipa_ioc_get_rt_tbl rt_tbl; - enum ipa_hdr_l2_type hdr_type; - bool client_is_found = false; - uint32_t rule_hdl; - -#ifdef FEATURE_IPA_V3 - 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; - } - - 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]); - - for(i=0; icommit = 1; - pFilteringTable->ep = rx_prop->rx[0].src_pipe; - pFilteringTable->ip = iptype; - pFilteringTable->num_rules = 1; - pFilteringTable->add_after_hdl = iptype == IPA_IP_v4? - eth_bridge_flt_rule_offset_v4: eth_bridge_flt_rule_offset_v6; - - 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; - IPACMDBG_H("Filtering rule uses routing table: %s\n",rt_tbl.name); - - memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); - if(hdr_type == IPA_HDR_L2_ETHERNET_II) - { - flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; - } - else if(hdr_type == IPA_HDR_L2_802_3) - { - flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; - } - else - { - IPACMERR("hdr type is not expected.\n"); - res = IPACM_FAILURE; - goto fail; - } - 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 fail; - } - rule_hdl = pFilteringTable->rules[0].flt_rule_hdl; - - memcpy(eth_bridge_client_flt_info[client_position].mac, mac, sizeof(eth_bridge_client_flt_info[client_position].mac)); - if(iptype == IPA_IP_v4) - { - eth_bridge_client_flt_info[client_position].flt_rule_set_v4 = true; - eth_bridge_client_flt_info[client_position].flt_rule_hdl_v4 = rule_hdl; - } - else - { - eth_bridge_client_flt_info[client_position].flt_rule_set_v6 = true; - eth_bridge_client_flt_info[client_position].flt_rule_hdl_v6 = rule_hdl; - } - -fail: - if(pFilteringTable) - free(pFilteringTable); -#endif - return res; -} - -int IPACM_Lan::eth_bridge_del_client_flt_rule(uint8_t* mac) -{ - 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.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - int i, j, res = IPACM_SUCCESS; - for(i=0; icommit = 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 = ipa_if_cate; - - 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(ipa_if_cate == LAN_IF || ipa_if_cate == 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 = ipa_if_cate; - - 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) -{ - if(t1 == IPA_HDR_L2_ETHERNET_II) - { - if(t2 == IPA_HDR_L2_ETHERNET_II) - { - return IPA_HDR_PROC_ETHII_TO_ETHII; - } - if(t2 == IPA_HDR_L2_802_3) - { - return IPA_HDR_PROC_ETHII_TO_802_3; - } - } - - if(t1 == IPA_HDR_L2_802_3) - { - if(t2 == IPA_HDR_L2_ETHERNET_II) - { - return IPA_HDR_PROC_802_3_TO_ETHII; - } - if(t2 == IPA_HDR_L2_802_3) - { - return IPA_HDR_PROC_802_3_TO_802_3; - } - } - - return IPA_HDR_PROC_NONE; -} - -int IPACM_Lan::eth_bridge_install_cache_client_flt_rule(ipa_ip_type iptype) -{ - int i; - - IPACMDBG_H("There are %d clients cached.\n",IPACM_Lan::eth_bridge_num_client); - for(i=0; imac, 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; imac, 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; imac, 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; imac, 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; -#ifdef FEATURE_IPA_V3 - rt_rule.rule.hashable = true; -#endif - rt_rule.rule.hdr_hdl = 0; - if(src == SRC_LAN) - { - if (ipa_if_cate == LAN_IF) - { - rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::cpe_to_usb_hdr_proc_ctx.proc_ctx_hdl; - } - else if (ipa_if_cate == 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(ipa_if_cate == LAN_IF) - { - rt_rule.rule.hdr_proc_ctx_hdl = IPACM_Lan::wlan_to_usb_hdr_proc_ctx.proc_ctx_hdl; - } - else if(ipa_if_cate == 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; inum_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; irt_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; irt_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; imac, 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; imac, 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; irt_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; imac, 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; imac, 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; irt_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; iipa_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); -void IPACM_Lan::eth_bridge_del_client(uint8_t* mac) -{ - int i, j, mem_size; - int num_client = IPACM_Lan::eth_bridge_num_client; - if(mac == NULL) - { - IPACMERR("Mac address is empty.\n"); - return; - } + pFilteringTable->commit = 1; + pFilteringTable->ip = iptype; + pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet; - for(i=0; irt_tbl_default_v4)) { - IPACMDBG_H("Found LAN client at position %d.\n", i); - break; + IPACMERR("Failed to get routing table handle.\n"); + res = IPACM_FAILURE; + goto fail; } - } - - if(i == num_client) - { - IPACMDBG_H("Not finding the LAN client.\n"); - return; - } - mem_size = sizeof(eth_bridge_subnet_client_info); - for(j=i+1; jrt_tbl_default_v4.hdl; + IPACMDBG_H("Private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name); - if(rx_prop == NULL) - { - IPACMDBG_H("No rx property, return.\n"); - return IPACM_SUCCESS; - } + 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; - i = 0; - j = 0; - while(iipa_num_private_subnet); i++) { - temp_eth_bridge_flt_rule[j] = eth_bridge_client_flt_info[i].flt_rule_hdl_v6; - eth_bridge_client_flt_info[i].flt_rule_set_v6 = false; - j++; + flt_rule.rule_hdl = private_fl_rule_hdl[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)); + IPACMDBG_H(" IPACM private subnet_addr as: 0x%x entry(%d)\n", flt_rule.rule.attrib.u.v4.dst_addr, i); } - /* if both IPv4/IPv6 flt rules have been removed, remove the client info from the array */ - if(!eth_bridge_client_flt_info[i].flt_rule_set_v4 || !eth_bridge_client_flt_info[i].flt_rule_set_v6) - { - memcpy(&(eth_bridge_client_flt_info[i]), &(eth_bridge_client_flt_info[client_flt_info_count-1]), sizeof(eth_bridge_subnet_client_flt_info)); - memset(&(eth_bridge_client_flt_info[client_flt_info_count-1]), 0, sizeof(eth_bridge_subnet_client_flt_info)); - client_flt_info_count--; - IPACMDBG_H("Now client flt info count: %d\n", client_flt_info_count); - } - else + if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) { - i++; + IPACMERR("Failed to modify private subnet filtering rules.\n"); + res = IPACM_FAILURE; + goto fail; } } - if (m_filtering.DeleteFilteringHdls(temp_eth_bridge_flt_rule, iptype, j) == false) +fail: + if(pFilteringTable != NULL) { - IPACMERR("Error Deleting Filtering Rule, aborting...\n"); - return IPACM_FAILURE; + free(pFilteringTable); } - - IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, j); - return IPACM_SUCCESS; + return res; } -int IPACM_Lan::eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl) +int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) { - if(hdr_hdl == NULL) + if(prefix == NULL) { - IPACMDBG_H("Hdr handle pointer is empty.\n"); + IPACMERR("IPv6 prefix is empty.\n"); return IPACM_FAILURE; } + IPACMDBG_H("Receive IPv6 prefix: 0x%08x%08x.\n", prefix[0], prefix[1]); - struct ipa_ioc_get_hdr hdr; - memset(&hdr, 0, sizeof(hdr)); + int len; + struct ipa_ioc_add_flt_rule* flt_rule; + struct ipa_flt_rule_add flt_rule_entry; - memcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name)); - if(m_header.GetHeaderHandle(&hdr) == false) + if(rx_prop != NULL) { - IPACMERR("Failed to get template hdr hdl.\n"); - return IPACM_FAILURE; - } - - *hdr_hdl = hdr.hdl; - return IPACM_SUCCESS; -} + len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); -int IPACM_Lan::del_hdr_proc_ctx() -{ - if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true) - { - if((ipa_if_cate == WLAN_IF) - || (IPACM_Lan::is_usb_up == false && IPACM_Lan::is_cpe_up == false)) + flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len); + if (!flt_rule) { - 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; + IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); + return IPACM_FAILURE; + } - ipacm_cmd_q_data evt_data; - memset(&evt_data, 0, sizeof(ipacm_cmd_q_data)); + 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; - 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 = ipa_if_cate; + memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); - 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); - } - } + 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 = 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 |= IPA_FLT_DST_ADDR; + flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = prefix[0]; + flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = prefix[1]; + flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x0; + flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x0; + flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; + flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; + flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x0; + flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x0; + memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); - if(IPACM_Lan::wlan_to_usb_hdr_proc_ctx.valid == true) - { - if(ipa_if_cate == WLAN_IF || IPACM_Lan::is_usb_up == false) + if (m_filtering.AddFilteringRule(flt_rule) == 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; + 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_prefix_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl; + IPACMDBG_H("IPv6 prefix filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[0]); + free(flt_rule); } } + return IPACM_SUCCESS; +} - if(IPACM_Lan::wlan_to_cpe_hdr_proc_ctx.valid == true) +void IPACM_Lan::delete_ipv6_prefix_flt_rule() +{ + if(m_filtering.DeleteFilteringHdls(ipv6_prefix_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE) == false) { - if(ipa_if_cate == 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; - } + IPACMERR("Failed to delete ipv6 prefix flt rule.\n"); + return; } + IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE); + return; +} - if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true) +int IPACM_Lan::handle_addr_evt_odu_bridge(ipacm_event_data_addr* data) +{ + int fd, res = IPACM_SUCCESS; + struct in6_addr ipv6_addr; + if(data == NULL) { - if(ipa_if_cate == WLAN_IF) - { - 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; - } + IPACMERR("Failed to get interface IP address.\n"); + return IPACM_FAILURE; } - if(IPACM_Lan::cpe_to_usb_hdr_proc_ctx.valid == true && IPACM_Lan::usb_to_cpe_hdr_proc_ctx.valid == true) + if(data->iptype == IPA_IP_v6) { - if(ipa_if_cate == LAN_IF || ipa_if_cate == ODU_IF) + fd = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR); + if(fd == 0) { - 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)); + IPACMERR("Failed to open %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU); + return IPACM_FAILURE; + } - 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 = ipa_if_cate; + memcpy(&ipv6_addr, data->ipv6_addr, sizeof(struct in6_addr)); - 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( ioctl(fd, ODU_BRIDGE_IOC_SET_LLV6_ADDR, &ipv6_addr) ) + { + IPACMERR("Failed to write IPv6 address to odu driver.\n"); + res = IPACM_FAILURE; } + num_dft_rt_v6++; + close(fd); } - return IPACM_SUCCESS; -} -bool IPACM_Lan::eth_bridge_is_lan_client(int ipa_if_cate) -{ - if(ipa_if_cate == ODU_IF || ipa_if_cate == LAN_IF) - { - return true; - } - else - { - return false; - } + return res; } -void IPACM_Lan::eth_bridge_get_rt_tbl_name(ipa_ip_type iptype, struct ipa_ioc_get_rt_tbl *rt_tbl, int dest_if_cate) +ipa_hdr_proc_type IPACM_Lan::eth_bridge_get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2) { - if(iptype == IPA_IP_v4) //IPv4 case + if(t1 == IPA_HDR_L2_ETHERNET_II) { - if(eth_bridge_is_lan_client(dest_if_cate) != true) //dest is WLAN client + if(t2 == IPA_HDR_L2_ETHERNET_II) { - if(eth_bridge_is_lan_client(ipa_if_cate) == true) //self is LAN client - { - strlcpy(rt_tbl->name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4.name, - sizeof(rt_tbl->name)); - } - else //self is WLAN client - { - strlcpy(rt_tbl->name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v4.name, - sizeof(rt_tbl->name)); - } + return IPA_HDR_PROC_ETHII_TO_ETHII; } - else //dest is LAN client + if(t2 == IPA_HDR_L2_802_3) { - if(eth_bridge_is_lan_client(ipa_if_cate) == true) //self is LAN client - { - strlcpy(rt_tbl->name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_lan_v4.name, - sizeof(rt_tbl->name)); - } - else //self is WLAN client - { - strlcpy(rt_tbl->name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v4.name, - sizeof(rt_tbl->name)); - } + return IPA_HDR_PROC_ETHII_TO_802_3; } } - else //IPv6 case + + if(t1 == IPA_HDR_L2_802_3) { - if(eth_bridge_is_lan_client(dest_if_cate) != true) //dest is WLAN client + if(t2 == IPA_HDR_L2_ETHERNET_II) { - if(eth_bridge_is_lan_client(ipa_if_cate) == true) //self is LAN client - { - strlcpy(rt_tbl->name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6.name, - sizeof(rt_tbl->name)); - } - else //self is WLAN client - { - strlcpy(rt_tbl->name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_wlan_wlan_v6.name, - sizeof(rt_tbl->name)); - } + return IPA_HDR_PROC_802_3_TO_ETHII; } - else //dest is LAN client + if(t2 == IPA_HDR_L2_802_3) { - if(eth_bridge_is_lan_client(ipa_if_cate) == true) //self is LAN client - { - strlcpy(rt_tbl->name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_lan_v6.name, - sizeof(rt_tbl->name)); - } - else //self is WLAN client - { - strlcpy(rt_tbl->name, IPACM_Iface::ipacmcfg->rt_tbl_eth_bridge_lan_wlan_v6.name, - sizeof(rt_tbl->name)); - } + return IPA_HDR_PROC_802_3_TO_802_3; } } + + return IPA_HDR_PROC_NONE; } -enum ipa_hdr_l2_type IPACM_Lan::eth_bridge_get_l2_hdr_type() +int IPACM_Lan::eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl) { - if(eth_bridge_is_lan_client(ipa_if_cate)) + if(hdr_hdl == NULL) { - return IPACM_Lan::lan_hdr_type; + IPACMDBG_H("Hdr handle pointer is empty.\n"); + return IPACM_FAILURE; } - else + + struct ipa_ioc_get_hdr hdr; + memset(&hdr, 0, sizeof(hdr)); + + memcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name)); + if(m_header.GetHeaderHandle(&hdr) == false) { - return IPACM_Lan::wlan_hdr_type; + IPACMERR("Failed to get template hdr hdl.\n"); + return IPACM_FAILURE; } + + *hdr_hdl = hdr.hdl; + return IPACM_SUCCESS; } int IPACM_Lan::handle_cradle_wan_mode_switch(bool is_wan_bridge_mode) @@ -6512,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; inum_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; irules[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 -#include #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: - { - 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: + case IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH: { - 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]); - - bool client_not_found; - client_info* client_ptr; + list::iterator it; - if(data->iptype == IPA_IP_v4) + 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++) { - 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 - { - 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); + + /* install inter-interface rules */ + if(it->get_m_support_inter_iface_offload()) + it->add_all_inter_interface_client_flt_rule(data->iptype); - 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 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) + for(it = ++m_iface.begin(); it != m_iface.end(); it++) { - client_ptr->ip.ipv4_addr = data->ipv4_addr; - } - else - { - 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::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; - - offload_link_info link_info; + it_target_iface->handle_down_event(); + m_iface.erase(it_target_iface); + return; +} - 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; - } - - //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::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::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) - { - num_offload_pair_v4_ --; - IPACMDBG_H("Now the number of v4 offload pair is %d\n", num_offload_pair_v4_); - } - else + if(it_iface->get_iface_pointer() == data->p_iface) //found the interface { - 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::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; - } - - 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::iterator it; - 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; - } + list::iterator it; - bool err_flag; - peer_info_list::iterator client_it; - peer_info_list::iterator peer_it; - client_info* peer; - - 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::iterator it; + list::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::iterator it; + ipa_hdr_l2_type peer_l2_type; + peer_iface_info &peer = m_peer_iface_info.front(); - 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 + 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) { - 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 + 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_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; iinter_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; iinter_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) - { - 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) + 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; isrc 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; iintra_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; - } + list::iterator it_iface; + list::iterator it_client; - peer_info_list::iterator it; - peer_info new_peer; - bool ret = false; - - 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::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::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::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(IPACM_Iface::m_routing.GetRoutingTable(&rt_tbl) == false) { - 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 - { - 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) + for(it_flt = peer->flt_rule.begin(); it_flt != peer->flt_rule.end(); it_flt++) { - IPACMDBG_H("Erase link info for both src and dst entries.\n"); - erase_offload_link(data->iptype, src_client_ptr, dst_client_ptr); - } - else - { - if(res && src_client_ptr->is_powersave && (dst_client_ptr->is_active || dst_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 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)) - { - 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; - } + list::iterator it; - peer_info_list::iterator it; - bool ret = false; - - 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; +} + +void IPACM_LanToLan_Iface::del_client_flt_rule(peer_iface_info *peer, client_info *client) +{ + list::iterator it_flt; - ret = false; - for(it = dst_client->peer.begin(); it != dst_client->peer.end(); it++) + 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]) { - 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_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]) + { + 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::iterator it_other_iface; + list::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; - } + list::iterator it; - 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]); - - 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::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; - } + list::iterator it_peer_info; + list::iterator it_client; + ipa_hdr_l2_type peer_l2_hdr_type; + bool flag[IPA_HDR_L2_MAX]; + int i; - 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 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) - { - 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++) + 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++) { - 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) + /* modify routing rules for intra-interface communication */ + IPACMDBG_H("Modify rt rules for intra-interface communication.\n"); + if(m_support_intra_iface_offload) { - 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++) - { - 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::iterator it_client; + list::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); - if(is_lan2lan_connection(new_conn) == false) + client_info &front_client = m_client_info.front(); + + /* 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::iterator it_client; + list::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(memcmp(it_client->mac_addr, mac, sizeof(it_client->mac_addr)) == 0) //found the client + { + IPACMDBG_H("Found the client.\n"); + break; + } + } + + if(it_client != m_client_info.end()) //if we found the client { - if(client_info_v4_.count(data->src_ipv4_addr) == 0 || client_info_v4_.count(data->dst_ipv4_addr) == 0) + /* uninstall inter-interface rules */ + if(m_support_inter_iface_offload) { - IPACMDBG("Either source or destination is not in client table\n"); - return false; + 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)); + + /* 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; + } + } } - 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; + /* 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)); + } - return (src_type != dst_type); + /* 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::iterator it_peer; + list::iterator it_client; + int i, j, k; - if(new_conn->iptype == IPA_IP_v4) + 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(m_support_inter_iface_offload) { - num_private_subnet = IPACM_Iface::ipacmcfg->ipa_num_private_subnet; - for(i=0; isrc_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::iterator it_flt; + list::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 bd5e048..fe13e67 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Main.cpp @@ -684,6 +684,7 @@ void* ipa_driver_msg_notifier(void *param) void IPACM_Sig_Handler(int sig) { + int cnt; ipacm_cmd_q_data evt_data; printf("Received Signal: %d\n", sig); @@ -729,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(); @@ -912,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 6230cbf..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; @@ -491,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); } @@ -1888,27 +1893,35 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) memset(&firewall_config, 0, sizeof(firewall_config)); strlcpy(firewall_config.firewall_config_file, "/etc/mobileap_firewall.xml", sizeof(firewall_config.firewall_config_file)); - IPACMDBG_H("Firewall XML file is %s \n", firewall_config.firewall_config_file); - if (IPACM_SUCCESS == IPACM_read_firewall_xml(firewall_config.firewall_config_file, &firewall_config)) + if (firewall_config.firewall_config_file) { - IPACMDBG_H("QCMAP Firewall XML read OK \n"); - /* find the number of v4/v6 firewall rules */ - for (i = 0; i < firewall_config.num_extd_firewall_entries; i++) + IPACMDBG_H("Firewall XML file is %s \n", firewall_config.firewall_config_file); + if (IPACM_SUCCESS == IPACM_read_firewall_xml(firewall_config.firewall_config_file, &firewall_config)) { - if (firewall_config.extd_firewall_entries[i].ip_vsn == 4) - { - rule_v4++; - } - else - { - rule_v6++; - } + IPACMDBG_H("QCMAP Firewall XML read OK \n"); + /* find the number of v4/v6 firewall rules */ + for (i = 0; i < firewall_config.num_extd_firewall_entries; i++) + { + if (firewall_config.extd_firewall_entries[i].ip_vsn == 4) + { + rule_v4++; + } + else + { + rule_v6++; + } + } + IPACMDBG_H("firewall rule v4:%d v6:%d total:%d\n", rule_v4, rule_v6, firewall_config.num_extd_firewall_entries); + } + else + { + IPACMERR("QCMAP Firewall XML read failed, no that file, use default configuration \n"); } - IPACMDBG_H("firewall rule v4:%d v6:%d total:%d\n", rule_v4, rule_v6, firewall_config.num_extd_firewall_entries); } else { - IPACMERR("QCMAP Firewall XML read failed, no that file, use default configuration \n"); + IPACMERR("No firewall xml mentioned \n"); + return IPACM_FAILURE; } /* construct ipa_ioc_add_flt_rule with N firewall rules */ @@ -2612,14 +2625,22 @@ int IPACM_Wan::config_dft_firewall_rules_ex(struct ipa_flt_rule_add *rules, int memset(&firewall_config, 0, sizeof(firewall_config)); strlcpy(firewall_config.firewall_config_file, "/etc/mobileap_firewall.xml", sizeof(firewall_config.firewall_config_file)); - IPACMDBG_H("Firewall XML file is %s \n", firewall_config.firewall_config_file); - if (IPACM_SUCCESS == IPACM_read_firewall_xml(firewall_config.firewall_config_file, &firewall_config)) + if (firewall_config.firewall_config_file) { - IPACMDBG_H("QCMAP Firewall XML read OK \n"); + IPACMDBG_H("Firewall XML file is %s \n", firewall_config.firewall_config_file); + if (IPACM_SUCCESS == IPACM_read_firewall_xml(firewall_config.firewall_config_file, &firewall_config)) + { + IPACMDBG_H("QCMAP Firewall XML read OK \n"); + } + else + { + IPACMERR("QCMAP Firewall XML read failed, no that file, use default configuration \n"); + } } else { - IPACMERR("QCMAP Firewall XML read failed, no that file, use default configuration \n"); + IPACMERR("No firewall xml mentioned \n"); + return IPACM_FAILURE; } /* add IPv6 frag rule when firewall is enabled*/ diff --git a/data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp b/data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp index 464e40d..00754a1 100644 --- a/data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp +++ b/data-ipa-cfg-mgr/ipacm/src/IPACM_Wlan.cpp @@ -54,8 +54,6 @@ 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; IPACM_Wlan::IPACM_Wlan(int iface_index) : IPACM_Lan(iface_index) @@ -107,61 +105,13 @@ IPACM_Wlan::IPACM_Wlan(int iface_index) : IPACM_Lan(iface_index) IPACM_Wlan::num_wlan_ap_iface++; IPACMDBG_H("Now the number of wlan AP iface is %d\n", IPACM_Wlan::num_wlan_ap_iface); - is_guest_ap = false; + m_is_guest_ap = false; if (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].wlan_mode == INTERNET) { - is_guest_ap = true; + m_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); - - 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) - { - if(ipa_if_cate == 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(); - } - } - } - } - } -#endif + IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, m_is_guest_ap); #ifdef FEATURE_IPA_ANDROID /* set the IPA-client pipe enum */ @@ -207,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 */ - ipa_if_cate = 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); @@ -334,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) @@ -406,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) @@ -513,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,31 +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; inum_of_attribs; i++) { if(data->attribs[i].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR) { - if (is_guest_ap == false) - { - 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(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_CLIENT_ADD_EVENT); - eth_bridge_add_client(data->attribs[i].u.mac_addr); - } + 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); } @@ -612,24 +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 - if (is_guest_ap == false) - { - if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true) - { - eth_bridge_del_wlan_client_rt_rule(data->mac_addr, SRC_WLAN); - } - 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_CLIENT_DEL_EVENT); - eth_bridge_del_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); } } @@ -642,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); } } @@ -657,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) && @@ -702,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) @@ -728,142 +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_CLIENT_ADD_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_CLIENT_ADD_EVENT event.\n"); - ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param; - if(is_guest_ap == true) - { - IPACMDBG_H("%s iface is wlan guest ap, return.\n", dev_name); - return; - } - - if(mac != NULL) - { - if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) - { - eth_bridge_add_client_flt_rule(mac->mac_addr, IPA_IP_v4, mac->ipa_if_cate); - } - if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) - { - eth_bridge_add_client_flt_rule(mac->mac_addr, IPA_IP_v6, mac->ipa_if_cate); - } - } - else - { - IPACMERR("Event MAC is empty.\n"); - } - } - break; - - case IPA_ETH_BRIDGE_CLIENT_DEL_EVENT: - { - IPACMDBG_H("Received IPA_ETH_BRIDGE_CLIENT_DEL_EVENT event.\n"); - ipacm_event_data_mac* mac = (ipacm_event_data_mac*)param; - if(is_guest_ap == true) - { - IPACMDBG_H("%s iface is wlan guest ap, return.\n", dev_name); - return; - } - if(mac != NULL) - { - if(eth_bridge_del_client_flt_rule(mac->mac_addr) == IPACM_FAILURE) - { - IPACMDBG_H("Failed to delete 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(is_guest_ap == true) - { - IPACMDBG_H("%s iface is wlan guest ap, return.\n", dev_name); - 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; iif_cat != LAN_IF && cat->if_cat != ODU_IF) - { - IPACMDBG_H("The event was not sent by LAN interface, ignore.\n"); - return; - } - if(is_guest_ap == true) - { - IPACMDBG_H("%s iface is wlan guest ap, return.\n", dev_name); - 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; iiface_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) { @@ -915,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(); } @@ -958,72 +744,6 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) return; } -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; -} - /* handle wifi client initial,copy all partial headers (tx property) */ int IPACM_Wlan::handle_wlan_client_init_ex(ipacm_event_data_wlan_ex *data) { @@ -1321,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", @@ -1380,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]; @@ -1406,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*/ } } } @@ -1811,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) @@ -1846,12 +1567,6 @@ int IPACM_Wlan::handle_down_evt() } IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE); -#ifdef FEATURE_ETH_BRIDGE_LE - if(is_guest_ap == false) //delete eth bridge flt rules only when it is not guest ap - { - eth_bridge_remove_all_client_flt_rule(IPA_IP_v4); - } -#endif if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES) == false) { IPACMERR("Error Deleting Filtering Rule, aborting...\n"); @@ -1896,13 +1611,6 @@ int IPACM_Wlan::handle_down_evt() } IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE); -#ifdef FEATURE_ETH_BRIDGE_LE - if(is_guest_ap == false) //delete eth bridge flt rules only when it is not guest ap - { - eth_bridge_remove_all_client_flt_rule(IPA_IP_v6); - } -#endif - if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES) == false) { IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n"); @@ -1958,17 +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 - if (is_guest_ap == false) - { - eth_bridge_del_wlan_client_rt_rule(get_client_memptr(wlan_client, i)->mac, SRC_WLAN); - eth_bridge_del_wlan_client_rt_rule(get_client_memptr(wlan_client, i)->mac, SRC_LAN); - eth_bridge_del_client(get_client_memptr(wlan_client, i)->mac); - eth_bridge_post_lan_client_event(get_client_memptr(wlan_client, i)->mac, IPA_ETH_BRIDGE_CLIENT_DEL_EVENT); - } -#endif /* First reset nat rules and then route rules */ if(get_client_memptr(wlan_client, i)->ipv4_set == true) { @@ -1992,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) @@ -2064,40 +1762,7 @@ int IPACM_Wlan::handle_down_evt() { 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(); @@ -2121,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) { @@ -2141,1052 +1800,69 @@ 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) +void IPACM_Wlan::handle_SCC_MCC_switch(ipa_ip_type iptype) { - int client_index; - client_index = get_wlan_client_index(mac_addr); - if (client_index == IPACM_INVALID_INDEX) + struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL; + struct ipa_rt_rule_mdfy *rt_rule_entry; + uint32_t tx_index; + int wlan_index, v6_num; + const int NUM = 1; + int num_wifi_client_tmp = IPACM_Wlan::num_wifi_client; + bool isAdded = false; + + if (tx_prop == NULL) { - IPACMDBG_H("wlan client not attached\n"); - return IPACM_SUCCESS; + IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); + return; } - 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 (rt_rule == NULL) { - 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; - } + rt_rule = (struct ipa_ioc_mdfy_rt_rule *) + calloc(1, sizeof(struct ipa_ioc_mdfy_rt_rule) + + NUM * sizeof(struct ipa_rt_rule_mdfy)); - lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client)); - if(lan_client == NULL) + if (rt_rule == NULL) { - IPACMERR("Unable to allocate memory.\n"); - return IPACM_FAILURE; + PERROR("Error Locate ipa_ioc_mdfy_rt_rule memory...\n"); + return; } - 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); + rt_rule->commit = 0; + rt_rule->num_rules = NUM; + rt_rule->ip = iptype; } + rt_rule_entry = &rt_rule->rules[0]; - if((get_client_memptr(wlan_client, client_index)->ipv6_set > 0) - && (iptype == IPA_IP_v6)) /* handle v6 case: may be multiple v6 addr */ + /* modify ipv4 routing rule */ + if (iptype == IPA_IP_v4) { - if(ip_type != IPA_IP_v6 && ip_type != IPA_IP_MAX) + for (wlan_index = 0; wlan_index < num_wifi_client_tmp; wlan_index++) { - IPACMERR("Client has IPv6 addr but iface does not have IPv6 up.\n"); - return IPACM_FAILURE; - } - int i; + IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", + wlan_index, iptype, + get_client_memptr(wlan_client, wlan_index)->ipv4_set, + get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4); - for(i=0; iipv6_set; i++) - { - lan_client = (ipacm_event_lan_client*)malloc(sizeof(ipacm_event_lan_client)); - if(lan_client == NULL) + if (get_client_memptr(wlan_client, wlan_index)->power_save_set == true || + get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 == false) { - IPACMERR("Unable to allocate memory.\n"); - return IPACM_FAILURE; + IPACMDBG_H("client %d route rules not set\n", wlan_index); + continue; } - 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; + IPACMDBG_H("Modify client %d route rule\n", wlan_index); + for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) + { + if (iptype != tx_prop->tx[tx_index].ip) + { + IPACMDBG_H("Tx:%d, ip-type: %d ip-type not matching: %d ignore\n", + tx_index, tx_prop->tx[tx_index].ip, iptype); + continue; + } - 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; inum_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; jmac, 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; jhdr[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; inum_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; jmac, 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; jhdr[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; -} - -/* 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)<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)<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)<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; irules[i].rule_hdl; - } - } - else - { - for(i=0; irules[i].rule_hdl; - } - } - } - -fail: - free(pFilteringTable); - return; -} - -int IPACM_Wlan::eth_bridge_install_cache_client_flt_rule(ipa_ip_type iptype) -{ - int i; - - if(is_guest_ap == true) - { - IPACMDBG_H("%s iface is wlan guest ap, return.\n", dev_name); - return IPACM_SUCCESS; - } - - IPACMDBG_H("There are %d clients cached.\n", IPACM_Lan::eth_bridge_num_client); - for(i=0; imac, 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; imac, 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; imac, 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; imac, 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; -#ifdef FEATURE_IPA_V3 - rt_rule.rule.hashable = true; -#endif - 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; inum_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; irt_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; irt_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; imac, 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; imac, 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; irt_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; imac, 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; imac, 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; irt_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; icommit = 0; - rt_rule->num_rules = NUM; - rt_rule->ip = iptype; - } - rt_rule_entry = &rt_rule->rules[0]; - - /* modify ipv4 routing rule */ - if (iptype == IPA_IP_v4) - { - for (wlan_index = 0; wlan_index < num_wifi_client_tmp; wlan_index++) - { - IPACMDBG_H("wlan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", - wlan_index, iptype, - get_client_memptr(wlan_client, wlan_index)->ipv4_set, - get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4); - - if (get_client_memptr(wlan_client, wlan_index)->power_save_set == true || - get_client_memptr(wlan_client, wlan_index)->route_rule_set_v4 == false) - { - IPACMDBG_H("client %d route rules not set\n", wlan_index); - continue; - } - - IPACMDBG_H("Modify client %d route rule\n", wlan_index); - for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) - { - if (iptype != tx_prop->tx[tx_index].ip) - { - IPACMDBG_H("Tx:%d, ip-type: %d ip-type not matching: %d ignore\n", - tx_index, tx_prop->tx[tx_index].ip, iptype); - continue; - } - - IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", wlan_index, - get_client_memptr(wlan_client, wlan_index)->v4_addr); + IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", wlan_index, + get_client_memptr(wlan_client, wlan_index)->v4_addr); IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n", wlan_index, @@ -3331,333 +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::eth_bridge_num_client; i++) - { - if (IPACM_Lan::eth_bridge_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_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_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) +void IPACM_Wlan::eth_bridge_handle_wlan_mode_switch() { - 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; - } + int i; - 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; - } - } - } + /* ====== post events to mimic WLAN interface goes down/up when AP mode is changing ====== */ - 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)); + /* first post IFACE_DOWN event */ + eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL); - if (rt_rule == NULL) + /* then post IFACE_UP event */ + if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) { - IPACMERR("Unable to allocate memory for modify rt rule\n"); - return IPACM_FAILURE; + eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v4, NULL); } - 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(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) { - 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++; - } + eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v6, NULL); } - if (rt_rule->num_rules > 0) + /* at last post CLIENT_ADD event */ + for(i = 0; i < num_wifi_client; i++) { - 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"); + eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, + get_client_memptr(wlan_client, i)->mac); } - if (rt_rule) - { - free(rt_rule); - } - return IPACM_SUCCESS; + return; } -void IPACM_Wlan::eth_bridge_handle_wlan_mode_switch() +bool IPACM_Wlan::is_guest_ap() { - int i; - uint8_t mac[IPA_MAC_ADDR_SIZE]; - - if(is_guest_ap == true) //switch from FULL to INTERNET mode - { - /* first delete all eth bridge flt rules */ - if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) - { - eth_bridge_remove_all_client_flt_rule(IPA_IP_v4); - } - if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) - { - eth_bridge_remove_all_client_flt_rule(IPA_IP_v6); - } - - for(i=0; imac, sizeof(mac)); - - /* remove client info from the client array */ - eth_bridge_del_client(mac); - - /* delete all eth bridge rt rules */ - if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true) - { - eth_bridge_del_wlan_client_rt_rule(mac, SRC_LAN); - } - if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true) - { - eth_bridge_del_wlan_client_rt_rule(mac, SRC_WLAN); - } - - /* post client delete event */ - eth_bridge_post_lan_client_event(mac, IPA_ETH_BRIDGE_CLIENT_DEL_EVENT); - } - } - else //switch from INTERNET to FULL mode - { - for(i=0; imac, sizeof(mac)); - - /* add client info from the client array */ - eth_bridge_add_client(mac); - - /* add client rt rules */ - if(IPACM_Lan::lan_to_wlan_hdr_proc_ctx.valid == true) - { - eth_bridge_add_wlan_client_rt_rule(mac, SRC_LAN, IPA_IP_v4); - eth_bridge_add_wlan_client_rt_rule(mac, SRC_LAN, IPA_IP_v6); - } - if(IPACM_Lan::wlan_to_wlan_hdr_proc_ctx.valid == true) - { - eth_bridge_add_wlan_client_rt_rule(mac, SRC_WLAN, IPA_IP_v4); - eth_bridge_add_wlan_client_rt_rule(mac, SRC_WLAN, IPA_IP_v6); - } - - /* post client add event */ - eth_bridge_post_lan_client_event(mac, IPA_ETH_BRIDGE_CLIENT_ADD_EVENT); - } - - /* add client flt rules */ - IPACMDBG_H("ip_type: %d\n", ip_type); - if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) - { - eth_bridge_install_cache_client_flt_rule(IPA_IP_v4); - } - if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) - { - eth_bridge_install_cache_client_flt_rule(IPA_IP_v6); - } - } - 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 @@ VIRTUAL + + 0 + 192.168.225.0 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/src/.Android.mk.swp b/data-ipa-cfg-mgr/ipanat/src/.Android.mk.swp deleted file mode 100644 index 2f3a09f1ec68c31ee51cdd2e2beb6515e91b74e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmYc?2=nw+FxN9-00IF9hRxd}!W(ByXZGP@U?|Q=Oi2Za695^BImwmzc?483Fw}t! z)K5t*(@)OTH#7#ZGLuvF^HM8Hk}^y5Q%f>Zi}X_xOA>W63lepc)6#Ww(~Ib1CXGylA?mJP$-)GD0egjMnhmU a1V%$(Gz3ONU^E0qLtr!nMnhmYhX4SxF(}^v diff --git a/data-ipa-cfg-mgr/ipanat/src/Android.mk b/data-ipa-cfg-mgr/ipanat/src/Android.mk index 67d01df..ea14920 100644 --- a/data-ipa-cfg-mgr/ipanat/src/Android.mk +++ b/data-ipa-cfg-mgr/ipanat/src/Android.mk @@ -16,12 +16,13 @@ LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr LOCAL_SRC_FILES := ipa_nat_drv.c \ ipa_nat_drvi.c +LOCAL_CFLAGS := -DDEBUG LOCAL_MODULE := libipanat LOCAL_MODULE_TAGS := optional LOCAL_PRELINK_MODULE := false -LOCAL_CLANG := true + include $(BUILD_SHARED_LIBRARY) endif # $(TARGET_ARCH) endif -endif +endif \ No newline at end of file