summaryrefslogtreecommitdiff
path: root/ipacm
diff options
context:
space:
mode:
authorChengYou Ho <chengyouho@google.com>2019-12-23 16:59:59 +0800
committerWilson Sung <wilsonsung@google.com>2020-02-03 13:33:21 +0800
commitdc455fa6e93bcb5a252747bed3941759ce247c38 (patch)
treea889a4367664513ff539f6556fe7aa9857ec2079 /ipacm
parent6bafc1497f181945305cba34f8b2f2ddac35b650 (diff)
parent3ba31701681587a2aba85ad4fed3b0d48e265fd0 (diff)
downloadipacfg-mgr-dc455fa6e93bcb5a252747bed3941759ce247c38.tar.gz
Merge remote-tracking branch 'goog/qcom/release/LA.UM.8.1.C9.09.00.00.518.343'
Bug: 146759211 Change-Id: I7e90b1f60353762b17bf0d1f5583767644cea12f
Diffstat (limited to 'ipacm')
-rw-r--r--ipacm/inc/IPACM_Config.h5
-rw-r--r--ipacm/inc/IPACM_ConntrackListener.h4
-rw-r--r--ipacm/inc/IPACM_Conntrack_NATApp.h12
-rw-r--r--ipacm/inc/IPACM_Defs.h21
-rw-r--r--ipacm/inc/IPACM_Filtering.h12
-rw-r--r--ipacm/inc/IPACM_Iface.h10
-rw-r--r--ipacm/inc/IPACM_Lan.h23
-rw-r--r--ipacm/inc/IPACM_OffloadManager.h4
-rw-r--r--ipacm/inc/IPACM_Routing.h4
-rw-r--r--ipacm/inc/IPACM_Wan.h91
-rw-r--r--ipacm/inc/IPACM_Wlan.h20
-rw-r--r--ipacm/src/Android.mk20
-rw-r--r--ipacm/src/IPACM_Config.cpp4
-rw-r--r--ipacm/src/IPACM_ConntrackListener.cpp14
-rw-r--r--ipacm/src/IPACM_Conntrack_NATApp.cpp298
-rw-r--r--ipacm/src/IPACM_Filtering.cpp459
-rw-r--r--ipacm/src/IPACM_Iface.cpp296
-rw-r--r--ipacm/src/IPACM_IfaceManager.cpp1
-rw-r--r--ipacm/src/IPACM_Lan.cpp495
-rw-r--r--ipacm/src/IPACM_Main.cpp99
-rw-r--r--ipacm/src/IPACM_OffloadManager.cpp169
-rw-r--r--ipacm/src/IPACM_Routing.cpp109
-rw-r--r--ipacm/src/IPACM_Wan.cpp2405
-rw-r--r--ipacm/src/IPACM_Wlan.cpp273
-rw-r--r--ipacm/src/IPACM_Xml.cpp13
25 files changed, 4093 insertions, 768 deletions
diff --git a/ipacm/inc/IPACM_Config.h b/ipacm/inc/IPACM_Config.h
index af1b616..9230f7d 100644
--- a/ipacm/inc/IPACM_Config.h
+++ b/ipacm/inc/IPACM_Config.h
@@ -147,6 +147,11 @@ public:
bool isMCC_Mode;
+ /* IPA_HW_FNR_STATS */
+ bool hw_fnr_stats_support;
+ int hw_counter_offset;
+ int sw_counter_offset;
+
/* To return the instance */
static IPACM_Config* GetInstance();
diff --git a/ipacm/inc/IPACM_ConntrackListener.h b/ipacm/inc/IPACM_ConntrackListener.h
index d965cf7..24a2c72 100644
--- a/ipacm/inc/IPACM_ConntrackListener.h
+++ b/ipacm/inc/IPACM_ConntrackListener.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -103,7 +103,7 @@ private:
public:
char wan_ifname[IPA_IFACE_NAME_LEN];
uint32_t wan_ipaddr;
- bool isStaMode;
+ ipacm_wan_iface_type backhaul_mode;
IPACM_ConntrackListener();
void event_callback(ipa_cm_event_id, void *data);
inline bool isWanUp()
diff --git a/ipacm/inc/IPACM_Conntrack_NATApp.h b/ipacm/inc/IPACM_Conntrack_NATApp.h
index c3749e1..b362907 100644
--- a/ipacm/inc/IPACM_Conntrack_NATApp.h
+++ b/ipacm/inc/IPACM_Conntrack_NATApp.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -65,6 +65,8 @@ typedef struct _nat_table_entry
bool enabled;
uint32_t rule_hdl;
+ /* used for pcie-modem */
+ uint32_t rule_id;
}nat_table_entry;
#define CHK_TBL_HDL() if(nat_table_hdl == 0){ return -1; }
@@ -80,6 +82,8 @@ private:
uint32_t pub_ip_addr;
uint32_t pub_ip_addr_pre;
uint32_t nat_table_hdl;
+ /* used for pcie-modem */
+ uint8_t pub_mux_id;
int curCnt, max_entries;
@@ -94,7 +98,10 @@ private:
struct nf_conntrack *ct;
struct nfct_handle *ct_hdl;
+ int m_fd_ipa;
+
NatApp();
+ ~NatApp();
int Init();
void UpdateCTUdpTs(nat_table_entry *, uint32_t);
@@ -114,6 +121,9 @@ public:
int AddEntry(const nat_table_entry *);
int DeleteEntry(const nat_table_entry *);
+ int AddConnection(const nat_table_entry *);
+ int DelConnection(const uint32_t);
+
void UpdateUDPTimeStamp();
int UpdatePwrSaveIf(uint32_t);
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index d2186b6..65d5ce4 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -122,6 +122,7 @@ extern "C"
#define IPA_MAX_NUM_ETH_CLIENTS 15
#define IPA_MAX_NUM_AMPDU_RULE 15
#define IPA_MAC_ADDR_SIZE 6
+#define IPA_MAX_NUM_SW_PDNS 15
/*===========================================================================
GLOBAL DEFINITIONS AND DECLARATIONS
@@ -186,7 +187,8 @@ typedef enum
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_SSR_NOTICE, /* NULL*/
+ IPA_SSR_NOTICE, /* NULL*/
+ IPA_COALESCE_NOTICE, /* NULL*/
#ifdef FEATURE_L2TP
IPA_ADD_VLAN_IFACE, /* ipa_ioc_vlan_iface_info */
IPA_DEL_VLAN_IFACE, /* ipa_ioc_vlan_iface_info */
@@ -352,31 +354,34 @@ typedef struct
struct ipa_wlan_hdr_attrib_val attribs[0];
} ipacm_event_data_wlan_ex;
+typedef enum
+{
+ Q6_WAN = 0,
+ WLAN_WAN,
+ ECM_WAN,
+ Q6_MHI_WAN
+} ipacm_wan_iface_type;
+
typedef struct _ipacm_event_iface_up
{
+ ipacm_wan_iface_type backhaul_type;
char ifname[IPA_IFACE_NAME_LEN];
uint32_t ipv4_addr;
uint32_t addr_mask;
uint32_t ipv6_prefix[2];
- bool is_sta;
uint8_t xlat_mux_id;
uint8_t mux_id;
}ipacm_event_iface_up;
typedef struct _ipacm_event_iface_up_tether
{
+ ipacm_wan_iface_type backhaul_type;
uint32_t if_index_tether;
uint32_t ipv6_prefix[2];
bool is_sta;
uint8_t xlat_mux_id;
}ipacm_event_iface_up_tehter;
-typedef enum
-{
- Q6_WAN = 0,
- WLAN_WAN,
- ECM_WAN
-} ipacm_wan_iface_type;
typedef struct _ipacm_ifacemgr_data
{
diff --git a/ipacm/inc/IPACM_Filtering.h b/ipacm/inc/IPACM_Filtering.h
index 9bb8247..428c21a 100644
--- a/ipacm/inc/IPACM_Filtering.h
+++ b/ipacm/inc/IPACM_Filtering.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -47,6 +47,8 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <IPACM_Defs.h>
#include <linux/rmnet_ipa_fd_ioctl.h>
+#define IPA_PCIE_MODEM_RULE_ID_START 69
+
class IPACM_Filtering
{
public:
@@ -54,6 +56,10 @@ public:
~IPACM_Filtering();
bool AddFilteringRule(struct ipa_ioc_add_flt_rule const *ruleTable);
bool AddFilteringRuleAfter(struct ipa_ioc_add_flt_rule_after const *ruleTable);
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ bool AddFilteringRule_hw_index(struct ipa_ioc_add_flt_rule *ruleTable, int hw_counter_index);
+ bool AddFilteringRuleAfter_hw_index(struct ipa_ioc_add_flt_rule_after *ruleTable, int hw_counter_index);
+#endif //IPA_IOCTL_SET_FNR_COUNTER_INFO
bool DeleteFilteringRule(struct ipa_ioc_del_flt_rule *ruleTable);
bool Commit(enum ipa_ip_type ip);
bool Reset(enum ipa_ip_type ip);
@@ -63,6 +69,8 @@ public:
uint8_t num_rules);
bool AddWanDLFilteringRule(struct ipa_ioc_add_flt_rule const *rule_table_v4, struct ipa_ioc_add_flt_rule const * rule_table_v6, uint8_t mux_id);
+ bool AddOffloadFilteringRule(struct ipa_ioc_add_flt_rule *flt_rule_tbl, uint8_t mux_id, uint8_t default_path);
+ bool DelOffloadFilteringRule(struct ipa_ioc_del_flt_rule const *flt_rule_tbl);
bool SendFilteringRuleIndex(struct ipa_fltr_installed_notif_req_msg_v01* table);
bool ModifyFilteringRule(struct ipa_ioc_mdfy_flt_rule* ruleTable);
ipa_filter_action_enum_v01 GetQmiFilterAction(ipa_flt_action action);
@@ -70,6 +78,8 @@ public:
private:
static const char *DEVICE_NAME;
int fd; /* File descriptor of the IPA device node /dev/ipa */
+ int total_num_offload_rules;
+ int pcie_modem_rule_id;
};
#endif //IPACM_FILTERING_H
diff --git a/ipacm/inc/IPACM_Iface.h b/ipacm/inc/IPACM_Iface.h
index a562613..55d9e99 100644
--- a/ipacm/inc/IPACM_Iface.h
+++ b/ipacm/inc/IPACM_Iface.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -139,13 +139,17 @@ public:
static IPACM_Filtering m_filtering;
static IPACM_Header m_header;
+ void change_to_network_order(ipa_ip_type iptype, ipa_rule_attrib* attrib);
+
/* software routing enable */
- virtual int handle_software_routing_enable(void);
+ virtual int handle_software_routing_enable(bool mhip);
/* software routing disable */
- virtual int handle_software_routing_disable(void);
+ virtual int handle_software_routing_disable(bool mhip);
void delete_iface(void);
+ bool is_global_ipv6_addr(uint32_t* ipv6_addr);
+
private:
static const char *DEVICE_NAME;
diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h
index 700dfbc..bf815c5 100644
--- a/ipacm/inc/IPACM_Lan.h
+++ b/ipacm/inc/IPACM_Lan.h
@@ -49,6 +49,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "IPACM_Filtering.h"
#include "IPACM_Config.h"
#include "IPACM_Conntrack_NATApp.h"
+#include "IPACM_Wan.h"
#define IPA_WAN_DEFAULT_FILTER_RULE_HANDLES 1
#define IPA_PRIV_SUBNET_FILTER_RULE_HANDLES 3
@@ -94,6 +95,8 @@ typedef struct _ipa_eth_client
int ipv6_set;
bool ipv4_header_set;
bool ipv6_header_set;
+ /* used for pcie-modem */
+ uint32_t v6_rt_rule_id[IPV6_NUM_ADDR];
eth_client_rt_hdl eth_rt_hdl[0]; /* depends on number of tx properties */
}ipa_eth_client;
@@ -121,10 +124,10 @@ public:
virtual int handle_wan_up_ex(ipacm_ext_prop* ext_prop, ipa_ip_type iptype, uint8_t xlat_mux_id);
/* delete filter rule for wan_down event*/
- virtual int handle_wan_down(bool is_sta_mode);
+ virtual int handle_wan_down(ipacm_wan_iface_type backhaul_mode);
/* delete filter rule for wan_down event*/
- virtual int handle_wan_down_v6(bool is_sta_mode);
+ virtual int handle_wan_down_v6(ipacm_wan_iface_type backhaul_mode);
/* configure private subnet filter rules*/
virtual int handle_private_subnet(ipa_ip_type iptype);
@@ -393,6 +396,18 @@ private:
{
for(num_v6 =0;num_v6 < get_client_memptr(eth_client, clt_indx)->route_rule_set_v6;num_v6++)
{
+ /* send client-v6 delete to pcie modem only with global ipv6 with tx_index = 1 one time*/
+ if(is_global_ipv6_addr(get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6]) && (IPACM_Wan::backhaul_mode == Q6_MHI_WAN)
+ && (get_client_memptr(eth_client, clt_indx)->v6_rt_rule_id[num_v6] > 0))
+ {
+ IPACMDBG_H("Delete client index %d ipv6 RT-rules for %d-st ipv6 for rule-id:%d\n", clt_indx,num_v6,
+ get_client_memptr(eth_client, clt_indx)->v6_rt_rule_id[num_v6]);
+ if (del_connection(clt_indx, num_v6))
+ {
+ IPACMERR("PCIE filter rule deletion failed! (%d-client) %d v6-entry\n",clt_indx, num_v6);
+ }
+ }
+
IPACMDBG_H("Delete client index %d ipv6 RT-rules for %d-st ipv6 for tx:%d\n", clt_indx,num_v6,tx_index);
rt_hdl = get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6];
if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false)
@@ -445,6 +460,10 @@ private:
/*handle reset usb-client rt-rules */
int handle_lan_client_reset_rt(ipa_ip_type iptype);
+
+ /* for pcie modem */
+ virtual int add_connection(int client_index, int v6_num);
+ virtual int del_connection(int client_index, int v6_num);
};
#endif /* IPACM_LAN_H */
diff --git a/ipacm/inc/IPACM_OffloadManager.h b/ipacm/inc/IPACM_OffloadManager.h
index 88a411b..8ac904f 100644
--- a/ipacm/inc/IPACM_OffloadManager.h
+++ b/ipacm/inc/IPACM_OffloadManager.h
@@ -86,7 +86,7 @@ public:
virtual RET getStats(const char * /* upstream */, bool /* reset */,
OffloadStatistics& /* ret */);
- static IPACM_OffloadManager *pInstance; //sky
+ static IPACM_OffloadManager *pInstance;
IpaEventListener *elrInstance;
@@ -96,6 +96,8 @@ public:
bool push_framework_event(const char * if_name, _ipacm_offload_prefix prefix);
+ static int num_offload_v4_tethered_iface;
+
private:
std::list<std::string> valid_ifaces;
diff --git a/ipacm/inc/IPACM_Routing.h b/ipacm/inc/IPACM_Routing.h
index b5ffabc..663076b 100644
--- a/ipacm/inc/IPACM_Routing.h
+++ b/ipacm/inc/IPACM_Routing.h
@@ -55,6 +55,10 @@ public:
~IPACM_Routing();
bool AddRoutingRule(struct ipa_ioc_add_rt_rule *ruleTable);
+
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ bool AddRoutingRule_hw_index(struct ipa_ioc_add_rt_rule *ruleTable, int hw_counter_index);
+#endif //IPA_IOCTL_SET_FNR_COUNTER_INFO
bool DeleteRoutingRule(struct ipa_ioc_del_rt_rule *ruleTable);
bool Commit(enum ipa_ip_type ip);
diff --git a/ipacm/inc/IPACM_Wan.h b/ipacm/inc/IPACM_Wan.h
index 1b917c6..684bfb7 100644
--- a/ipacm/inc/IPACM_Wan.h
+++ b/ipacm/inc/IPACM_Wan.h
@@ -89,6 +89,12 @@ typedef struct _ipa_wan_client
wan_client_rt_hdl wan_rt_hdl[0]; /* depends on number of tx properties */
}ipa_wan_client;
+typedef struct
+{
+ bool coalesce_tcp_enable;
+ bool coalesce_udp_enable;
+}ipacm_coalesce;
+
/* wan iface */
class IPACM_Wan : public IPACM_Iface
{
@@ -215,15 +221,48 @@ public:
return IPACM_SUCCESS;
}
#endif
+ static void coalesce_config(uint8_t qmap_id, bool tcp_enable, bool udp_enable)
+ {
+ if (qmap_id >= IPA_MAX_NUM_SW_PDNS)
+ {
+ IPACMERR("qmap_id (%d) beyond the Max range (%d), abort\n",
+ qmap_id, IPA_MAX_NUM_SW_PDNS);
+ return ;
+ }
+
+ IPACM_Wan::coalesce_enable_info[qmap_id].coalesce_tcp_enable = tcp_enable;
+ IPACM_Wan::coalesce_enable_info[qmap_id].coalesce_udp_enable = udp_enable;
+ IPACMDBG_H(" Updated qmap(%d) coalesce enable TCP:%d UDP:%d\n",
+ qmap_id,
+ IPACM_Wan::coalesce_enable_info[qmap_id].coalesce_tcp_enable,
+ IPACM_Wan::coalesce_enable_info[qmap_id].coalesce_udp_enable);
+ return ;
+ }
+
+ static void coalesce_config_reset()
+ {
+ int i;
+ /* reset coalesce settings on all modem interfaces */
+ for (i = 0; i < IPA_MAX_NUM_SW_PDNS; i++)
+ IPACM_Wan::coalesce_config(i, false, false);
+ return ;
+ }
static uint32_t getWANIP()
{
return curr_wan_ip;
}
- static bool getXlat_Mux_Id()
+ static int getXlat_Mux_Id()
{
- return xlat_mux_id;
+ if (is_xlat)
+ {
+ IPACMDBG_H("xlat_mux_id: %d\n", xlat_mux_id);
+ return xlat_mux_id;
+ } else {
+ IPACMDBG_H("no xlat return invalid mux-id: 0\n");
+ return 0;
+ }
}
static void clearExtProp()
@@ -243,12 +282,13 @@ public:
static int num_v6_flt_rule;
ipacm_wan_iface_type m_is_sta_mode;
- static bool backhaul_is_sta_mode;
+ static ipacm_wan_iface_type backhaul_mode;
static bool is_ext_prop_set;
static uint32_t backhaul_ipv6_prefix[2];
static bool embms_is_on;
static bool backhaul_is_wan_bridge;
+ static bool is_xlat;
static bool isWan_Bridge_Mode()
{
@@ -260,8 +300,16 @@ public:
static int ipa_if_num_tether_v4[IPA_MAX_IFACE_ENTRIES];
static uint32_t ipa_if_num_tether_v6_total;
static int ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES];
+
+ static bool isXlat()
+ {
+ return is_xlat;
+ }
#endif
+ /* indicate coalesce support on tcp or udp*/
+ static ipacm_coalesce coalesce_enable_info[IPA_MAX_NUM_SW_PDNS];
+
private:
bool is_ipv6_frag_firewall_flt_rule_installed;
@@ -292,6 +340,8 @@ private:
bool header_partial_default_wan_v6;
uint8_t ext_router_mac_addr[IPA_MAC_ADDR_SIZE];
uint8_t netdev_mac[IPA_MAC_ADDR_SIZE];
+ /* create additional set of v4 Coalesce RT-rules: tcp udp */
+ uint32_t dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+ 2*MAX_DEFAULT_v6_ROUTE_RULES];
static int num_ipv4_modem_pdn;
@@ -314,13 +364,25 @@ private:
int header_name_count;
uint32_t num_wan_client;
uint8_t invalid_mac[IPA_MAC_ADDR_SIZE];
- bool is_xlat;
+ bool is_xlat_local;
/* update network stats for CNE */
int ipa_network_stats_fd;
uint32_t hdr_hdl_dummy_v6;
uint32_t hdr_proc_hdl_dummy_v6;
+ /* handle for UDP mhi frag rule */
+ uint32_t mhi_dl_v4_frag_hdl;
+
+ /* handle for icmpv6 exception rule */
+ uint32_t icmpv6_exception_hdl;
+
+ /* handle for TCP FIN rule */
+ uint32_t tcp_fin_hdl;
+
+ /* handle for TCP RST rule */
+ uint32_t tcp_rst_hdl;
+
inline ipa_wan_client* get_client_memptr(ipa_wan_client *param, int cnt)
{
char *ret = ((char *)param) + (wan_client_len * cnt);
@@ -506,6 +568,9 @@ private:
/* handle new_address event */
int handle_addr_evt(ipacm_event_data_addr *data);
+ /* handle new_address event for q6_mhi */
+ int handle_addr_evt_mhi_q6(ipacm_event_data_addr *data);
+
/* wan default route/filter rule configuration */
int handle_route_add_evt(ipa_ip_type iptype);
@@ -562,10 +627,6 @@ private:
int install_wan_filtering_rule(bool is_sw_routing);
- void change_to_network_order(ipa_ip_type iptype, ipa_rule_attrib* attrib);
-
- bool is_global_ipv6_addr(uint32_t* ipv6_addr);
-
void handle_wlan_SCC_MCC_switch(bool, ipa_ip_type);
void handle_wan_client_SCC_MCC_switch(bool, ipa_ip_type);
@@ -578,6 +639,20 @@ private:
/* construct dummy ethernet header */
int add_dummy_rx_hdr();
+
+ int handle_coalesce_evt();
+
+ int add_offload_frag_rule();
+
+ int delete_offload_frag_rule();
+
+ int add_icmpv6_exception_rule();
+
+ int delete_icmpv6_exception_rule();
+
+ int add_tcp_fin_rst_exception_rule();
+
+ int delete_tcp_fin_rst_exception_rule();
};
#endif /* IPACM_WAN_H */
diff --git a/ipacm/inc/IPACM_Wlan.h b/ipacm/inc/IPACM_Wlan.h
index f3c6d65..9c828ee 100644
--- a/ipacm/inc/IPACM_Wlan.h
+++ b/ipacm/inc/IPACM_Wlan.h
@@ -54,6 +54,7 @@ typedef struct _wlan_client_rt_hdl
uint32_t wifi_rt_rule_hdl_v4;
uint32_t wifi_rt_rule_hdl_v6[IPV6_NUM_ADDR];
uint32_t wifi_rt_rule_hdl_v6_wan[IPV6_NUM_ADDR];
+
}wlan_client_rt_hdl;
typedef struct _ipa_wlan_client
@@ -72,6 +73,8 @@ typedef struct _ipa_wlan_client
bool ipv6_header_set;
bool power_save_set;
enum ipa_client_type wigig_ipa_client;
+ /* used for pcie-modem */
+ uint32_t v6_rt_rule_id[IPV6_NUM_ADDR];
wlan_client_rt_hdl wifi_rt_hdl[0]; /* depends on number of tx properties */
}ipa_wlan_client;
@@ -185,6 +188,18 @@ private:
{
for(num_v6 =0;num_v6 < get_client_memptr(wlan_client, clt_indx)->route_rule_set_v6;num_v6++)
{
+ /* send client-v6 delete to pcie modem only with global ipv6 with tx_index = 0 one time*/
+ if(is_global_ipv6_addr(get_client_memptr(wlan_client, clt_indx)->v6_addr[num_v6]) && (IPACM_Wan::backhaul_mode == Q6_MHI_WAN)
+ && (get_client_memptr(wlan_client, clt_indx)->v6_rt_rule_id[num_v6] > 0))
+ {
+ IPACMDBG_H("Delete client index %d ipv6 RT-rules for %d-st ipv6 for rule-id:%d\n", clt_indx,num_v6,
+ get_client_memptr(wlan_client, clt_indx)->v6_rt_rule_id[num_v6]);
+ if (del_connection(clt_indx, num_v6))
+ {
+ IPACMERR("PCIE filter rule deletion failed! (%d-client) %d v6-entry\n",clt_indx, num_v6);
+ }
+ }
+
IPACMDBG_H("Delete client index %d ipv6 Qos rules for %d-st ipv6 for tx:%d\n", clt_indx,num_v6,tx_index);
rt_hdl = get_client_memptr(wlan_client, clt_indx)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6[num_v6];
if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false)
@@ -237,6 +252,11 @@ private:
void handle_SCC_MCC_switch(ipa_ip_type);
+ /* for pcie modem */
+ int add_connection(int client_index, int v6_num);
+
+ int del_connection(int client_index, int v6_num);
+
#ifdef FEATURE_IPACM_RESTART
/*query wlan-clients */
int ipa_query_wlan_client();
diff --git a/ipacm/src/Android.mk b/ipacm/src/Android.mk
index 28c36fc..634308a 100644
--- a/ipacm/src/Android.mk
+++ b/ipacm/src/Android.mk
@@ -1,6 +1,18 @@
+TARGET_DISABLE_IPACM := false
+
+ifeq ($(TARGET_USES_QMAA),true)
+ifneq ($(TARGET_USES_QMAA_OVERRIDE_DATA),true)
+ TARGET_DISABLE_IPACM := true
+endif #TARGET_USES_QMAA_OVERRIDE_DATA
+endif #TARGET_USES_QMAA
+
+
+ifneq ($(TARGET_DISABLE_IPACM),true)
+ifneq ($(TARGET_HAS_LOW_RAM),true)
BOARD_PLATFORM_LIST := msm8909
BOARD_PLATFORM_LIST += msm8916
BOARD_PLATFORM_LIST += msm8917
+BOARD_PLATFORM_LIST += qm215
BOARD_IPAv3_LIST := msm8998
BOARD_IPAv3_LIST += sdm845
BOARD_IPAv3_LIST += sdm710
@@ -10,6 +22,9 @@ BOARD_IPAv3_LIST += $(MSMSTEPPE)
BOARD_IPAv3_LIST += $(TRINKET)
BOARD_IPAv3_LIST += lito
BOARD_IPAv3_LIST += atoll
+BOARD_IPAv3_LIST += bengal
+BOARD_ETH_BRIDGE_LIST := msmnile
+BOARD_ETH_BRIDGE_LIST += kona
ifneq ($(call is-board-platform-in-list,$(BOARD_PLATFORM_LIST)),true)
ifneq (,$(filter $(QCOM_BOARD_PLATFORMS),$(TARGET_BOARD_PLATFORM)))
@@ -27,7 +42,10 @@ LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_CFLAGS := -DFEATURE_IPA_ANDROID
LOCAL_CFLAGS += -DFEATURE_IPACM_RESTART
+
+ifeq ($(call is-board-platform-in-list,$(BOARD_ETH_BRIDGE_LIST)),true)
LOCAL_CFLAGS += -DFEATURE_ETH_BRIDGE_LE
+endif
LOCAL_CFLAGS += -DFEATURE_IPACM_HAL -Wall -Werror -Wno-error=macro-redefined -Wno-enum-compare
ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
@@ -121,3 +139,5 @@ include $(BUILD_PREBUILT)
endif # $(TARGET_ARCH)
endif
endif
+endif
+endif \ No newline at end of file
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index bfacd7c..781f1cb 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -143,6 +143,10 @@ IPACM_Config::IPACM_Config()
ipa_bridge_enable = false;
isMCC_Mode = false;
ipa_max_valid_rm_entry = 0;
+ /* IPA_HW_FNR_STATS */
+ hw_fnr_stats_support = false;
+ hw_counter_offset = 0;
+ sw_counter_offset = 0;
memset(&rt_tbl_default_v4, 0, sizeof(rt_tbl_default_v4));
memset(&rt_tbl_lan_v4, 0, sizeof(rt_tbl_lan_v4));
diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp
index d6289e3..e006393 100644
--- a/ipacm/src/IPACM_ConntrackListener.cpp
+++ b/ipacm/src/IPACM_ConntrackListener.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -230,7 +230,7 @@ void IPACM_ConntrackListener::HandleNonNatIPAddr(
bool NatIface = false;
int cnt, ret;
- if (isStaMode)
+ if (backhaul_mode != Q6_WAN)
{
IPACMDBG("In STA mode, don't add dummy rules for non nat ifaces\n");
return;
@@ -368,8 +368,8 @@ void IPACM_ConntrackListener::TriggerWANUp(void *in_param)
}
WanUp = true;
- isStaMode = wanup_data->is_sta;
- IPACMDBG("isStaMode: %d\n", isStaMode);
+ backhaul_mode = wanup_data->backhaul_type;
+ IPACMDBG("backhaul_mode: %d\n", backhaul_mode);
wan_ipaddr = wanup_data->ipv4_addr;
memcpy(wan_ifname, wanup_data->ifname, sizeof(wan_ifname));
@@ -730,7 +730,7 @@ bool IPACM_ConntrackListener::AddIface(
}
}
- if (!isStaMode)
+ if (backhaul_mode == Q6_WAN)
{
/* check whether non nat iface or not, on Non Nat iface
add dummy rule by copying public ip to private ip */
@@ -999,7 +999,7 @@ void IPACM_ConntrackListener::CheckSTAClient(
/* Check whether target is in STA client list or not
if not ignore the connection */
- if(!isStaMode || (StaClntCnt == 0))
+ if((backhaul_mode == Q6_WAN) || (StaClntCnt == 0))
{
return;
}
@@ -1114,7 +1114,7 @@ void IPACM_ConntrackListener::ProcessTCPorUDPMsg(
}
else
{
- if (isStaMode)
+ if (backhaul_mode != Q6_WAN)
{
IPACMDBG("In STA mode, ignore connections destinated to STA interface\n");
goto IGNORE;
diff --git a/ipacm/src/IPACM_Conntrack_NATApp.cpp b/ipacm/src/IPACM_Conntrack_NATApp.cpp
index 4004597..c1f47e1 100644
--- a/ipacm/src/IPACM_Conntrack_NATApp.cpp
+++ b/ipacm/src/IPACM_Conntrack_NATApp.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -28,6 +28,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "IPACM_Conntrack_NATApp.h"
#include "IPACM_ConntrackClient.h"
+#include "IPACM_ConntrackListener.h"
#ifdef FEATURE_IPACM_HAL
#include "IPACM_OffloadManager.h"
#endif
@@ -47,6 +48,7 @@ NatApp::NatApp()
nat_table_hdl = 0;
pub_ip_addr = 0;
+ pub_mux_id = 0;
curCnt = 0;
@@ -57,6 +59,18 @@ NatApp::NatApp()
ct_hdl = NULL;
memset(temp, 0, sizeof(temp));
+ m_fd_ipa = open(IPA_DEVICE_NAME, O_RDWR);
+ if(m_fd_ipa < 0)
+ {
+ IPACMERR("Failed to open %s\n",IPA_DEVICE_NAME);
+ }
+}
+
+NatApp::~NatApp()
+{
+ if (m_fd_ipa) {
+ close(m_fd_ipa);
+ }
}
int NatApp::Init(void)
@@ -205,6 +219,22 @@ int NatApp::AddTable(uint32_t pub_ip, uint8_t mux_id)
continue;
}
cache[cnt].enabled = true;
+ /* send connections info to pcie modem only with DL direction */
+ if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP))
+ {
+ ret = AddConnection(&cache[cnt]);
+ if(ret > 0)
+ {
+ /* save the rule id for deletion */
+ cache[cnt].rule_id = ret;
+ IPACMDBG_H("rule-id(%d)\n", cache[cnt].rule_id);
+ }
+ else
+ {
+ IPACMERR("unable to add Connection to pcie modem: error:%d\n", ret);
+ cache[cnt].rule_id = 0;
+ }
+ }
IPACMDBG("On wan-iface reset added below rule successfully\n");
iptodot("Private IP", nat_rule.private_ip);
@@ -217,24 +247,21 @@ int NatApp::AddTable(uint32_t pub_ip, uint8_t mux_id)
}
pub_ip_addr = pub_ip;
+ pub_mux_id = mux_id;
+ IPACMDBG(" Set pub_mux_id: %d\t", pub_mux_id);
return 0;
}
void NatApp::Reset()
{
- int cnt = 0;
-
nat_table_hdl = 0;
pub_ip_addr = 0;
- /* NAT tbl deleted, reset enabled bit */
- for(cnt = 0; cnt < max_entries; cnt++)
- {
- cache[cnt].enabled = false;
- }
+ pub_mux_id = 0;
}
int NatApp::DeleteTable(uint32_t pub_ip)
{
+ int cnt = 0;
int ret;
IPACMDBG_H("%s() %d\n", __FUNCTION__, __LINE__);
@@ -247,6 +274,27 @@ int NatApp::DeleteTable(uint32_t pub_ip)
return -1;
}
+ /* NAT tbl deleted, reset enabled bit */
+ for(cnt = 0; cnt < max_entries; cnt++)
+ {
+ cache[cnt].enabled = false;
+ /* send connections del info to pcie modem first */
+ if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP) && (cache[cnt].rule_id > 0))
+
+ {
+ ret = DelConnection(cache[cnt].rule_id);
+ if(ret)
+ {
+ IPACMERR("unable to del Connection to pcie modem: %d\n", ret);
+ }
+ else
+ {
+ /* save the rule id for deletion */
+ cache[cnt].rule_id = 0;
+ }
+ }
+ }
+
ret = ipa_nat_del_ipv4_tbl(nat_table_hdl);
if(ret)
{
@@ -286,6 +334,7 @@ bool NatApp::ChkForDup(const nat_table_entry *rule)
int NatApp::DeleteEntry(const nat_table_entry *rule)
{
int cnt = 0;
+ int ret = 0;
IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
log_nat(rule->protocol,rule->private_ip,rule->target_ip,rule->private_port,\
@@ -303,6 +352,21 @@ int NatApp::DeleteEntry(const nat_table_entry *rule)
if(cache[cnt].enabled == true)
{
+ /* send connections del info to pcie modem first */
+ if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP) && (cache[cnt].rule_id > 0))
+ {
+ ret = DelConnection(cache[cnt].rule_id);
+ if(ret)
+ {
+ IPACMERR("unable to del Connection to pcie modem: %d\n", ret);
+ }
+ else
+ {
+ /* save the rule id for deletion */
+ cache[cnt].rule_id = 0;
+ }
+ }
+
if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
{
IPACMERR("%s() %d deletion failed\n", __FUNCTION__, __LINE__);
@@ -329,6 +393,7 @@ int NatApp::AddEntry(const nat_table_entry *rule)
{
int cnt = 0;
ipa_nat_ipv4_rule nat_rule;
+ int ret = 0;
IPACMDBG("%s() %d\n", __FUNCTION__, __LINE__);
@@ -398,8 +463,23 @@ int NatApp::AddEntry(const nat_table_entry *rule)
}
cache[cnt].enabled = true;
+ /* send connections info to pcie modem only with DL direction */
+ if ((CtList->backhaul_mode == Q6_MHI_WAN) && (rule->dst_nat == true || rule->protocol == IPPROTO_TCP))
+ {
+ ret = AddConnection(rule);
+ if(ret > 0)
+ {
+ /* save the rule id for deletion */
+ cache[cnt].rule_id = ret;
+ IPACMDBG_H("rule-id(%d)\n", cache[cnt].rule_id);
+ }
+ else
+ {
+ IPACMERR("unable to add Connection to pcie modem: error:%d\n", ret);
+ cache[cnt].rule_id = 0;
+ }
+ }
}
-
cache[cnt].private_ip = rule->private_ip;
cache[cnt].target_ip = rule->target_ip;
cache[cnt].target_port = rule->target_port;
@@ -430,6 +510,137 @@ int NatApp::AddEntry(const nat_table_entry *rule)
return 0;
}
+/* Add new entry to the nat table on new connection, return rule-id */
+int NatApp::AddConnection(const nat_table_entry *rule)
+{
+ int len, res = IPACM_SUCCESS;
+ ipa_ioc_add_flt_rule *pFilteringTable = NULL;
+
+ /* contruct filter rules to pcie modem */
+ struct ipa_flt_rule_add flt_rule_entry;
+ ipa_ioc_generate_flt_eq flt_eq;
+
+ IPACMDBG("\n");
+ len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
+ pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->global = false;
+ pFilteringTable->ip = IPA_IP_v4;
+ pFilteringTable->num_rules = (uint8_t)1;
+
+ /* Configuring Software-Routing Filtering Rule */
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
+ flt_rule_entry.at_rear = true;
+ flt_rule_entry.flt_rule_hdl = -1;
+ flt_rule_entry.status = -1;
+
+ flt_rule_entry.rule.retain_hdr = 1;
+ flt_rule_entry.rule.to_uc = 0;
+ flt_rule_entry.rule.eq_attrib_type = 1;
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+#ifdef FEATURE_IPA_V3
+ flt_rule_entry.rule.hashable = true;
+#endif
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_PORT;
+ flt_rule_entry.rule.attrib.src_port = rule->target_port;
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_PORT;
+ flt_rule_entry.rule.attrib.dst_port = rule->public_port;
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
+ flt_rule_entry.rule.attrib.u.v4.protocol = rule->protocol;
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
+ flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
+ flt_rule_entry.rule.attrib.u.v4.dst_addr = rule->public_ip;
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
+ flt_rule_entry.rule.attrib.u.v4.src_addr_mask = 0xFFFFFFFF;
+ flt_rule_entry.rule.attrib.u.v4.src_addr = rule->target_ip;
+ IPACMDBG_H("src(0x%x) port(%d)->dst(0x%x) port(%d), protocol(%d) pub_mux_id (%d)\n",
+ rule->target_ip, rule->target_port, rule->public_ip, rule->public_port,
+ rule->protocol, pub_mux_id);
+
+ memset(&flt_eq, 0, sizeof(flt_eq));
+ memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
+ flt_eq.ip = IPA_IP_v4;
+ if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
+ {
+ IPACMERR("Failed to get eq_attrib\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &flt_eq.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+ memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+
+ if(false == IPACM_Iface::m_filtering.AddOffloadFilteringRule(pFilteringTable, pub_mux_id, 0))
+ {
+ IPACMERR("Failed to install WAN DL filtering table.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ /* get rule-id */
+ res = pFilteringTable->rules[0].flt_rule_hdl;
+
+fail:
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int NatApp::DelConnection(const uint32_t rule_id)
+{
+ int len, res = IPACM_SUCCESS;
+ ipa_ioc_del_flt_rule *pFilteringTable = NULL;
+
+
+ struct ipa_flt_rule_del flt_rule_entry;
+
+ IPACMDBG("\n");
+ len = sizeof(struct ipa_ioc_del_flt_rule) + sizeof(struct ipa_flt_rule_del);
+ pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = IPA_IP_v4;
+ pFilteringTable->num_hdls = (uint8_t)1;
+
+ /* Configuring Software-Routing Filtering Rule */
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
+ flt_rule_entry.hdl = rule_id;
+
+ memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
+
+ if(false == IPACM_Iface::m_filtering.DelOffloadFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Failed to install WAN DL filtering table.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+fail:
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
void NatApp::UpdateCTUdpTs(nat_table_entry *rule, uint32_t new_ts)
{
#ifdef FEATURE_IPACM_HAL
@@ -629,7 +840,7 @@ bool NatApp::isPwrSaveIf(uint32_t ip_addr)
int NatApp::UpdatePwrSaveIf(uint32_t client_lan_ip)
{
- int cnt;
+ int cnt, ret;
IPACMDBG_H("Received IP address: 0x%x\n", client_lan_ip);
if(client_lan_ip == INVALID_IP_ADDR)
@@ -662,6 +873,21 @@ int NatApp::UpdatePwrSaveIf(uint32_t client_lan_ip)
if(cache[cnt].private_ip == client_lan_ip &&
cache[cnt].enabled == true)
{
+ /* send connections del info to pcie modem first */
+ if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP) && (cache[cnt].rule_id > 0))
+ {
+ ret = DelConnection(cache[cnt].rule_id);
+ if(ret)
+ {
+ IPACMERR("unable to del Connection to pcie modem: %d\n", ret);
+ }
+ else
+ {
+ /* save the rule id for deletion */
+ cache[cnt].rule_id = 0;
+ }
+ }
+
if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
{
IPACMERR("unable to delete the rule\n");
@@ -678,7 +904,7 @@ int NatApp::UpdatePwrSaveIf(uint32_t client_lan_ip)
int NatApp::ResetPwrSaveIf(uint32_t client_lan_ip)
{
- int cnt;
+ int cnt, ret;
ipa_nat_ipv4_rule nat_rule;
IPACMDBG_H("Received ip address: 0x%x\n", client_lan_ip);
@@ -721,6 +947,22 @@ int NatApp::ResetPwrSaveIf(uint32_t client_lan_ip)
continue;
}
cache[cnt].enabled = true;
+ /* send connections info to pcie modem only with DL direction */
+ if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP))
+ {
+ ret = AddConnection(&cache[cnt]);
+ if(ret > 0)
+ {
+ /* save the rule id for deletion */
+ cache[cnt].rule_id = ret;
+ IPACMDBG_H("rule-id(%d)\n", cache[cnt].rule_id);
+ }
+ else
+ {
+ IPACMERR("unable to add Connection to pcie modem: error:%d\n", ret);
+ cache[cnt].rule_id = 0;
+ }
+ }
IPACMDBG("On power reset added below rule successfully\n");
iptodot("Private IP", nat_rule.private_ip);
@@ -866,7 +1108,7 @@ void NatApp::FlushTempEntries(uint32_t ip_addr, bool isAdd,
int NatApp::DelEntriesOnClntDiscon(uint32_t ip_addr)
{
- int cnt, tmp = 0;
+ int cnt, tmp = 0, ret;
IPACMDBG_H("Received IP address: 0x%x\n", ip_addr);
if(ip_addr == INVALID_IP_ADDR)
@@ -891,6 +1133,21 @@ int NatApp::DelEntriesOnClntDiscon(uint32_t ip_addr)
{
if(cache[cnt].enabled == true)
{
+ /* send connections del info to pcie modem first */
+ if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP) && (cache[cnt].rule_id > 0))
+ {
+ ret = DelConnection(cache[cnt].rule_id);
+ if(ret)
+ {
+ IPACMERR("unable to del Connection to pcie modem: %d\n", ret);
+ }
+ else
+ {
+ /* save the rule id for deletion */
+ cache[cnt].rule_id = 0;
+ }
+ }
+
if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
{
IPACMERR("unable to delete the rule\n");
@@ -913,7 +1170,7 @@ int NatApp::DelEntriesOnClntDiscon(uint32_t ip_addr)
int NatApp::DelEntriesOnSTAClntDiscon(uint32_t ip_addr)
{
- int cnt, tmp = curCnt;
+ int cnt, tmp = curCnt, ret;
IPACMDBG_H("Received IP address: 0x%x\n", ip_addr);
if(ip_addr == INVALID_IP_ADDR)
@@ -929,6 +1186,21 @@ int NatApp::DelEntriesOnSTAClntDiscon(uint32_t ip_addr)
{
if(cache[cnt].enabled == true)
{
+ /* send connections del info to pcie modem first */
+ if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP) && (cache[cnt].rule_id > 0))
+ {
+ ret = DelConnection(cache[cnt].rule_id);
+ if(ret)
+ {
+ IPACMERR("unable to del Connection to pcie modem: %d\n", ret);
+ }
+ else
+ {
+ /* save the rule id for deletion */
+ cache[cnt].rule_id = 0;
+ }
+ }
+
if(ipa_nat_del_ipv4_rule(nat_table_hdl, cache[cnt].rule_hdl) < 0)
{
IPACMERR("unable to delete the rule\n");
diff --git a/ipacm/src/IPACM_Filtering.cpp b/ipacm/src/IPACM_Filtering.cpp
index 3545d81..a158d74 100644
--- a/ipacm/src/IPACM_Filtering.cpp
+++ b/ipacm/src/IPACM_Filtering.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -57,6 +57,8 @@ IPACM_Filtering::IPACM_Filtering()
{
IPACMERR("Failed opening %s.\n", DEVICE_NAME);
}
+ total_num_offload_rules = 0;
+ pcie_modem_rule_id = 0;
}
IPACM_Filtering::~IPACM_Filtering()
@@ -114,6 +116,242 @@ bool IPACM_Filtering::AddFilteringRule(struct ipa_ioc_add_flt_rule const *ruleTa
return true;
}
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+bool IPACM_Filtering::AddFilteringRule_hw_index(struct ipa_ioc_add_flt_rule *ruleTable, int hw_counter_index)
+{
+ int retval=0, cnt = 0, len = 0;
+ struct ipa_ioc_add_flt_rule_v2 *ruleTable_v2;
+ struct ipa_flt_rule_add_v2 flt_rule_entry;
+ bool ret = true;
+
+ IPACMDBG("Printing filter add attributes\n");
+ IPACMDBG("ip type: %d\n", ruleTable->ip);
+ IPACMDBG("Number of rules: %d\n", ruleTable->num_rules);
+ IPACMDBG("End point: %d and global value: %d\n", ruleTable->ep, ruleTable->global);
+ IPACMDBG("commit value: %d\n", ruleTable->commit);
+
+ /* change to v2 format*/
+ len = sizeof(struct ipa_ioc_add_flt_rule_v2);
+ ruleTable_v2 = (struct ipa_ioc_add_flt_rule_v2*)malloc(len);
+ if (ruleTable_v2 == NULL)
+ {
+ IPACMERR("Error Locate ipa_ioc_add_flt_rule_v2 memory...\n");
+ return false;
+ }
+ memset(ruleTable_v2, 0, len);
+ ruleTable_v2->rules = (uint64_t)calloc(ruleTable->num_rules, sizeof(struct ipa_flt_rule_add_v2));
+ if (!ruleTable_v2->rules) {
+ IPACMERR("Failed to allocate memory for filtering rules\n");
+ ret = false;
+ goto fail_tbl;
+ }
+
+ ruleTable_v2->commit = ruleTable->commit;
+ ruleTable_v2->ep = ruleTable->ep;
+ ruleTable_v2->global = ruleTable->global;
+ ruleTable_v2->ip = ruleTable->ip;
+ ruleTable_v2->num_rules = ruleTable->num_rules;
+ ruleTable_v2->flt_rule_size = sizeof(struct ipa_flt_rule_add_v2);
+
+ for (cnt=0; cnt < ruleTable->num_rules; cnt++)
+ {
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add_v2));
+ flt_rule_entry.at_rear = ruleTable->rules[cnt].at_rear;
+ flt_rule_entry.rule.retain_hdr = ruleTable->rules[cnt].rule.retain_hdr;
+ flt_rule_entry.rule.to_uc = ruleTable->rules[cnt].rule.to_uc;
+ flt_rule_entry.rule.action = ruleTable->rules[cnt].rule.action;
+ flt_rule_entry.rule.rt_tbl_hdl = ruleTable->rules[cnt].rule.rt_tbl_hdl;
+ flt_rule_entry.rule.rt_tbl_idx = ruleTable->rules[cnt].rule.rt_tbl_idx;
+ flt_rule_entry.rule.eq_attrib_type = ruleTable->rules[cnt].rule.eq_attrib_type;
+ flt_rule_entry.rule.max_prio = ruleTable->rules[cnt].rule.max_prio;
+ flt_rule_entry.rule.hashable = ruleTable->rules[cnt].rule.hashable;
+ flt_rule_entry.rule.rule_id = ruleTable->rules[cnt].rule.rule_id;
+ flt_rule_entry.rule.set_metadata = ruleTable->rules[cnt].rule.set_metadata;
+ flt_rule_entry.rule.pdn_idx = ruleTable->rules[cnt].rule.pdn_idx;
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &ruleTable->rules[cnt].rule.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+ memcpy(&flt_rule_entry.rule.attrib,
+ &ruleTable->rules[cnt].rule.attrib,
+ sizeof(flt_rule_entry.rule.attrib));
+ IPACMDBG("Filter rule:%d attrib mask: 0x%x\n", cnt,
+ ruleTable->rules[cnt].rule.attrib.attrib_mask);
+ /* 0 means disable hw-counter-sats */
+ if (hw_counter_index != 0)
+ {
+ flt_rule_entry.rule.enable_stats = 1;
+ flt_rule_entry.rule.cnt_idx = hw_counter_index;
+ }
+
+ /* copy to v2 table*/
+ memcpy((void *)(ruleTable_v2->rules + (cnt * sizeof(struct ipa_flt_rule_add_v2))),
+ &flt_rule_entry, sizeof(flt_rule_entry));
+ }
+
+ retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE_V2, ruleTable_v2);
+ if (retval != 0)
+ {
+ IPACMERR("Failed adding Filtering rule %pK\n", ruleTable_v2);
+ PERROR("unable to add filter rule:");
+
+ for (int cnt = 0; cnt < ruleTable_v2->num_rules; cnt++)
+ {
+ if (((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
+ {
+ IPACMERR("Adding Filter rule:%d failed with status:%d\n",
+ cnt, ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status);
+ }
+ }
+ ret = false;
+ goto fail_rule;
+ }
+
+ /* copy results from v2 to v1 format */
+ for (int cnt = 0; cnt < ruleTable->num_rules; cnt++)
+ {
+ /* copy status to v1 format */
+ ruleTable->rules[cnt].status = ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status;
+ ruleTable->rules[cnt].flt_rule_hdl = ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].flt_rule_hdl;
+
+ if(((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
+ {
+ IPACMERR("Adding Filter rule:%d failed with status:%d\n",
+ cnt, ((struct ipa_flt_rule_add_v2 *) ruleTable_v2->rules)[cnt].status);
+ }
+ }
+
+ IPACMDBG("Added Filtering rule %pK\n", ruleTable_v2);
+
+fail_rule:
+ if((void *)ruleTable_v2->rules != NULL)
+ free((void *)ruleTable_v2->rules);
+fail_tbl:
+ if (ruleTable_v2 != NULL)
+ free(ruleTable_v2);
+ return ret;
+}
+
+bool IPACM_Filtering::AddFilteringRuleAfter_hw_index(struct ipa_ioc_add_flt_rule_after *ruleTable, int hw_counter_index)
+{
+ bool ret = true;
+#ifdef FEATURE_IPA_V3
+ int retval=0, cnt = 0, len = 0;
+ struct ipa_ioc_add_flt_rule_after_v2 *ruleTable_v2;
+ struct ipa_flt_rule_add_v2 flt_rule_entry;
+
+ IPACMDBG("Printing filter add attributes\n");
+ IPACMDBG("ep: %d\n", ruleTable->ep);
+ IPACMDBG("ip type: %d\n", ruleTable->ip);
+ IPACMDBG("Number of rules: %d\n", ruleTable->num_rules);
+ IPACMDBG("add_after_hdl: %d\n", ruleTable->add_after_hdl);
+ IPACMDBG("commit value: %d\n", ruleTable->commit);
+
+ /* change to v2 format*/
+ len = sizeof(struct ipa_ioc_add_flt_rule_after_v2);
+ ruleTable_v2 = (struct ipa_ioc_add_flt_rule_after_v2*)malloc(len);
+ if (ruleTable_v2 == NULL)
+ {
+ IPACMERR("Error Locate ipa_ioc_add_flt_rule_after_v2 memory...\n");
+ return false;
+ }
+ memset(ruleTable_v2, 0, len);
+ ruleTable_v2->rules = (uint64_t)calloc(ruleTable->num_rules, sizeof(struct ipa_flt_rule_add_v2));
+ if (!ruleTable_v2->rules) {
+ IPACMERR("Failed to allocate memory for filtering rules\n");
+ ret = false;
+ goto fail_tbl;
+ }
+
+ ruleTable_v2->commit = ruleTable->commit;
+ ruleTable_v2->ep = ruleTable->ep;
+ ruleTable_v2->ip = ruleTable->ip;
+ ruleTable_v2->num_rules = ruleTable->num_rules;
+ ruleTable_v2->add_after_hdl = ruleTable->add_after_hdl;
+ ruleTable_v2->flt_rule_size = sizeof(struct ipa_flt_rule_add_v2);
+
+ for (cnt=0; cnt < ruleTable->num_rules; cnt++)
+ {
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add_v2));
+ flt_rule_entry.at_rear = ruleTable->rules[cnt].at_rear;
+ flt_rule_entry.rule.retain_hdr = ruleTable->rules[cnt].rule.retain_hdr;
+ flt_rule_entry.rule.to_uc = ruleTable->rules[cnt].rule.to_uc;
+ flt_rule_entry.rule.action = ruleTable->rules[cnt].rule.action;
+ flt_rule_entry.rule.rt_tbl_hdl = ruleTable->rules[cnt].rule.rt_tbl_hdl;
+ flt_rule_entry.rule.rt_tbl_idx = ruleTable->rules[cnt].rule.rt_tbl_idx;
+ flt_rule_entry.rule.eq_attrib_type = ruleTable->rules[cnt].rule.eq_attrib_type;
+ flt_rule_entry.rule.max_prio = ruleTable->rules[cnt].rule.max_prio;
+ flt_rule_entry.rule.hashable = ruleTable->rules[cnt].rule.hashable;
+ flt_rule_entry.rule.rule_id = ruleTable->rules[cnt].rule.rule_id;
+ flt_rule_entry.rule.set_metadata = ruleTable->rules[cnt].rule.set_metadata;
+ flt_rule_entry.rule.pdn_idx = ruleTable->rules[cnt].rule.pdn_idx;
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &ruleTable->rules[cnt].rule.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+ memcpy(&flt_rule_entry.rule.attrib,
+ &ruleTable->rules[cnt].rule.attrib,
+ sizeof(flt_rule_entry.rule.attrib));
+ IPACMDBG("Filter rule:%d attrib mask: 0x%x\n", cnt,
+ ruleTable->rules[cnt].rule.attrib.attrib_mask);
+ /* 0 means disable hw-counter-sats */
+ if (hw_counter_index != 0)
+ {
+ flt_rule_entry.rule.enable_stats = 1;
+ flt_rule_entry.rule.cnt_idx = hw_counter_index;
+ }
+
+ /* copy to v2 table*/
+ memcpy((void *)(ruleTable_v2->rules + (cnt * sizeof(struct ipa_flt_rule_add_v2))),
+ &flt_rule_entry, sizeof(flt_rule_entry));
+ }
+
+ retval = ioctl(fd, IPA_IOC_ADD_FLT_RULE_AFTER_V2, ruleTable_v2);
+ if (retval != 0)
+ {
+ IPACMERR("Failed adding Filtering rule %pK\n", ruleTable_v2);
+ PERROR("unable to add filter rule:");
+
+ for (int cnt = 0; cnt < ruleTable_v2->num_rules; cnt++)
+ {
+ if (((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
+ {
+ IPACMERR("Adding Filter rule:%d failed with status:%d\n",
+ cnt, ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status);
+ }
+ }
+ ret = false;
+ goto fail_rule;
+ }
+
+ /* copy results from v2 to v1 format */
+ for (int cnt = 0; cnt < ruleTable->num_rules; cnt++)
+ {
+ /* copy status to v1 format */
+ ruleTable->rules[cnt].status = ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status;
+ ruleTable->rules[cnt].flt_rule_hdl = ((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].flt_rule_hdl;
+
+ if(((struct ipa_flt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
+ {
+ IPACMERR("Adding Filter rule:%d failed with status:%d\n",
+ cnt, ((struct ipa_flt_rule_add_v2 *) ruleTable_v2->rules)[cnt].status);
+ }
+ }
+
+ IPACMDBG("Added Filtering rule %pK\n", ruleTable_v2);
+
+fail_rule:
+ if((void *)ruleTable_v2->rules != NULL)
+ free((void *)ruleTable_v2->rules);
+fail_tbl:
+ if (ruleTable_v2 != NULL)
+ free(ruleTable_v2);
+#else
+ if (ruleTable)
+ IPACMERR("Not support adding Filtering rule %pK\n", ruleTable);
+#endif
+ return ret;
+}
+#endif //IPA_IOCTL_SET_FNR_COUNTER_INFO
+
bool IPACM_Filtering::AddFilteringRuleAfter(struct ipa_ioc_add_flt_rule_after const *ruleTable)
{
#ifdef FEATURE_IPA_V3
@@ -461,6 +699,225 @@ bool IPACM_Filtering::AddWanDLFilteringRule(struct ipa_ioc_add_flt_rule const *r
return true;
}
+bool IPACM_Filtering::AddOffloadFilteringRule(struct ipa_ioc_add_flt_rule *flt_rule_tbl, uint8_t mux_id, uint8_t default_path)
+{
+#ifdef WAN_IOCTL_ADD_OFFLOAD_CONNECTION
+ int ret = 0, cnt, pos = 0;
+ ipa_add_offload_connection_req_msg_v01 qmi_add_msg;
+ int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
+ if(fd_wwan_ioctl < 0)
+ {
+ IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
+ return false;
+ }
+
+ if(flt_rule_tbl == NULL)
+ {
+ if(mux_id ==0)
+ {
+ IPACMERR("Invalid add_offload_req muxd: (%d)\n", mux_id);
+ close(fd_wwan_ioctl);
+ return false;
+ }
+#ifdef QMI_IPA_MAX_FILTERS_EX2_V01
+ /* used for sending mux_id info to modem for UL sky*/
+ IPACMDBG_H("sending mux_id info (%d) to modem for UL\n", mux_id);
+ memset(&qmi_add_msg, 0, sizeof(qmi_add_msg));
+ qmi_add_msg.embedded_call_mux_id_valid = true;
+ qmi_add_msg.embedded_call_mux_id = mux_id;
+ ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_OFFLOAD_CONNECTION, &qmi_add_msg);
+ if (ret != 0)
+ {
+ IPACMERR("Failed sending WAN_IOC_ADD_OFFLOAD_CONNECTION with ret %d\n ", ret);
+ close(fd_wwan_ioctl);
+ return false;
+ }
+#endif
+ close(fd_wwan_ioctl);
+ return true;
+ }
+ /* check Max offload connections */
+ if (total_num_offload_rules + flt_rule_tbl->num_rules > QMI_IPA_MAX_FILTERS_V01)
+ {
+ IPACMERR("(%d) add_offload req with curent(%d), exceed max (%d).\n",
+ flt_rule_tbl->num_rules, total_num_offload_rules,
+ QMI_IPA_MAX_FILTERS_V01);
+ close(fd_wwan_ioctl);
+ return false;
+ }
+ else
+ {
+ memset(&qmi_add_msg, 0, sizeof(qmi_add_msg));
+
+ if (flt_rule_tbl->num_rules > 0)
+ {
+ qmi_add_msg.filter_spec_ex2_list_valid = true;
+ }
+ else
+ {
+ IPACMDBG_H("Get %d offload-req\n", flt_rule_tbl->num_rules);
+ close(fd_wwan_ioctl);
+ return true;
+ }
+ qmi_add_msg.filter_spec_ex2_list_len = flt_rule_tbl->num_rules;
+
+ /* check if we want to take default MHI path */
+ if (default_path)
+ {
+ qmi_add_msg.default_mhi_path_valid = true;
+ qmi_add_msg.default_mhi_path = true;
+ }
+
+ IPACMDBG_H("passing %d offload req to modem. default %d\n", flt_rule_tbl->num_rules, qmi_add_msg.default_mhi_path);
+
+ if(flt_rule_tbl != NULL)
+ {
+ for(cnt = flt_rule_tbl->num_rules - 1; cnt >= 0; cnt--)
+ {
+ if (pos < QMI_IPA_MAX_FILTERS_V01)
+ {
+ if (flt_rule_tbl->ip == IPA_IP_v4)
+ {
+ qmi_add_msg.filter_spec_ex2_list[pos].ip_type = QMI_IPA_IP_TYPE_V4_V01;
+ } else if (flt_rule_tbl->ip == IPA_IP_v6) {
+ qmi_add_msg.filter_spec_ex2_list[pos].ip_type = QMI_IPA_IP_TYPE_V6_V01;
+ } else {
+ IPACMDBG_H("invalid ip-type %d\n", flt_rule_tbl->ip);
+ close(fd_wwan_ioctl);
+ return true;
+ }
+
+ qmi_add_msg.filter_spec_ex2_list[pos].filter_action = GetQmiFilterAction(flt_rule_tbl->rules[cnt].rule.action);
+ qmi_add_msg.filter_spec_ex2_list[pos].is_mux_id_valid = 1;
+ qmi_add_msg.filter_spec_ex2_list[pos].mux_id = mux_id;
+ /* assign the rule-id */
+ flt_rule_tbl->rules[cnt].flt_rule_hdl = IPA_PCIE_MODEM_RULE_ID_START + pcie_modem_rule_id;
+ qmi_add_msg.filter_spec_ex2_list[pos].rule_id = flt_rule_tbl->rules[cnt].flt_rule_hdl;
+ qmi_add_msg.filter_spec_ex2_list[pos].is_rule_hashable = flt_rule_tbl->rules[cnt].rule.hashable;
+ memcpy(&qmi_add_msg.filter_spec_ex2_list[pos].filter_rule,
+ &flt_rule_tbl->rules[cnt].rule.eq_attrib,
+ sizeof(struct ipa_filter_rule_type_v01));
+ IPACMDBG_H("mux-id %d, hashable %d\n", qmi_add_msg.filter_spec_ex2_list[pos].mux_id, qmi_add_msg.filter_spec_ex2_list[pos].is_rule_hashable);
+ pos++;
+ pcie_modem_rule_id = (pcie_modem_rule_id + 1)%100;
+ }
+ else
+ {
+ IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos);
+ }
+ }
+ }
+
+ ret = ioctl(fd_wwan_ioctl, WAN_IOC_ADD_OFFLOAD_CONNECTION, &qmi_add_msg);
+ if (ret != 0)
+ {
+ IPACMERR("Failed sending WAN_IOC_ADD_OFFLOAD_CONNECTION with ret %d\n ", ret);
+ close(fd_wwan_ioctl);
+ return false;
+ }
+ }
+ /* update total_num_offload_rules */
+ total_num_offload_rules += flt_rule_tbl->num_rules;
+ IPACMDBG_H("total_num_offload_rules %d \n", total_num_offload_rules);
+ close(fd_wwan_ioctl);
+ return true;
+#else
+ if(flt_rule_tbl != NULL)
+ {
+ IPACMERR("Not support (%d) AddOffloadFilteringRule with mux-id (%d) and default path = %d\n", flt_rule_tbl->num_rules, mux_id, default_path);
+ }
+ return false;
+#endif
+}
+
+bool IPACM_Filtering::DelOffloadFilteringRule(struct ipa_ioc_del_flt_rule const *flt_rule_tbl)
+{
+#ifdef WAN_IOCTL_ADD_OFFLOAD_CONNECTION
+ bool result = true;
+ int ret = 0, cnt, pos = 0;
+ ipa_remove_offload_connection_req_msg_v01 qmi_del_msg;
+ int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
+
+ if(fd_wwan_ioctl < 0)
+ {
+ IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
+ return false;
+ }
+
+ if(flt_rule_tbl == NULL)
+ {
+ IPACMERR("Invalid add_offload_req\n");
+ result = false;
+ goto fail;
+ }
+
+ /* check # of offload connections */
+ if (flt_rule_tbl->num_hdls > total_num_offload_rules) {
+ IPACMERR("(%d) del_offload req , exceed curent(%d)\n",
+ flt_rule_tbl->num_hdls, total_num_offload_rules);
+ result = false;
+ goto fail;
+ }
+ else
+ {
+ memset(&qmi_del_msg, 0, sizeof(qmi_del_msg));
+
+ if (flt_rule_tbl->num_hdls > 0)
+ {
+ qmi_del_msg.filter_handle_list_valid = true;
+ }
+ else
+ {
+ IPACMERR("Get %d offload-req\n", flt_rule_tbl->num_hdls);
+ goto fail;
+ }
+ qmi_del_msg.filter_handle_list_len = flt_rule_tbl->num_hdls;
+
+ IPACMDBG_H("passing %d offload req to modem.\n", flt_rule_tbl->num_hdls);
+
+ if(flt_rule_tbl != NULL)
+ {
+ for(cnt = flt_rule_tbl->num_hdls - 1; cnt >= 0; cnt--)
+ {
+ if (pos < QMI_IPA_MAX_FILTERS_V01)
+ {
+ /* passing rule-id to wan-driver */
+ qmi_del_msg.filter_handle_list[pos].filter_spec_identifier = flt_rule_tbl->hdl[cnt].hdl;
+ pos++;
+ }
+ else
+ {
+ IPACMERR(" QMI only support max %d rules, current (%d)\n ",QMI_IPA_MAX_FILTERS_V01, pos);
+ result = false;
+ goto fail;
+ }
+ }
+ }
+
+ ret = ioctl(fd_wwan_ioctl, WAN_IOC_RMV_OFFLOAD_CONNECTION, &qmi_del_msg);
+ if (ret != 0)
+ {
+ IPACMERR("Failed deleting Filtering rule %pK with ret %d\n ", &qmi_del_msg, ret);
+ result = false;
+ goto fail;
+ }
+ }
+ /* update total_num_offload_rules */
+ total_num_offload_rules -= flt_rule_tbl->num_hdls;
+ IPACMDBG_H("total_num_offload_rules %d \n", total_num_offload_rules);
+
+fail:
+ close(fd_wwan_ioctl);
+ return result;
+#else
+ if(flt_rule_tbl != NULL)
+ {
+ IPACMERR("Not support (%d) DelOffloadFilteringRule\n", flt_rule_tbl->num_hdls);
+ }
+ return false;
+#endif
+}
+
bool IPACM_Filtering::SendFilteringRuleIndex(struct ipa_fltr_installed_notif_req_msg_v01* table)
{
int ret = 0;
diff --git a/ipacm/src/IPACM_Iface.cpp b/ipacm/src/IPACM_Iface.cpp
index 512846f..ec4a9ea 100644
--- a/ipacm/src/IPACM_Iface.cpp
+++ b/ipacm/src/IPACM_Iface.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -88,12 +88,14 @@ IPACM_Iface::IPACM_Iface(int iface_index)
}
/* software routing enable */
-int IPACM_Iface::handle_software_routing_enable(void)
+int IPACM_Iface::handle_software_routing_enable(bool mhip)
{
-
+ int fd =0;
int res = IPACM_SUCCESS;
struct ipa_flt_rule_add flt_rule_entry;
ipa_ioc_add_flt_rule *m_pFilteringTable;
+ /* contruct filter rules to pcie modem */
+ ipa_ioc_generate_flt_eq flt_eq;
IPACMDBG("\n");
if (softwarerouting_act == true)
@@ -121,11 +123,9 @@ int IPACM_Iface::handle_software_routing_enable(void)
}
m_pFilteringTable->commit = 1;
- m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
m_pFilteringTable->global = false;
m_pFilteringTable->num_rules = (uint8_t)1;
-
/* Configuring Software-Routing Filtering Rule */
memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
@@ -143,10 +143,48 @@ int IPACM_Iface::handle_software_routing_enable(void)
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
/* check iface is v4 or v6 or both*/
-// if (ip_type == IPA_IP_MAX)
-// {
+
/* handle v4 */
m_pFilteringTable->ip = IPA_IP_v4;
+
+ fd = open(IPA_DEVICE_NAME, O_RDWR);
+ if (fd < 0)
+ {
+ IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
+ free(m_pFilteringTable);
+ return IPACM_FAILURE;
+ }
+
+ if (mhip)
+ {
+ /* generate eq */
+ memset(&flt_eq, 0, sizeof(flt_eq));
+ memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
+ flt_eq.ip = IPA_IP_v4;
+
+
+ if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) //define and cpy attribute to this struct
+ {
+ IPACMERR("Failed to get eq_attrib\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &flt_eq.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+ memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+
+ /* add rule */
+ if(false == m_filtering.AddOffloadFilteringRule(m_pFilteringTable, IPACM_Iface::ipacmcfg->GetQmapId(), 1))
+ {
+ IPACMERR("Failed to install WAN DL filtering table.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ else
+ {
+ m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
{
IPACMERR("Error Adding Filtering rule, aborting...\n");
@@ -159,46 +197,44 @@ int IPACM_Iface::handle_software_routing_enable(void)
res = IPACM_FAILURE;
goto fail;
}
-
IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
- IPACMDBG("soft-routing flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl);
+ }
+
+ IPACMDBG("soft-routing ipv4 flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl);
/* copy filter hdls */
software_routing_fl_rule_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl;
-
/* handle v6*/
m_pFilteringTable->ip = IPA_IP_v6;
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+ if (mhip)
+ {
+ /* generate eq */
+ memset(&flt_eq, 0, sizeof(flt_eq));
+ memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
+ flt_eq.ip = IPA_IP_v6;
+
+ if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) //define and cpy attribute to this struct
{
- IPACMERR("Error Adding Filtering rule, aborting...\n");
+ IPACMERR("Failed to get eq_attrib\n");
res = IPACM_FAILURE;
goto fail;
}
- else if (m_pFilteringTable->rules[0].status)
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &flt_eq.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+ memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+
+ /* add rule */
+ if(false == m_filtering.AddOffloadFilteringRule(m_pFilteringTable, IPACM_Iface::ipacmcfg->GetQmapId(), 1))
{
- IPACMDBG("adding flt rule failed status=0x%x\n", m_pFilteringTable->rules[0].status);
+ IPACMERR("Failed to install WAN DL filtering table.\n");
res = IPACM_FAILURE;
goto fail;
}
-
- IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
- IPACMDBG("soft-routing flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl);
- /* copy filter hdls */
- software_routing_fl_rule_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl;
- softwarerouting_act = true;
-#if 0
}
else
{
- if (ip_type == IPA_IP_v4)
- {
- m_pFilteringTable->ip = IPA_IP_v4;
- }
- else
- {
- m_pFilteringTable->ip = IPA_IP_v6;
- }
-
+ m_pFilteringTable->ep = rx_prop->rx[0].src_pipe;
if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
{
IPACMERR("Error Adding Filtering rule, aborting...\n");
@@ -211,32 +247,29 @@ int IPACM_Iface::handle_software_routing_enable(void)
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
+ }
- IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, ip_type, 1);
- IPACMDBG("soft-routing flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl);
+ IPACMDBG("soft-routing ipv6 flt rule hdl0=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl);
/* copy filter hdls */
- if (ip_type == IPA_IP_v4)
- {
- software_routing_fl_rule_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl;
- }
- else
- {
software_routing_fl_rule_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl;
- }
softwarerouting_act = true;
- }
-#endif
fail:
+ close(fd);
+ if(m_pFilteringTable != NULL)
+ {
free(m_pFilteringTable);
-
+ }
return res;
}
/* software routing disable */
-int IPACM_Iface::handle_software_routing_disable(void)
+int IPACM_Iface::handle_software_routing_disable(bool mhip)
{
- int res = IPACM_SUCCESS;
+ int len, res = IPACM_SUCCESS;
+ ipa_ioc_del_flt_rule *pFilteringTable = NULL;
+ struct ipa_flt_rule_del flt_rule_entry;
if (rx_prop == NULL)
{
@@ -250,63 +283,96 @@ int IPACM_Iface::handle_software_routing_disable(void)
return IPACM_SUCCESS;
}
-// if (ip_type == IPA_IP_MAX)
-// {
- /* ipv4 case */
- if (m_filtering.DeleteFilteringHdls(&software_routing_fl_rule_hdl[0],
- IPA_IP_v4, 1) == false)
+ if(mhip)
+ {
+ len = sizeof(struct ipa_ioc_del_flt_rule) + sizeof(struct ipa_flt_rule_del);
+ pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
{
- IPACMERR("Error Adding Filtering rule, aborting...\n");
+ IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = IPA_IP_v4;
+ pFilteringTable->num_hdls = (uint8_t)1;
+
+ if (software_routing_fl_rule_hdl[0] == 0)
+ {
+ IPACMERR("invalid ipv4_exception_hdl.\n");
res = IPACM_FAILURE;
goto fail;
}
- IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
- /* ipv6 case */
- if (m_filtering.DeleteFilteringHdls(&software_routing_fl_rule_hdl[1],
- IPA_IP_v6, 1) == false)
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
+ flt_rule_entry.hdl = software_routing_fl_rule_hdl[0];
+
+ memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
+
+ if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
{
- IPACMERR("Error Adding Filtering rule, aborting...\n");
+ IPACMERR("Failed to delete MHI ipv4 exception rule.\n");
res = IPACM_FAILURE;
goto fail;
}
- IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
- softwarerouting_act = false;
-#if 0
+ software_routing_fl_rule_hdl[0] = 0;
}
else
{
- if (ip_type == IPA_IP_v4)
+ /* ipv4 case */
+ if (m_filtering.DeleteFilteringHdls(&software_routing_fl_rule_hdl[0],
+ IPA_IP_v4, 1) == false)
{
- ip = IPA_IP_v4;
+ IPACMERR("Error Adding Filtering rule, aborting...\n");
+ res = IPACM_FAILURE;
+ goto fail;
}
- else
+ }
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1);
+
+ if(mhip)
+ {
+ pFilteringTable->ip = IPA_IP_v6;
+ if (software_routing_fl_rule_hdl[1] == 0)
{
- ip = IPA_IP_v6;
+ IPACMERR("invalid ipv6_exception_hdl.\n");
+ res = IPACM_FAILURE;
+ goto fail;
}
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
+ flt_rule_entry.hdl = software_routing_fl_rule_hdl[1];
- if (ip_type == IPA_IP_v4)
+ memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
+
+ if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
{
- flt_hdl = software_routing_fl_rule_hdl[0];
+ IPACMERR("Failed to delete MHI ipv6 exception rule.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ software_routing_fl_rule_hdl[1] = 0;
}
else
{
- flt_hdl = software_routing_fl_rule_hdl[1];
- }
-
- if (m_filtering.DeleteFilteringHdls(&flt_hdl, ip, 1) == false)
+ /* ipv6 case */
+ if (m_filtering.DeleteFilteringHdls(&software_routing_fl_rule_hdl[1],
+ IPA_IP_v6, 1) == false)
{
IPACMERR("Error Adding Filtering rule, aborting...\n");
res = IPACM_FAILURE;
goto fail;
}
- IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, ip, 1);
- softwarerouting_act = false;
}
-#endif
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
+ softwarerouting_act = false;
fail:
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
return res;
}
@@ -633,6 +699,7 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
int res = IPACM_SUCCESS, len = 0;
struct ipa_flt_rule_add flt_rule_entry;
ipa_ioc_add_flt_rule *m_pFilteringTable;
+ bool result;
/* Adding this hack because WLAN may not registered for Rx-endpoint, other ifaces will always have*/
const char *dev_wlan0="wlan0";
@@ -739,7 +806,25 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
#endif
memcpy(&(m_pFilteringTable->rules[2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(ipa_if_cate == WAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ } else if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ } else
+ {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+
+ if (result == false)
{
IPACMERR("Error Adding Filtering rule, aborting...\n");
res = IPACM_FAILURE;
@@ -921,7 +1006,20 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
memcpy(&(m_pFilteringTable->rules[7]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
#endif
- if (m_filtering.AddFilteringRule(m_pFilteringTable) == false)
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(ipa_if_cate == WAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+
+ if (result == false)
{
IPACMERR("Error Adding Filtering rule, aborting...\n");
res = IPACM_FAILURE;
@@ -1045,6 +1143,58 @@ void IPACM_Iface::config_ip_type(ipa_ip_type iptype)
return;
}
+void IPACM_Iface::change_to_network_order(ipa_ip_type iptype, ipa_rule_attrib* attrib)
+{
+ if(attrib == NULL)
+ {
+ IPACMERR("Attribute pointer is NULL.\n");
+ return;
+ }
+
+ if(iptype == IPA_IP_v6)
+ {
+ int i;
+ for(i=0; i<4; i++)
+ {
+ attrib->u.v6.src_addr[i] = htonl(attrib->u.v6.src_addr[i]);
+ attrib->u.v6.src_addr_mask[i] = htonl(attrib->u.v6.src_addr_mask[i]);
+ attrib->u.v6.dst_addr[i] = htonl(attrib->u.v6.dst_addr[i]);
+ attrib->u.v6.dst_addr_mask[i] = htonl(attrib->u.v6.dst_addr_mask[i]);
+ }
+ }
+ else
+ {
+ IPACMDBG_H("IP type is not IPv6, do nothing: %d\n", iptype);
+ }
+
+ return;
+}
+
+bool IPACM_Iface::is_global_ipv6_addr(uint32_t* ipv6_addr)
+{
+ uint32_t ipv6_link_local_prefix, ipv6_link_local_prefix_mask;
+ ipv6_link_local_prefix = 0xFE800000;
+ ipv6_link_local_prefix_mask = 0xFFC00000;
+
+ if(ipv6_addr == NULL)
+ {
+ IPACMERR("IPv6 address is empty.\n");
+ return false;
+ }
+ IPACMDBG_H("Get ipv6 address with first word 0x%08x.\n", ipv6_addr[0]);
+
+ if((ipv6_addr[0] & ipv6_link_local_prefix_mask) == (ipv6_link_local_prefix & ipv6_link_local_prefix_mask))
+ {
+ IPACMDBG_H("This IPv6 address is link local.\n");
+ return false;
+ }
+ else
+ {
+ IPACMDBG_H("This IPv6 address is not link local.\n");
+ return true;
+ }
+}
+
void IPACM_Iface::delete_iface(void)
{
IPACMDBG_H("netdev (%s):ipa_index (%d) instance close \n",
diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp
index 1c7dfc4..3e825dd 100644
--- a/ipacm/src/IPACM_IfaceManager.cpp
+++ b/ipacm/src/IPACM_IfaceManager.cpp
@@ -484,6 +484,7 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param)
}
else
{
+ IPACM_EvtDispatcher::registr(IPA_COALESCE_NOTICE, w);
IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, w);
}
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 827839b..755d730 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -184,9 +184,9 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
handle_tethering_client(false, IPACM_CLIENT_MAX);
#else
handle_tethering_client(false, IPACM_CLIENT_USB);
-#endif
+#endif // FEATURE_IPACM_HAL end
}
-#endif
+#endif // FEATURE_IPA_ANDROID end
memset(is_downstream_set, 0, sizeof(is_downstream_set));
memset(is_upstream_set, 0, sizeof(is_upstream_set));
@@ -195,9 +195,9 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
#ifdef FEATURE_IPACM_HAL
/* check if Upstream was set before as WIFI with RNDIS case */
- if(ipa_if_cate == LAN_IF && IPACM_Wan::backhaul_is_sta_mode == true) /* LTE */
+ if(ipa_if_cate == LAN_IF && IPACM_Wan::backhaul_mode == WLAN_WAN) /* LTE */
{
- IPACMDBG_H(" Skip the Upstream falg set on LAN instance (%d) with WIFI backhaul (%d)\n", ipa_if_cate, IPACM_Wan::backhaul_is_sta_mode ); /* RNDIS+WIFI not support on msm*/
+ IPACMDBG_H(" Skip the Upstream flag set on LAN instance (%d) with WIFI backhaul (%d)\n", ipa_if_cate, IPACM_Wan::backhaul_mode ); /* RNDIS+WIFI not support on msm*/
return;
}
@@ -213,7 +213,7 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
IPACMDBG_H("Upstream was set previously for ipv6, change is_upstream_set flag\n");
is_upstream_set[IPA_IP_v6] = true;
}
-#endif
+#endif // FEATURE_IPACM_HAL end
return;
}
@@ -399,7 +399,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
handle_private_subnet_android(data->iptype);
#else
handle_private_subnet(data->iptype);
-#endif
+#endif // FEATURE_IPA_ANDROID end
}
else
{
@@ -419,14 +419,14 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
handle_private_subnet_android(data->iptype);
#else
handle_private_subnet(data->iptype);
-#endif
+#endif // FEATURE_IPA_ANDROID end
#ifndef FEATURE_IPACM_HAL
if (IPACM_Wan::isWanUP(ipa_if_num))
{
if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
{
- if(IPACM_Wan::backhaul_is_sta_mode == false)
+ if(IPACM_Wan::backhaul_mode == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
handle_wan_up_ex(ext_prop, IPA_IP_v4,
@@ -448,7 +448,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
{
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)
+ if(IPACM_Wan::backhaul_mode == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
@@ -474,7 +474,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("Upstream was set previously for ipv6, change is_upstream_set flag\n");
is_upstream_set[IPA_IP_v6] = true;
}
-#endif
+#endif //FEATURE_IPACM_HAL end
/* Post event to NAT */
if (data->iptype == IPA_IP_v4)
{
@@ -511,7 +511,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
{
/* handle software routing enable event*/
IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
- handle_software_routing_enable();
+ handle_software_routing_enable(false);
}
}
@@ -528,7 +528,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No event data is found.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s xlat_mux_id: %d\n", data_wan_tether->is_sta,
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s, xlat %d\n", data_wan_tether->backhaul_type,
data_wan_tether->if_index_tether,
IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name,
data_wan_tether->xlat_mux_id);
@@ -539,7 +539,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
return;
}
#else /* not offload rndis on WIFI mode on MSM targets */
- if (data_wan_tether->is_sta)
+ if (data_wan_tether->backhaul_type == WLAN_WAN)
{
IPACMERR("Not support RNDIS offload on WIFI mode, dun install UL filter rules for WIFI mode\n");
@@ -577,7 +577,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
} /* end of for loop */
return;
}
-#endif
+#endif // FEATURE_IPACM_HAL end
if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
{
#ifdef FEATURE_IPACM_HAL
@@ -588,7 +588,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
if (is_downstream_set[IPA_IP_v4] == true)
{
IPACMDBG_H("Downstream was set before, adding UL rules.\n");
- if (data_wan_tether->is_sta == false)
+ if (data_wan_tether->backhaul_type == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
handle_wan_up_ex(ext_prop, IPA_IP_v4,
@@ -599,14 +599,14 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
}
}
#else
- if (data_wan_tether->is_sta == false)
+ if (data_wan_tether->backhaul_type == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan_tether->xlat_mux_id);
} else {
handle_wan_up(IPA_IP_v4);
}
-#endif
+#endif // FEATURE_IPACM_HAL end
}
break;
@@ -619,7 +619,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No event data is found.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->backhaul_type,
data_wan_tether->if_index_tether,
IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
#ifndef FEATURE_IPACM_HAL
@@ -628,7 +628,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("IPA_HANDLE_WAN_UP_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
return;
}
-#endif
+#endif // FEATURE_IPACM_HAL end
if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
{
#ifdef FEATURE_IPACM_HAL
@@ -642,7 +642,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("Downstream was set before, adding UL rules.\n");
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)
+ if (data_wan_tether->backhaul_type == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
@@ -654,14 +654,14 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
}
}
#else
- if (data_wan_tether->is_sta == false)
+ if (data_wan_tether->backhaul_type == Q6_WAN)
{
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);
}
-#endif
+#endif // FEATURE_IPACM_HAL end
}
break;
@@ -673,7 +673,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No event data is found.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->backhaul_type,
data_wan_tether->if_index_tether,
IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
#ifndef FEATURE_IPACM_HAL
@@ -682,7 +682,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("IPA_HANDLE_WAN_DOWN_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
return;
}
-#endif
+#endif // FEATURE_IPACM_HAL end
if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
{
#ifdef FEATURE_IPACM_HAL
@@ -693,12 +693,12 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
if(is_downstream_set[IPA_IP_v4] == true)
{
IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
- handle_wan_down(data_wan_tether->is_sta);
+ handle_wan_down(data_wan_tether->backhaul_type);
}
}
#else
- handle_wan_down(data_wan_tether->is_sta);
-#endif
+ handle_wan_down(data_wan_tether->backhaul_type);
+#endif // FEATURE_IPACM_HAL end
}
break;
@@ -710,7 +710,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No event data is found.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->backhaul_type,
data_wan_tether->if_index_tether,
IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
#ifndef FEATURE_IPACM_HAL
@@ -719,7 +719,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("IPA_HANDLE_WAN_DOWN_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num);
return;
}
-#endif
+#endif // FEATURE_IPACM_HAL end
if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
{
#ifdef FEATURE_IPACM_HAL
@@ -732,14 +732,14 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
/* reset usb-client ipv6 rt-rules */
handle_lan_client_reset_rt(IPA_IP_v6);
- handle_wan_down_v6(data_wan_tether->is_sta);
+ handle_wan_down_v6(data_wan_tether->backhaul_type);
}
}
#else
/* reset usb-client ipv6 rt-rules */
handle_lan_client_reset_rt(IPA_IP_v6);
- handle_wan_down_v6(data_wan_tether->is_sta);
-#endif
+ handle_wan_down_v6(data_wan_tether->backhaul_type);
+#endif // FEATURE_IPACM_HAL end
}
break;
@@ -750,6 +750,25 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
if (ipa_interface_index == ipa_if_num)
{
IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n");
+#ifdef FEATURE_IPA_ANDROID
+ if (IPACM_Wan::isXlat() && (data->prefix.iptype == IPA_IP_v4))
+ {
+ /* indicate v4-offload */
+ IPACM_OffloadManager::num_offload_v4_tethered_iface++;
+ IPACMDBG_H("in xlat: update num_offload_v4_tethered_iface %d\n", IPACM_OffloadManager::num_offload_v4_tethered_iface);
+
+ /* xlat not support for 2st tethered iface */
+ if (IPACM_OffloadManager::num_offload_v4_tethered_iface > 1)
+ {
+ IPACMDBG_H("Not support 2st downstream iface %s for xlat, cur: %d\n", dev_name,
+ IPACM_OffloadManager::num_offload_v4_tethered_iface);
+ return;
+ }
+ }
+
+ IPACMDBG_H(" support downstream iface %s, cur %d\n", dev_name,
+ IPACM_OffloadManager::num_offload_v4_tethered_iface);
+#endif
if (data->prefix.iptype < IPA_IP_MAX && is_downstream_set[data->prefix.iptype] == false)
{
IPACMDBG_H("Add downstream for IP iptype %d\n", data->prefix.iptype);
@@ -771,7 +790,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
install_ipv6_prefix_flt_rule(ipv6_prefix);
}
- if (IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
+ if (IPACM_Wan::backhaul_mode == Q6_WAN) /* LTE */
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(data->prefix.iptype);
if (data->prefix.iptype == IPA_IP_v4)
@@ -812,10 +831,10 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
if (data->prefix.iptype == IPA_IP_v4)
{
- handle_wan_down(IPACM_Wan::backhaul_is_sta_mode); /* LTE STA */
+ handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
} else {
handle_lan_client_reset_rt(IPA_IP_v6);
- handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode); /* LTE STA */
+ handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
}
}
}
@@ -823,7 +842,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
break;
}
-#else
+#else // above Andorid
case IPA_HANDLE_WAN_UP:
IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n");
@@ -833,10 +852,10 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No event data is found.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
+ IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
{
- if (data_wan->is_sta == false)
+ if (data_wan->backhaul_type == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan->xlat_mux_id);
@@ -857,12 +876,12 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No event data is found.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
+ IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
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->backhaul_type == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
@@ -882,10 +901,10 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No event data is found.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
+ IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
{
- handle_wan_down(data_wan->is_sta);
+ handle_wan_down(data_wan->backhaul_type);
}
break;
@@ -902,13 +921,13 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
/* reset usb-client ipv6 rt-rules */
handle_lan_client_reset_rt(IPA_IP_v6);
- IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
+ IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
{
- handle_wan_down_v6(data_wan->is_sta);
+ handle_wan_down_v6(data_wan->backhaul_type);
}
break;
-#endif
+#endif // FEATURE_IPA_ANDROID end
case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
{
@@ -919,9 +938,9 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
/* if RNDIS under WIFI mode in MSM, dun add RT rule*/
#ifdef FEATURE_IPACM_HAL
- if(IPACM_Wan::backhaul_is_sta_mode == true) /* WIFI */
+ if(IPACM_Wan::backhaul_mode == WLAN_WAN) /* WIFI */
{
- IPACMDBG_H(" dun construct header and RT-rules for RNDIS-PC in WIFI mode on MSM targets (STA %d) \n", IPACM_Wan::backhaul_is_sta_mode);
+ IPACMDBG_H(" dun construct header and RT-rules for RNDIS-PC in WIFI mode on MSM targets (STA %d) \n", IPACM_Wan::backhaul_mode);
return;
}
#endif
@@ -1051,13 +1070,13 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
case IPA_SW_ROUTING_ENABLE:
IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n");
/* handle software routing enable event*/
- handle_software_routing_enable();
+ handle_software_routing_enable(false);
break;
case IPA_SW_ROUTING_DISABLE:
IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n");
/* handle software routing disable event*/
- handle_software_routing_disable();
+ handle_software_routing_disable(false);
break;
case IPA_CRADLE_WAN_MODE_SWITCH:
@@ -1086,7 +1105,7 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n");
if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num))
{
- if(IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
+ if(IPACM_Wan::backhaul_mode == Q6_WAN) /* LTE */
{
ipa_get_data_stats_resp_msg_v01 *data = (ipa_get_data_stats_resp_msg_v01 *)param;
IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data->ipa_stats_type);
@@ -1193,7 +1212,7 @@ int IPACM_Lan::handle_del_ipv6_addr(ipacm_event_data_all *data)
}
/* delete filter rule for wan_down event for IPv4*/
-int IPACM_Lan::handle_wan_down(bool is_sta_mode)
+int IPACM_Lan::handle_wan_down(ipacm_wan_iface_type backhaul_mode)
{
ipa_fltr_installed_notif_req_msg_v01 flt_index;
int fd;
@@ -1205,7 +1224,15 @@ int IPACM_Lan::handle_wan_down(bool is_sta_mode)
return IPACM_FAILURE;
}
- if(is_sta_mode == false && modem_ul_v4_set == true)
+#ifdef FEATURE_IPA_ANDROID
+ /* indicate v4-offload remove */
+ if (IPACM_Wan::isXlat() && (IPACM_OffloadManager::num_offload_v4_tethered_iface > 0)) {
+ IPACM_OffloadManager::num_offload_v4_tethered_iface--;
+ IPACMDBG_H("num_offload_v4_tethered_iface %d\n", IPACM_OffloadManager::num_offload_v4_tethered_iface);
+ }
+#endif
+
+ if(backhaul_mode == Q6_WAN && modem_ul_v4_set == true)
{
if (num_wan_ul_fl_rule_v4 > MAX_WAN_UL_FILTER_RULES)
{
@@ -1499,6 +1526,7 @@ int IPACM_Lan::handle_private_subnet(ipa_ip_type iptype)
{
struct ipa_flt_rule_add flt_rule_entry;
int i;
+ bool result;
ipa_ioc_add_flt_rule *m_pFilteringTable;
@@ -1562,7 +1590,20 @@ int IPACM_Lan::handle_private_subnet(ipa_ip_type iptype)
IPACMDBG_H("Loop %d 5\n", i);
}
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+
+ if (result == false)
{
IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
free(m_pFilteringTable);
@@ -1591,6 +1632,7 @@ int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type)
struct ipa_flt_rule_add flt_rule_entry;
int len = 0;
ipa_ioc_add_flt_rule *m_pFilteringTable;
+ bool result;
IPACMDBG_H("set WAN interface as default filter rule\n");
@@ -1665,7 +1707,20 @@ int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type)
flt_rule_entry.rule.attrib.u.v4.src_addr = prefix[IPA_IP_v4].v4Addr;
#endif
memcpy(&m_pFilteringTable->rules[0], &flt_rule_entry, sizeof(flt_rule_entry));
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+ if (result == false)
{
IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
free(m_pFilteringTable);
@@ -1743,18 +1798,32 @@ int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type)
/* only offload UL traffic of certain clients */
#ifdef FEATURE_IPACM_HAL
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
- flt_rule_entry.rule.attrib.u.v6.src_addr_mask[0] = ntohl(prefix[IPA_IP_v6].v6Mask[0]);
- flt_rule_entry.rule.attrib.u.v6.src_addr_mask[1] = ntohl(prefix[IPA_IP_v6].v6Mask[1]);
- flt_rule_entry.rule.attrib.u.v6.src_addr_mask[2] = ntohl(prefix[IPA_IP_v6].v6Mask[2]);
- flt_rule_entry.rule.attrib.u.v6.src_addr_mask[3] = ntohl(prefix[IPA_IP_v6].v6Mask[3]);
- flt_rule_entry.rule.attrib.u.v6.src_addr[0] = ntohl(prefix[IPA_IP_v6].v6Addr[0]);
- flt_rule_entry.rule.attrib.u.v6.src_addr[1] = ntohl(prefix[IPA_IP_v6].v6Addr[1]);
- flt_rule_entry.rule.attrib.u.v6.src_addr[2] = ntohl(prefix[IPA_IP_v6].v6Addr[2]);
- flt_rule_entry.rule.attrib.u.v6.src_addr[3] = ntohl(prefix[IPA_IP_v6].v6Addr[3]);
+ flt_rule_entry.rule.attrib.u.v6.src_addr_mask[0] = prefix[IPA_IP_v6].v6Mask[0];
+ flt_rule_entry.rule.attrib.u.v6.src_addr_mask[1] = prefix[IPA_IP_v6].v6Mask[1];
+ flt_rule_entry.rule.attrib.u.v6.src_addr_mask[2] = prefix[IPA_IP_v6].v6Mask[2];
+ flt_rule_entry.rule.attrib.u.v6.src_addr_mask[3] = prefix[IPA_IP_v6].v6Mask[3];
+ flt_rule_entry.rule.attrib.u.v6.src_addr[0] = prefix[IPA_IP_v6].v6Addr[0];
+ flt_rule_entry.rule.attrib.u.v6.src_addr[1] = prefix[IPA_IP_v6].v6Addr[1];
+ flt_rule_entry.rule.attrib.u.v6.src_addr[2] = prefix[IPA_IP_v6].v6Addr[2];
+ flt_rule_entry.rule.attrib.u.v6.src_addr[3] = prefix[IPA_IP_v6].v6Addr[3];
#endif
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+
+ if (result == false)
{
IPACMERR("Error Adding Filtering rule, aborting...\n");
free(m_pFilteringTable);
@@ -1817,6 +1886,7 @@ int IPACM_Lan::handle_wan_up_ex(ipacm_ext_prop *ext_prop, ipa_ip_type iptype, ui
ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id);
modem_ul_v6_set = true;
} else if (iptype ==IPA_IP_v4 && modem_ul_v4_set == false) {
+ IPACMDBG_H("check getXlat_Mux_Id:%d\n", IPACM_Wan::getXlat_Mux_Id());
IPACMDBG_H("IPA_IP_v4 xlat_mux_id: %d, modem_ul_v4_set %d\n", xlat_mux_id, modem_ul_v4_set);
ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id);
modem_ul_v4_set = true;
@@ -2401,6 +2471,15 @@ int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptyp
get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[v6_num] = rt_rule->rules[0].rt_rule_hdl;
IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[v6_num], iptype);
+
+ /* send client-v6 info to pcie modem only with global ipv6 with tx_index = 1 one time*/
+ if(is_global_ipv6_addr(get_client_memptr(eth_client, eth_index)->v6_addr[v6_num]) && (IPACM_Wan::backhaul_mode == Q6_MHI_WAN))
+ {
+ if (add_connection(eth_index, v6_num))
+ {
+ IPACMERR("PCIE filter rule addition failed! (%d-client) %d v6-entry\n",eth_index, v6_num);
+ }
+ }
}
}
@@ -2928,8 +3007,8 @@ int IPACM_Lan::handle_down_evt()
/* delete wan filter rule */
if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL)
{
- IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
- handle_wan_down(IPACM_Wan::backhaul_is_sta_mode);
+ IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_mode);
+ handle_wan_down(IPACM_Wan::backhaul_mode);
#ifdef FEATURE_IPA_ANDROID
#ifndef FEATURE_IPACM_HAL
/* Clean-up tethered-iface list */
@@ -2940,8 +3019,8 @@ int IPACM_Lan::handle_down_evt()
if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL)
{
- IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
- handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode);
+ IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_mode);
+ handle_wan_down_v6(IPACM_Wan::backhaul_mode);
#ifdef FEATURE_IPA_ANDROID
/* Clean-up tethered-iface list */
IPACM_Wan::delete_tether_iface(IPA_IP_v6, ipa_if_num);
@@ -3149,7 +3228,7 @@ fail:
/* check software routing fl rule hdl */
if (softwarerouting_act == true && rx_prop != NULL)
{
- handle_software_routing_disable();
+ handle_software_routing_disable(false);
}
if (odu_route_rule_v4_hdl != NULL)
@@ -3205,7 +3284,8 @@ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptyp
int fd;
int i, index, eq_index;
uint32_t value = 0;
- uint8_t qmap_id;
+ uint8_t qmap_id, xlat_debug;
+ bool result;
IPACMDBG_H("Set modem UL flt rules\n");
@@ -3263,13 +3343,14 @@ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptyp
flt_index.retain_header = 0;
flt_index.embedded_call_mux_id_valid = 1;
qmap_id = IPACM_Iface::ipacmcfg->GetQmapId();
+ xlat_debug = IPACM_Wan::getXlat_Mux_Id();
flt_index.embedded_call_mux_id = qmap_id;
#ifndef FEATURE_IPA_V3
- IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d\n",
- flt_index.source_pipe_index, flt_index.filter_index_list_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id);
+ IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d, xlat_mux id: %d, wan-debug %d\n",
+ flt_index.source_pipe_index, flt_index.filter_index_list_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id, xlat_mux_id, xlat_debug);
#else /* defined (FEATURE_IPA_V3) */
- IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d\n",
- flt_index.source_pipe_index, flt_index.rule_id_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id);
+ IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d, xlat_mux id: %d, wan-debug %d\n",
+ flt_index.source_pipe_index, flt_index.rule_id_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id, xlat_mux_id, xlat_debug);
#endif
len = sizeof(struct ipa_ioc_add_flt_rule) + prop->num_ext_props * sizeof(struct ipa_flt_rule_add);
pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
@@ -3340,6 +3421,13 @@ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptyp
}
/* Handle XLAT configuration */
+ /* temp wa to reset xlat_mux_id to qmap_id if it's xlat call */
+ if (IPACM_Wan::isXlat() && (iptype == IPA_IP_v4))
+ {
+ IPACMDBG_H("WA to replace xlat_mux_id %d with qmap_id: %d\n", xlat_mux_id, qmap_id);
+ xlat_mux_id = qmap_id;
+ }
+
if ((iptype == IPA_IP_v4) && prop->prop[cnt].is_xlat_rule && (xlat_mux_id != 0))
{
/* fill the value of meta-data */
@@ -3490,7 +3578,20 @@ int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptyp
goto fail;
}
- if(false == m_filtering.AddFilteringRule(pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(pFilteringTable);
+#endif
+
+ if(result == false)
{
IPACMERR("Error Adding RuleTable to Filtering, aborting...\n");
ret = IPACM_FAILURE;
@@ -3532,7 +3633,7 @@ fail:
return ret;
}
-int IPACM_Lan::handle_wan_down_v6(bool is_sta_mode)
+int IPACM_Lan::handle_wan_down_v6(ipacm_wan_iface_type backhaul_mode)
{
ipa_fltr_installed_notif_req_msg_v01 flt_index;
int fd;
@@ -3548,7 +3649,7 @@ int IPACM_Lan::handle_wan_down_v6(bool is_sta_mode)
memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
- if(is_sta_mode == false && modem_ul_v6_set == true)
+ if(backhaul_mode == Q6_WAN && modem_ul_v6_set == true)
{
if (num_wan_ul_fl_rule_v6 > MAX_WAN_UL_FILTER_RULES)
{
@@ -3786,6 +3887,7 @@ 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;
+ bool result;
if(rx_prop != NULL)
{
@@ -3822,7 +3924,20 @@ int IPACM_Lan::install_ipv4_icmp_flt_rule()
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)
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(flt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(flt_rule);
+ }
+#else
+ result = m_filtering.AddFilteringRule(flt_rule);
+#endif
+
+ if (result == false)
{
IPACMERR("Error Adding Filtering rule, aborting...\n");
free(flt_rule);
@@ -3845,6 +3960,7 @@ 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;
+ bool result;
if(rx_prop != NULL)
{
@@ -3880,7 +3996,20 @@ int IPACM_Lan::install_ipv6_icmp_flt_rule()
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)
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(flt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(flt_rule);
+ }
+#else
+ result = m_filtering.AddFilteringRule(flt_rule);
+#endif
+
+ if (result == false)
{
IPACMERR("Error Adding Filtering rule, aborting...\n");
free(flt_rule);
@@ -3913,6 +4042,7 @@ int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)
int i, len, res = IPACM_SUCCESS;
struct ipa_flt_rule_add flt_rule;
ipa_ioc_add_flt_rule* pFilteringTable;
+ bool result;
len = sizeof(struct ipa_ioc_add_flt_rule) + IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(struct ipa_flt_rule_add);
@@ -3956,7 +4086,20 @@ int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)
memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add));
}
- if (false == m_filtering.AddFilteringRule(pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(pFilteringTable);
+#endif
+
+ if (result == false)
{
IPACMERR("Error adding dummy private subnet v4 flt rule\n");
res = IPACM_FAILURE;
@@ -4081,6 +4224,7 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix)
int len;
struct ipa_ioc_add_flt_rule* flt_rule;
struct ipa_flt_rule_add flt_rule_entry;
+ bool result;
if(rx_prop != NULL)
{
@@ -4123,7 +4267,20 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix)
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)
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(flt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(flt_rule);
+ }
+#else
+ result = m_filtering.AddFilteringRule(flt_rule);
+#endif
+
+ if (result == false)
{
IPACMERR("Error Adding Filtering rule, aborting...\n");
free(flt_rule);
@@ -4575,7 +4732,7 @@ int IPACM_Lan::set_tether_client(wan_ioctl_set_tether_client_pipe *tether_client
}
}
- ret = ioctl(fd_wwan_ioctl, WAN_IOC_SET_TETHER_CLIENT_PIPE, &tether_client);
+ ret = ioctl(fd_wwan_ioctl, WAN_IOC_SET_TETHER_CLIENT_PIPE, tether_client);
if(ret != 0)
{
IPACMERR("Failed set tether-client-pipe %p with ret %d\n ", &tether_client, ret);
@@ -4966,6 +5123,7 @@ int IPACM_Lan::eth_bridge_add_flt_rule(uint8_t *mac, uint32_t rt_tbl_hdl, ipa_ip
int len;
struct ipa_flt_rule_add flt_rule_entry;
struct ipa_ioc_add_flt_rule_after *pFilteringTable = NULL;
+ bool result;
if (rx_prop == NULL || tx_prop == NULL)
{
@@ -5014,7 +5172,19 @@ int IPACM_Lan::eth_bridge_add_flt_rule(uint8_t *mac, uint32_t rt_tbl_hdl, ipa_ip
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))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ result = m_filtering.AddFilteringRuleAfter_hw_index(pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRuleAfter(pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRuleAfter(pFilteringTable);
+#endif
+ if (result == false)
{
IPACMERR("Failed to add client filtering rules.\n");
res = IPACM_FAILURE;
@@ -5892,6 +6062,7 @@ int IPACM_Lan::add_tcp_syn_flt_rule(ipa_ip_type iptype)
int len;
struct ipa_flt_rule_add flt_rule_entry;
ipa_ioc_add_flt_rule *m_pFilteringTable;
+ bool result;
if(rx_prop == NULL)
{
@@ -5936,8 +6107,20 @@ int IPACM_Lan::add_tcp_syn_flt_rule(ipa_ip_type iptype)
}
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
- if(false == m_filtering.AddFilteringRule(m_pFilteringTable))
+ if(result == false)
{
IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
free(m_pFilteringTable);
@@ -5997,7 +6180,7 @@ int IPACM_Lan::add_tcp_syn_flt_rule_l2tp(ipa_ip_type inner_ip_type)
}
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry));
-
+ /* no need for hw counters */
if(false == m_filtering.AddFilteringRule(m_pFilteringTable))
{
IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
@@ -6009,3 +6192,147 @@ int IPACM_Lan::add_tcp_syn_flt_rule_l2tp(ipa_ip_type inner_ip_type)
free(m_pFilteringTable);
return IPACM_SUCCESS;
}
+
+int IPACM_Lan::add_connection(int client_index, int v6_num)
+{
+ int len, res = IPACM_SUCCESS;
+ uint8_t mux_id;
+ ipa_ioc_add_flt_rule *pFilteringTable = NULL;
+ int fd;
+
+ mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
+ /* contruct filter rules to pcie modem */
+ struct ipa_flt_rule_add flt_rule_entry;
+ ipa_ioc_generate_flt_eq flt_eq;
+
+ IPACMDBG("\n");
+ len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
+ pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->global = false;
+ pFilteringTable->ip = IPA_IP_v6;
+ pFilteringTable->num_rules = (uint8_t)1;
+
+ /* Configuring Filtering Rule */
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
+ flt_rule_entry.at_rear = true;
+ flt_rule_entry.flt_rule_hdl = -1;
+ flt_rule_entry.status = -1;
+
+ flt_rule_entry.rule.retain_hdr = 1;
+ flt_rule_entry.rule.to_uc = 0;
+ flt_rule_entry.rule.eq_attrib_type = 1;
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+#ifdef FEATURE_IPA_V3
+ flt_rule_entry.rule.hashable = true;
+#endif
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
+ flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = get_client_memptr(eth_client, client_index)->v6_addr[v6_num][0];
+ flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = get_client_memptr(eth_client, client_index)->v6_addr[v6_num][1];
+ flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = get_client_memptr(eth_client, client_index)->v6_addr[v6_num][2];
+ flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = get_client_memptr(eth_client, client_index)->v6_addr[v6_num][3];
+ 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] = 0xFFFFFFFF;
+ flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
+
+ IPACMDBG_H("ipv6 address got: 0x%x:%x:%x:%x\n", get_client_memptr(eth_client, client_index)->v6_addr[v6_num][0],
+ get_client_memptr(eth_client, client_index)->v6_addr[v6_num][1],
+ get_client_memptr(eth_client, client_index)->v6_addr[v6_num][2],
+ get_client_memptr(eth_client, client_index)->v6_addr[v6_num][3]);
+
+ /* change to network order for modem */
+ change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib);
+
+ memset(&flt_eq, 0, sizeof(flt_eq));
+ memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
+ flt_eq.ip = IPA_IP_v6;
+
+ fd = open(IPA_DEVICE_NAME, O_RDWR);
+ if (fd < 0)
+ {
+ IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
+ free(pFilteringTable);
+ return IPACM_FAILURE;
+ }
+
+ if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
+ {
+ IPACMERR("Failed to get eq_attrib\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &flt_eq.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+ memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+
+ if(false == m_filtering.AddOffloadFilteringRule(pFilteringTable, mux_id, 0))
+ {
+ IPACMERR("Failed to install WAN DL filtering table.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ get_client_memptr(eth_client, client_index)->v6_rt_rule_id[v6_num] = pFilteringTable->rules[0].flt_rule_hdl;
+ IPACMDBG_H("%d-st client v6_num %d: id handle 0x%x\n", client_index, v6_num, get_client_memptr(eth_client, client_index)->v6_rt_rule_id[v6_num]);
+fail:
+ close(fd);
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int IPACM_Lan::del_connection(int client_index, int v6_num)
+{
+ int len, res = IPACM_SUCCESS;
+ ipa_ioc_del_flt_rule *pFilteringTable = NULL;
+
+ struct ipa_flt_rule_del flt_rule_entry;
+
+ IPACMDBG("\n");
+ len = sizeof(struct ipa_ioc_del_flt_rule) + sizeof(struct ipa_flt_rule_del);
+ pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = IPA_IP_v6;
+ pFilteringTable->num_hdls = (uint8_t)1;
+
+ /* Configuring Software-Routing Filtering Rule */
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
+ flt_rule_entry.hdl = get_client_memptr(eth_client, client_index)->v6_rt_rule_id[v6_num];
+
+ memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
+
+ if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Failed to install WAN DL filtering table.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ get_client_memptr(eth_client, client_index)->v6_rt_rule_id[v6_num] = 0;
+
+fail:
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index 04f8a89..afdf26d 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -113,6 +113,12 @@ int ipa_reset();
int ipa_query_wlan_client();
#endif
+
+/* support ipa-hw-index-counters */
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+int ipa_reset_hw_index_counter();
+#endif
+
#ifdef FEATURE_IPACM_HAL
IPACM_OffloadManager* OffloadMng;
HAL *hal;
@@ -240,6 +246,10 @@ void* ipa_driver_msg_notifier(void *param)
#endif
struct ipa_get_data_stats_resp_msg_v01 event_data_stats;
struct ipa_get_apn_data_stats_resp_msg_v01 event_network_stats;
+#ifdef IPA_RT_SUPPORT_COAL
+ struct ipa_coalesce_info coalesce_info;
+#endif
+
#ifdef FEATURE_IPACM_HAL
IPACM_OffloadManager* OffloadMng;
#endif
@@ -821,6 +831,40 @@ void* ipa_driver_msg_notifier(void *param)
evt_data.evt_data = mapping;
break;
#endif
+#ifdef IPA_RT_SUPPORT_COAL
+ case IPA_COALESCE_ENABLE:
+ memcpy(&coalesce_info, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_coalesce_info));
+ IPACMDBG_H("Received IPA_COALESCE_ENABLE qmap-id:%d tcp:%d, udp%d\n",
+ coalesce_info.qmap_id, coalesce_info.tcp_enable, coalesce_info.udp_enable);
+ if (coalesce_info.qmap_id >=IPA_MAX_NUM_SW_PDNS)
+ {
+ IPACMERR("qmap_id (%d) beyond the Max range (%d), abort\n",
+ coalesce_info.qmap_id, IPA_MAX_NUM_SW_PDNS);
+ return NULL;
+ }
+ IPACM_Wan::coalesce_config(coalesce_info.qmap_id, coalesce_info.tcp_enable, coalesce_info.udp_enable);
+ /* Notify all LTE instance to do RSC configuration */
+ evt_data.event = IPA_COALESCE_NOTICE;
+ evt_data.evt_data = NULL;
+ break;
+
+ case IPA_COALESCE_DISABLE:
+ memcpy(&coalesce_info, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_coalesce_info));
+ IPACMDBG_H("Received IPA_COALESCE_DISABLE qmap-id:%d tcp:%d, udp%d\n",
+ coalesce_info.qmap_id, coalesce_info.tcp_enable, coalesce_info.udp_enable);
+ if (coalesce_info.qmap_id >=IPA_MAX_NUM_SW_PDNS)
+ {
+ IPACMERR("qmap_id (%d) beyond the Max range (%d), abort\n",
+ coalesce_info.qmap_id, IPA_MAX_NUM_SW_PDNS);
+ return NULL;
+ }
+ IPACM_Wan::coalesce_config(coalesce_info.qmap_id, false, false);
+ /* Notify all LTE instance to do RSC configuration */
+ evt_data.event = IPA_COALESCE_NOTICE;
+ evt_data.evt_data = NULL;
+ break;
+#endif
+
default:
IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type);
continue;
@@ -894,6 +938,11 @@ int main(int argc, char **argv)
ipa_reset();
#endif
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ IPACMDBG_H("Configure IPA-HW index-counter\n");
+ ipa_reset_hw_index_counter();
+#endif
+
neigh = new IPACM_Neighbor();
ifacemgr = new IPACM_IfaceManager();
#ifdef FEATURE_IPACM_HAL
@@ -912,6 +961,8 @@ int main(int argc, char **argv)
IPACMDBG_H("Staring IPA main\n");
IPACMDBG_H("ipa_cmdq_successful\n");
+ /* reset coalesce settings */
+ IPACM_Wan::coalesce_config_reset();
RegisterForSignals();
@@ -1120,3 +1171,51 @@ int ipa_reset()
return IPACM_SUCCESS;
}
#endif
+
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+int ipa_reset_hw_index_counter()
+{
+ int fd = -1;
+ struct ipa_ioc_flt_rt_counter_alloc fnr_counters;
+ struct ipa_ioc_fnr_index_info fnr_info;
+
+ if ((fd = open(IPA_DEVICE_NAME, O_RDWR)) < 0) {
+ IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
+ return IPACM_FAILURE;
+ }
+
+ memset(&fnr_counters, 0, sizeof(fnr_counters));
+ fnr_counters.hw_counter.num_counters = 4;
+ fnr_counters.hw_counter.allow_less = false;
+ fnr_counters.sw_counter.num_counters = 4;
+ fnr_counters.sw_counter.allow_less = false;
+ IPACMDBG_H("Allocating %d hw counters and %d sw counters\n",
+ fnr_counters.hw_counter.num_counters, fnr_counters.sw_counter.num_counters);
+
+ if (ioctl(fd, IPA_IOC_FNR_COUNTER_ALLOC, &fnr_counters) < 0) {
+ IPACMERR("IPA_IOC_FNR_COUNTER_ALLOC call failed: %s \n", strerror(errno));
+ close(fd);
+ return IPACM_FAILURE;
+ }
+
+ IPACMDBG_H("hw-counter start offset %d, sw-counter start offset %d\n",
+ fnr_counters.hw_counter.start_id, fnr_counters.sw_counter.start_id);
+ IPACM_Iface::ipacmcfg->hw_fnr_stats_support = true;
+ IPACM_Iface::ipacmcfg->hw_counter_offset = fnr_counters.hw_counter.start_id;
+ IPACM_Iface::ipacmcfg->sw_counter_offset = fnr_counters.sw_counter.start_id;
+
+ /* set FNR counter info */
+ memset(&fnr_info, 0, sizeof(fnr_info));
+ fnr_info.hw_counter_offset = fnr_counters.hw_counter.start_id;
+ fnr_info.sw_counter_offset = fnr_counters.sw_counter.start_id;
+
+ if (ioctl(fd, IPA_IOC_SET_FNR_COUNTER_INFO, &fnr_info) < 0) {
+ IPACMERR("IPA_IOC_SET_FNR_COUNTER_INFO call failed: %s \n", strerror(errno));
+ close(fd);
+ return IPACM_FAILURE;
+ }
+
+ close(fd);
+ return IPACM_SUCCESS;
+}
+#endif
diff --git a/ipacm/src/IPACM_OffloadManager.cpp b/ipacm/src/IPACM_OffloadManager.cpp
index 1359d49..7919413 100644
--- a/ipacm/src/IPACM_OffloadManager.cpp
+++ b/ipacm/src/IPACM_OffloadManager.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -51,6 +51,7 @@ const char *IPACM_OffloadManager::DEVICE_NAME = "/dev/wwan_ioctl";
/* NatApp class Implementation */
IPACM_OffloadManager *IPACM_OffloadManager::pInstance = NULL;
+int IPACM_OffloadManager::num_offload_v4_tethered_iface = 0;
IPACM_OffloadManager::IPACM_OffloadManager()
{
@@ -237,44 +238,49 @@ RET IPACM_OffloadManager::addDownstream(const char * downstream_name, const Pref
/* copy to the cache */
for(int i = 0; i < MAX_EVENT_CACHE ;i++)
{
- if(event_cache[latest_cache_index].valid == false)
+ if (latest_cache_index >= 0)
{
- //do the copy
- event_cache[latest_cache_index].valid = true;
- event_cache[latest_cache_index].event = IPA_DOWNSTREAM_ADD;
- memcpy(event_cache[latest_cache_index].dev_name, downstream_name, sizeof(event_cache[latest_cache_index].dev_name));
- memcpy(&event_cache[latest_cache_index].prefix_cache, &prefix, sizeof(event_cache[latest_cache_index].prefix_cache));
- if (prefix.fam == V4) {
- IPACMDBG_H("cache event(%d) subnet info v4Addr (%x) v4Mask (%x) dev(%s) on entry (%d)\n",
- event_cache[latest_cache_index].event,
- event_cache[latest_cache_index].prefix_cache.v4Addr,
- event_cache[latest_cache_index].prefix_cache.v4Mask,
- event_cache[latest_cache_index].dev_name,
- latest_cache_index);
- } else {
- IPACMDBG_H("cache event (%d) v6Addr: %08x:%08x:%08x:%08x \n",
- event_cache[latest_cache_index].event,
- event_cache[latest_cache_index].prefix_cache.v6Addr[0],
- event_cache[latest_cache_index].prefix_cache.v6Addr[1],
- event_cache[latest_cache_index].prefix_cache.v6Addr[2],
- event_cache[latest_cache_index].prefix_cache.v6Addr[3]);
- IPACMDBG_H("subnet v6Mask: %08x:%08x:%08x:%08x dev(%s) on entry(%d), \n",
- event_cache[latest_cache_index].prefix_cache.v6Mask[0],
- event_cache[latest_cache_index].prefix_cache.v6Mask[1],
- event_cache[latest_cache_index].prefix_cache.v6Mask[2],
- event_cache[latest_cache_index].prefix_cache.v6Mask[3],
- event_cache[latest_cache_index].dev_name,
- latest_cache_index);
+ if(event_cache[latest_cache_index].valid == false)
+ {
+ //do the copy
+ event_cache[latest_cache_index].valid = true;
+ event_cache[latest_cache_index].event = IPA_DOWNSTREAM_ADD;
+ memcpy(event_cache[latest_cache_index].dev_name, downstream_name,
+ sizeof(event_cache[latest_cache_index].dev_name));
+ memcpy(&event_cache[latest_cache_index].prefix_cache, &prefix,
+ sizeof(event_cache[latest_cache_index].prefix_cache));
+ if (prefix.fam == V4) {
+ IPACMDBG_H("cache event(%d) subnet info v4Addr (%x) v4Mask (%x) dev(%s) on entry (%d)\n",
+ event_cache[latest_cache_index].event,
+ event_cache[latest_cache_index].prefix_cache.v4Addr,
+ event_cache[latest_cache_index].prefix_cache.v4Mask,
+ event_cache[latest_cache_index].dev_name,
+ latest_cache_index);
+ } else {
+ IPACMDBG_H("cache event (%d) v6Addr: %08x:%08x:%08x:%08x \n",
+ event_cache[latest_cache_index].event,
+ event_cache[latest_cache_index].prefix_cache.v6Addr[0],
+ event_cache[latest_cache_index].prefix_cache.v6Addr[1],
+ event_cache[latest_cache_index].prefix_cache.v6Addr[2],
+ event_cache[latest_cache_index].prefix_cache.v6Addr[3]);
+ IPACMDBG_H("subnet v6Mask: %08x:%08x:%08x:%08x dev(%s) on entry(%d), \n",
+ event_cache[latest_cache_index].prefix_cache.v6Mask[0],
+ event_cache[latest_cache_index].prefix_cache.v6Mask[1],
+ event_cache[latest_cache_index].prefix_cache.v6Mask[2],
+ event_cache[latest_cache_index].prefix_cache.v6Mask[3],
+ event_cache[latest_cache_index].dev_name,
+ latest_cache_index);
+ }
+ latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
+ break;
}
latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
- break;
}
- latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
if(i == MAX_EVENT_CACHE - 1)
{
IPACMDBG_H(" run out of event cache (%d)\n", i);
- return FAIL_HARDWARE;
- }
+ return FAIL_HARDWARE;
+ }
}
return SUCCESS;
@@ -412,37 +418,43 @@ RET IPACM_OffloadManager::setUpstream(const char *upstream_name, const Prefix& g
/* copy to the cache */
for(int i = 0; i < MAX_EVENT_CACHE ;i++)
{
- if(event_cache[latest_cache_index].valid == false)
+ if (latest_cache_index >= 0)
{
- //do the copy
- event_cache[latest_cache_index].valid = true;
- event_cache[latest_cache_index].event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
- memcpy(event_cache[latest_cache_index].dev_name, upstream_name, sizeof(event_cache[latest_cache_index].dev_name));
- memcpy(&event_cache[latest_cache_index].prefix_cache, &gw_addr_v4, sizeof(event_cache[latest_cache_index].prefix_cache));
- memcpy(&event_cache[latest_cache_index].prefix_cache_v6, &gw_addr_v6, sizeof(event_cache[latest_cache_index].prefix_cache_v6));
- if (gw_addr_v4.fam == V4) {
- IPACMDBG_H("cache event(%d) ipv4 gateway: (%x) dev(%s) on entry (%d)\n",
- event_cache[latest_cache_index].event,
- event_cache[latest_cache_index].prefix_cache.v4Addr,
- event_cache[latest_cache_index].dev_name,
- latest_cache_index);
- }
-
- if (gw_addr_v6.fam == V6)
- {
- IPACMDBG_H("cache event (%d) ipv6 gateway: %08x:%08x:%08x:%08x dev(%s) on entry(%d)\n",
- event_cache[latest_cache_index].event,
- event_cache[latest_cache_index].prefix_cache_v6.v6Addr[0],
- event_cache[latest_cache_index].prefix_cache_v6.v6Addr[1],
- event_cache[latest_cache_index].prefix_cache_v6.v6Addr[2],
- event_cache[latest_cache_index].prefix_cache_v6.v6Addr[3],
- event_cache[latest_cache_index].dev_name,
- latest_cache_index);
+ if(event_cache[latest_cache_index].valid == false)
+ {
+ //do the copy
+ event_cache[latest_cache_index].valid = true;
+ event_cache[latest_cache_index].event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
+ memcpy(event_cache[latest_cache_index].dev_name, upstream_name,
+ sizeof(event_cache[latest_cache_index].dev_name));
+ memcpy(&event_cache[latest_cache_index].prefix_cache, &gw_addr_v4,
+ sizeof(event_cache[latest_cache_index].prefix_cache));
+ memcpy(&event_cache[latest_cache_index].prefix_cache_v6, &gw_addr_v6,
+ sizeof(event_cache[latest_cache_index].prefix_cache_v6));
+ if (gw_addr_v4.fam == V4) {
+ IPACMDBG_H("cache event(%d) ipv4 gateway: (%x) dev(%s) on entry (%d)\n",
+ event_cache[latest_cache_index].event,
+ event_cache[latest_cache_index].prefix_cache.v4Addr,
+ event_cache[latest_cache_index].dev_name,
+ latest_cache_index);
+ }
+
+ if (gw_addr_v6.fam == V6)
+ {
+ IPACMDBG_H("cache event (%d) ipv6 gateway: %08x:%08x:%08x:%08x dev(%s) on entry(%d)\n",
+ event_cache[latest_cache_index].event,
+ event_cache[latest_cache_index].prefix_cache_v6.v6Addr[0],
+ event_cache[latest_cache_index].prefix_cache_v6.v6Addr[1],
+ event_cache[latest_cache_index].prefix_cache_v6.v6Addr[2],
+ event_cache[latest_cache_index].prefix_cache_v6.v6Addr[3],
+ event_cache[latest_cache_index].dev_name,
+ latest_cache_index);
+ }
+ latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
+ break;
}
latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
- break;
}
- latest_cache_index = (latest_cache_index + 1)% MAX_EVENT_CACHE;
if(i == MAX_EVENT_CACHE - 1)
{
IPACMDBG_H(" run out of event cache (%d) \n", i);
@@ -566,6 +578,7 @@ RET IPACM_OffloadManager::stopAllOffload()
memset(event_cache, 0, MAX_EVENT_CACHE*sizeof(framework_event_cache));
latest_cache_index = 0;
valid_ifaces.clear();
+ IPACM_OffloadManager::num_offload_v4_tethered_iface = 0;
return result;
}
@@ -590,7 +603,7 @@ RET IPACM_OffloadManager::setQuota(const char * upstream_name /* upstream */, ui
return FAIL_INPUT_CHECK;
}
- IPACMDBG_H("SET_DATA_QUOTA %s %llu", quota.interface_name, (long long)mb);
+ IPACMDBG_H("SET_DATA_QUOTA %s %llu\n", quota.interface_name, (long long)mb);
rc = ioctl(fd, WAN_IOC_SET_DATA_QUOTA, &quota);
@@ -765,12 +778,14 @@ IPACM_OffloadManager* IPACM_OffloadManager::GetInstance()
bool IPACM_OffloadManager::search_framwork_cache(char * interface_name)
{
bool rel = false;
+ bool cache_need = false;
/* IPACM needs to kee old FDs, can't clear */
IPACMDBG_H("check netdev(%s)\n", interface_name);
for(int i = 0; i < MAX_EVENT_CACHE ;i++)
{
+ cache_need = false;
if(event_cache[i].valid == true)
{
//do the compare
@@ -780,14 +795,40 @@ bool IPACM_OffloadManager::search_framwork_cache(char * interface_name)
{
IPACMDBG_H("found netdev (%s) in entry (%d) with event (%d)\n", interface_name, i, event_cache[i].event);
/* post event again */
- if (event_cache[i].event == IPA_DOWNSTREAM_ADD)
+ if (event_cache[i].event == IPA_DOWNSTREAM_ADD) {
+ /* check if downsteam netdev driver finished its configuration on IPA-HW for ipv4 and ipv6 */
+ if (event_cache[i].prefix_cache.fam == V4 && IPACM_Iface::ipacmcfg->CheckNatIfaces(event_cache[i].dev_name, IPA_IP_v4))
+ cache_need = true;
+ if (event_cache[i].prefix_cache.fam == V6 && IPACM_Iface::ipacmcfg->CheckNatIfaces(event_cache[i].dev_name, IPA_IP_v6))
+ cache_need = true;
+ if (cache_need) {
+ IPACMDBG_H("still need cache (%d), index (%d) ip-family (%d)\n", cache_need, i, event_cache[i].prefix_cache.fam);
+ break;
+ } else {
+ IPACMDBG_H("no need cache (%d), handling it event (%d)\n", cache_need, event_cache[i].event);
addDownstream(interface_name, event_cache[i].prefix_cache);
- else if (event_cache[i].event == IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT)
+ }
+ } else if (event_cache[i].event == IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT) {
+ /* check if upstream netdev driver finished its configuration on IPA-HW for ipv4 and ipv6 */
+ if (event_cache[i].prefix_cache.fam == V4 && IPACM_Iface::ipacmcfg->CheckNatIfaces(event_cache[i].dev_name, IPA_IP_v4))
+ cache_need = true;
+ if (event_cache[i].prefix_cache_v6.fam == V6 && IPACM_Iface::ipacmcfg->CheckNatIfaces(event_cache[i].dev_name, IPA_IP_v6))
+ cache_need = true;
+ if (cache_need) {
+ IPACMDBG_H("still need cache (%d), index (%d)\n", cache_need, i);
+ break;
+ } else {
+ IPACMDBG_H("no need cache (%d), handling it event (%d)\n", cache_need, event_cache[i].event);
setUpstream(interface_name, event_cache[i].prefix_cache, event_cache[i].prefix_cache_v6);
- else
- IPACMERR("wrong event cached (%d)", event_cache[i].event);
+ }
+ } else {
+ IPACMERR("wrong event cached (%d) index (%d)\n", event_cache[i].event, i);
+ }
+
+ /* reset entry */
event_cache[i].valid = false;
rel = true;
+ IPACMDBG_H("reset entry (%d)", i);
}
}
}
diff --git a/ipacm/src/IPACM_Routing.cpp b/ipacm/src/IPACM_Routing.cpp
index 2a2555a..654a0f9 100644
--- a/ipacm/src/IPACM_Routing.cpp
+++ b/ipacm/src/IPACM_Routing.cpp
@@ -112,6 +112,115 @@ bool IPACM_Routing::AddRoutingRule(struct ipa_ioc_add_rt_rule *ruleTable)
return true;
}
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+bool IPACM_Routing::AddRoutingRule_hw_index(struct ipa_ioc_add_rt_rule *ruleTable, int hw_counter_index)
+{
+ int retval = 0, cnt = 0, len = 0;
+ struct ipa_ioc_add_rt_rule_v2 *ruleTable_v2;
+ struct ipa_rt_rule_add_v2 rt_rule_entry;
+ bool ret = true;
+
+ IPACMDBG("Printing routing add attributes\n");
+ IPACMDBG("ip type: %d\n", ruleTable->ip);
+ IPACMDBG("rt tbl type: %s\n", ruleTable->rt_tbl_name);
+ IPACMDBG("Number of rules: %d\n", ruleTable->num_rules);
+ IPACMDBG("commit value: %d\n", ruleTable->commit);
+
+ /* change to v2 format*/
+ len = sizeof(struct ipa_ioc_add_rt_rule_v2);
+ ruleTable_v2 = (struct ipa_ioc_add_rt_rule_v2*)malloc(len);
+ if (ruleTable_v2 == NULL)
+ {
+ IPACMERR("Error Locate ipa_ioc_add_rt_rule_v2 memory...\n");
+ return false;
+ }
+ memset(ruleTable_v2, 0, len);
+ ruleTable_v2->rules = (uint64_t)calloc(ruleTable->num_rules, sizeof(struct ipa_rt_rule_add_v2));
+ if (!ruleTable_v2->rules) {
+ IPACMERR("Failed to allocate memory for routing rules\n");
+ ret = false;
+ goto fail_tbl;
+ }
+
+ ruleTable_v2->commit = ruleTable->commit;
+ ruleTable_v2->ip = ruleTable->ip;
+ ruleTable_v2->num_rules = ruleTable->num_rules;
+ ruleTable_v2->rule_add_size = sizeof(struct ipa_rt_rule_add_v2);
+ memcpy(ruleTable_v2->rt_tbl_name,
+ ruleTable->rt_tbl_name,
+ sizeof(ruleTable_v2->rt_tbl_name));
+
+ for (cnt=0; cnt < ruleTable->num_rules; cnt++)
+ {
+ memset(&rt_rule_entry, 0, sizeof(struct ipa_rt_rule_add_v2));
+ rt_rule_entry.at_rear = ruleTable->rules[cnt].at_rear;
+ rt_rule_entry.rule.dst = ruleTable->rules[cnt].rule.dst;
+ rt_rule_entry.rule.hdr_hdl = ruleTable->rules[cnt].rule.hdr_hdl;
+ rt_rule_entry.rule.hdr_proc_ctx_hdl = ruleTable->rules[cnt].rule.hdr_proc_ctx_hdl;
+ rt_rule_entry.rule.max_prio = ruleTable->rules[cnt].rule.max_prio;
+ rt_rule_entry.rule.hashable = ruleTable->rules[cnt].rule.hashable;
+ rt_rule_entry.rule.retain_hdr = ruleTable->rules[cnt].rule.retain_hdr;
+ rt_rule_entry.rule.coalesce = ruleTable->rules[cnt].rule.coalesce;
+ memcpy(&rt_rule_entry.rule.attrib,
+ &ruleTable->rules[cnt].rule.attrib,
+ sizeof(rt_rule_entry.rule.attrib));
+ IPACMDBG("RT rule:%d attrib mask: 0x%x\n", cnt,
+ ruleTable->rules[cnt].rule.attrib.attrib_mask);
+ /* 0 means disable hw-counter-sats */
+ if (hw_counter_index != 0)
+ {
+ rt_rule_entry.rule.enable_stats = 1;
+ rt_rule_entry.rule.cnt_idx = hw_counter_index;
+ }
+
+ /* copy to v2 table*/
+ memcpy((void *)(ruleTable_v2->rules + (cnt * sizeof(struct ipa_rt_rule_add_v2))),
+ &rt_rule_entry, sizeof(rt_rule_entry));
+ }
+
+ retval = ioctl(m_fd, IPA_IOC_ADD_RT_RULE_V2, ruleTable_v2);
+ if (retval != 0)
+ {
+ IPACMERR("Failed adding Routing rule %pK\n", ruleTable_v2);
+ PERROR("unable to add routing rule:");
+
+ for (int cnt = 0; cnt < ruleTable_v2->num_rules; cnt++)
+ {
+ if (((struct ipa_rt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
+ {
+ IPACMERR("Adding Routing rule:%d failed with status:%d\n",
+ cnt, ((struct ipa_rt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status);
+ }
+ }
+ ret = false;
+ goto fail_rule;
+ }
+
+ /* copy results from v2 to v1 format */
+ for (int cnt = 0; cnt < ruleTable->num_rules; cnt++)
+ {
+ /* copy status to v1 format */
+ ruleTable->rules[cnt].status = ((struct ipa_rt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status;
+ ruleTable->rules[cnt].rt_rule_hdl = ((struct ipa_rt_rule_add_v2 *)ruleTable_v2->rules)[cnt].rt_rule_hdl;
+
+ if(((struct ipa_rt_rule_add_v2 *)ruleTable_v2->rules)[cnt].status != 0)
+ {
+ IPACMERR("Adding Routing rule:%d failed with status:%d\n",
+ cnt, ((struct ipa_rt_rule_add_v2 *) ruleTable_v2->rules)[cnt].status);
+ }
+ }
+ IPACMDBG("Added Routing rule %pK\n", ruleTable_v2);
+fail_rule:
+ if((void *)ruleTable_v2->rules != NULL)
+ free((void *)ruleTable_v2->rules);
+fail_tbl:
+ if (ruleTable_v2 != NULL)
+ free(ruleTable_v2);
+ return ret;
+}
+#endif //IPA_IOCTL_SET_FNR_COUNTER_INFO
+
+
bool IPACM_Routing::DeleteRoutingRule(struct ipa_ioc_del_rt_rule *ruleTable)
{
int retval = 0;
diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp
index 278f9ac..db0304a 100644
--- a/ipacm/src/IPACM_Wan.cpp
+++ b/ipacm/src/IPACM_Wan.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013, 2018 The Linux Foundation. All rights reserved.
+Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -69,7 +69,7 @@ struct ipa_flt_rule_add IPACM_Wan::flt_rule_v6[IPA_MAX_FLT_RULE];
char IPACM_Wan::wan_up_dev_name[IF_NAME_LEN];
-bool IPACM_Wan::backhaul_is_sta_mode = false;
+ipacm_wan_iface_type IPACM_Wan::backhaul_mode = Q6_WAN;
bool IPACM_Wan::is_ext_prop_set = false;
int IPACM_Wan::num_ipv4_modem_pdn = 0;
@@ -77,6 +77,9 @@ int IPACM_Wan::num_ipv6_modem_pdn = 0;
bool IPACM_Wan::embms_is_on = false;
bool IPACM_Wan::backhaul_is_wan_bridge = false;
+bool IPACM_Wan::is_xlat = false;
+
+ipacm_coalesce IPACM_Wan::coalesce_enable_info[IPA_MAX_NUM_SW_PDNS];
uint32_t IPACM_Wan::backhaul_ipv6_prefix[2];
@@ -107,7 +110,6 @@ IPACM_Wan::IPACM_Wan(int iface_index,
wan_route_rule_v6_hdl_a5 = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t));
IPACMDBG_H("IPACM->IPACM_Wan(%d) constructor: Tx:%d\n", ipa_if_num, iface_query->num_tx_props);
}
- m_is_sta_mode = is_sta_mode;
wan_v4_addr_set = false;
wan_v4_addr_gw_set = false;
@@ -132,15 +134,41 @@ IPACM_Wan::IPACM_Wan(int iface_index,
header_name_count = 0;
memset(invalid_mac, 0, sizeof(invalid_mac));
- is_xlat = false;
+ is_xlat_local = false;
hdr_hdl_dummy_v6 = 0;
hdr_proc_hdl_dummy_v6 = 0;
is_default_gateway = false;
m_fd_ipa = 0;
wan_client_len = 0;
+ m_is_sta_mode = is_sta_mode;
if(iface_query != NULL)
{
+ IPACMDBG_H("index:%d constructor: Tx properties:%d\n", iface_index, iface_query->num_tx_props);
+
+ if(is_sta_mode == Q6_WAN)
+ {
+ query_ext_prop();
+
+ if ((iface_query->num_ext_props == 1) && ((ext_prop != NULL) && ext_prop->ext[0].ip == IPA_IP_MAX))
+ {
+ /* only has one ext properties with IP_MAX type, will be the mhi-modem */
+ IPACMDBG_H("One extended property for iface %s, replace %d to Q6_MHI_WAN\n", dev_name, is_sta_mode);
+ m_is_sta_mode = Q6_MHI_WAN;
+ }
+ else
+ {
+ IPACMDBG_H("The new WAN interface is modem.\n");
+ m_is_sta_mode = is_sta_mode;
+ is_default_gateway = false;
+ }
+ }
+ else
+ {
+ m_is_sta_mode = is_sta_mode;
+ IPACMDBG_H("The new WAN interface is WLAN STA.\n");
+ }
+
wan_client_len = (sizeof(ipa_wan_client)) + (iface_query->num_tx_props * sizeof(wan_client_rt_hdl));
wan_client = (ipa_wan_client *)calloc(IPA_MAX_NUM_WAN_CLIENTS, wan_client_len);
if (wan_client == NULL)
@@ -148,19 +176,11 @@ IPACM_Wan::IPACM_Wan(int iface_index,
IPACMERR("unable to allocate memory\n");
return;
}
- IPACMDBG_H("index:%d constructor: Tx properties:%d\n", iface_index, iface_query->num_tx_props);
- }
-
-
- if(m_is_sta_mode == Q6_WAN)
- {
- IPACMDBG_H("The new WAN interface is modem.\n");
- is_default_gateway = false;
- query_ext_prop();
}
else
{
- IPACMDBG_H("The new WAN interface is WLAN STA.\n");
+ IPACMDBG_H("iface_query is empty.\n");
+ return;
}
m_fd_ipa = open(IPA_DEVICE_NAME, O_RDWR);
@@ -207,6 +227,7 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
struct ipa_ioc_add_flt_rule *flt_rule;
struct ipa_flt_rule_add flt_rule_entry;
struct ipa_ioc_get_hdr hdr;
+ bool result;
const int NUM_RULES = 1;
uint32_t num_ipv6_addr;
@@ -252,29 +273,11 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
rt_rule->commit = 1;
rt_rule->num_rules = NUM_RULES;
rt_rule->ip = data->iptype;
+ /* setup RT rule for v6_lan table*/
strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name));
rt_rule_entry = &rt_rule->rules[0];
- if(m_is_sta_mode == Q6_WAN)
- {
- strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
- hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
- if(m_header.GetHeaderHandle(&hdr) == false)
- {
- IPACMERR("Failed to get QMAP header.\n");
- return IPACM_FAILURE;
- }
- rt_rule_entry->rule.hdr_hdl = hdr.hdl;
- }
rt_rule_entry->at_rear = false;
- if(m_is_sta_mode == Q6_WAN)
- {
- rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
- }
- else
- {
- rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
- }
rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0];
rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1];
@@ -291,6 +294,90 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
#ifdef FEATURE_IPA_V3
rt_rule_entry->rule.hashable = false;
#endif
+ if(m_is_sta_mode == Q6_WAN)
+ {
+ strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
+ hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
+ if(m_header.GetHeaderHandle(&hdr) == false)
+ {
+ IPACMERR("Failed to get QMAP header.\n");
+ return IPACM_FAILURE;
+ }
+ rt_rule_entry->rule.hdr_hdl = hdr.hdl;
+ rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
+ /* legacy default v4 rt-rule */
+#ifdef IPA_RT_SUPPORT_COAL
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ /* legacy default v6 rt-rule */
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail;
+ }
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
+
+ /* setup same rule for v6_wan table*/
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail;
+ }
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
+
+ IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, entry: %d %d\n",
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],
+ MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6,
+ MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1);
+ /* RSC TCP rule*/
+ rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
+ rt_rule_entry->rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
+#ifdef IPA_RT_SUPPORT_COAL
+ if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
+ rt_rule_entry->rule.coalesce = true;
+ else
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rsc tcp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail;
+ }
+ dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv6 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d), entry %d", dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable,
+ 2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6);
+ /* RSB UDP rule*/
+ rt_rule_entry->rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_UDP;
+#ifdef IPA_RT_SUPPORT_COAL
+ if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable)
+ rt_rule_entry->rule.coalesce = true;
+ else
+ rt_rule_entry->rule.coalesce = false;
+#endif
if (false == m_routing.AddRoutingRule(rt_rule))
{
IPACMERR("Routing rule addition failed!\n");
@@ -299,6 +386,27 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
}
else if (rt_rule_entry->status)
{
+ IPACMERR("rsb udp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail;
+ }
+ dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv6 wan iface rsb udp rt-rule hdll=0x%x\n enable(%d) entry %d", dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable,
+ 2*MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1);
+ }
+ else
+ {
+ rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
+ /* legacy default v6 rt-rule */
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else if (rt_rule_entry->status)
+ {
IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
res = rt_rule_entry->status;
goto fail;
@@ -321,9 +429,12 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
}
dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl;
- IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, num_dft_rt_v6: %d \n",
+ IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, entry: %d %d\n",
dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6],
- dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],num_dft_rt_v6);
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],
+ MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6,
+ MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1);
+ }
/* add default filtering rules when wan-iface get global v6-prefix */
if (num_dft_rt_v6 == 1)
@@ -335,6 +446,11 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
IPACMDBG_H("Now the number of modem ipv6 pdn is %d.\n", num_ipv6_modem_pdn);
init_fl_rule_ex(data->iptype);
}
+ else if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING for ip-family %d \n", dev_name, IPA_IP_v6);
+ IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_v6);
+ }
else
{
init_fl_rule(data->iptype);
@@ -383,8 +499,20 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF;
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(flt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(flt_rule);
+ }
+#else
+ result = m_filtering.AddFilteringRule(flt_rule);
+#endif
- if (m_filtering.AddFilteringRule(flt_rule) == false)
+ if (result == false)
{
IPACMERR("Error Adding Filtering rule, aborting...\n");
free(flt_rule);
@@ -421,6 +549,21 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
else
{
IPACMDBG_H(" device (%s) ipv4 addr is changed\n", dev_name);
+ /* Delete default Coalese v4 RT rule */
+ if (m_is_sta_mode == Q6_WAN) {
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RSC TCP RT rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RSB UDP RT rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
/* Delete default v4 RT rule */
IPACMDBG_H("Delete default v4 routing rules\n");
if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
@@ -446,30 +589,80 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
rt_rule->num_rules = NUM_RULES;
rt_rule->ip = data->iptype;
rt_rule_entry = &rt_rule->rules[0];
+ rt_rule_entry->at_rear = false;
+ rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
+ /* still need setup v4 default routing rule to A5*/
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
+ rt_rule_entry->rule.attrib.u.v4.dst_addr = data->ipv4_addr;
+ rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
+#ifdef FEATURE_IPA_V3
+ rt_rule_entry->rule.hashable = false;
+#endif
if(m_is_sta_mode == Q6_WAN)
{
+ /* query qmap header*/
strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
if(m_header.GetHeaderHandle(&hdr) == false)
{
IPACMERR("Failed to get QMAP header.\n");
- return IPACM_FAILURE;
+ res = IPACM_FAILURE;
+ goto fail;
}
rt_rule_entry->rule.hdr_hdl = hdr.hdl;
rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
+ /* legacy default v4 rt-rule */
+#ifdef IPA_RT_SUPPORT_COAL
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ /* legacy default v4 rt-rule */
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail;
}
+ dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
+ /* RSC TCP rule*/
+ rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
+ rt_rule_entry->rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
+
+#ifdef IPA_RT_SUPPORT_COAL
+ if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
+ rt_rule_entry->rule.coalesce = true;
else
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ if (false == m_routing.AddRoutingRule(rt_rule))
{
- rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rsc tcp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail;
}
- rt_rule_entry->at_rear = false;
- rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
- /* still need setup v4 default routing rule to A5*/
- strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
- rt_rule_entry->rule.attrib.u.v4.dst_addr = data->ipv4_addr;
- rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
-#ifdef FEATURE_IPA_V3
- rt_rule_entry->rule.hashable = false;
+ dft_coalesce_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv4 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[0],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable);
+
+ /* RSB UDP rule*/
+ rt_rule_entry->rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_UDP;
+#ifdef IPA_RT_SUPPORT_COAL
+ if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable)
+ rt_rule_entry->rule.coalesce = true;
+ else
+ rt_rule_entry->rule.coalesce = false;
#endif
if (false == m_routing.AddRoutingRule(rt_rule))
{
@@ -479,14 +672,35 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
}
else if (rt_rule_entry->status)
{
+ IPACMERR("rsb udp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail;
+ }
+ dft_coalesce_rt_rule_hdl[1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv4 wan iface rsb udp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[1],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable);
+ }
+ else
+ {
+ rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
+ /* legacy default v4 rt-rule */
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else if (rt_rule_entry->status)
+ {
IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
res = rt_rule_entry->status;
goto fail;
}
dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
- /* initial multicast/broadcast/fragment filter rule */
+ }
+ /* initial multicast/broadcast/fragment filter rule */
/* only do one time */
if(!wan_v4_addr_set)
{
@@ -498,6 +712,11 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
IPACMDBG_H("Now the number of modem ipv4 pdn is %d.\n", num_ipv4_modem_pdn);
init_fl_rule_ex(data->iptype);
}
+ else if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING for ip-family %d \n", dev_name, IPA_IP_v4);
+ IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_v4);
+ }
else
{
init_fl_rule(data->iptype);
@@ -526,11 +745,231 @@ int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data)
IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6);
fail:
- free(rt_rule);
-
+ if (rt_rule != NULL)
+ {
+ free(rt_rule);
+ }
return res;
}
+/* handle new_address event */
+int IPACM_Wan::handle_addr_evt_mhi_q6(ipacm_event_data_addr *data)
+{
+ uint32_t num_ipv6_addr;
+ int res = IPACM_SUCCESS;
+ struct ipa_ioc_add_rt_rule *rt_rule = NULL;
+ struct ipa_rt_rule_add *rt_rule_entry;
+ struct ipa_ioc_get_hdr hdr;
+ const int NUM_RULES = 1;
+
+#ifdef FEATURE_IPACM_HAL
+ IPACM_OffloadManager* OffloadMng;
+#endif
+
+ memset(&hdr, 0, sizeof(hdr));
+ if(tx_prop == NULL || rx_prop == NULL)
+ {
+ IPACMDBG_H("Either tx or rx property is NULL, return.\n");
+ return IPACM_SUCCESS;
+ }
+ /* Update the IP Type. */
+ config_ip_type(data->iptype);
+
+ if (data->iptype == IPA_IP_v6)
+ {
+ for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++)
+ {
+ if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) &&
+ (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) &&
+ (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) &&
+ (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3]))
+ {
+ IPACMDBG_H("find matched ipv6 address, index:%d \n", num_ipv6_addr);
+ return IPACM_SUCCESS;
+ break;
+ }
+ }
+
+ ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0];
+ ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1];
+ ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2];
+ ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3];
+
+ /* store ipv6 prefix if the ipv6 address is not link local */
+ if(is_global_ipv6_addr(data->ipv6_addr))
+ {
+ memcpy(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix));
+ }
+ num_dft_rt_v6++;
+ if (num_dft_rt_v6 == 1)
+ {
+ /* Add Natting iface to IPACM_Config if there is Rx/Tx property */
+ if (rx_prop != NULL || tx_prop != NULL)
+ {
+ IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING for ip-family %d \n", dev_name, IPA_IP_v6);
+ IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_v6);
+ }
+ /* skylar setup v6-wan-tbl */
+ rt_rule = (struct ipa_ioc_add_rt_rule *)
+ calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
+ NUM_RULES * sizeof(struct ipa_rt_rule_add));
+ if (!rt_rule)
+ {
+ IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
+
+ rt_rule->commit = 1;
+ rt_rule->num_rules = NUM_RULES;
+ rt_rule->ip = data->iptype;
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
+ rt_rule_entry = &rt_rule->rules[0];
+ strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
+ hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
+ if(m_header.GetHeaderHandle(&hdr) == false)
+ {
+ IPACMERR("Failed to get QMAP header.\n");
+ free(rt_rule);
+ return IPACM_FAILURE;
+ }
+ rt_rule_entry->rule.hdr_hdl = hdr.hdl;
+ rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
+ rt_rule_entry->at_rear = false;
+ rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
+ /* still need setup v4 default routing rule to A5*/
+ rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = data->ipv6_addr[2];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = data->ipv6_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;
+ ipv6_addr[0][0] = data->ipv6_addr[0];
+ ipv6_addr[0][1] = data->ipv6_addr[1];
+ ipv6_addr[0][2] = data->ipv6_addr[2];
+ ipv6_addr[0][3] = data->ipv6_addr[3];
+#ifdef FEATURE_IPA_V3
+ rt_rule_entry->rule.hashable = false;
+#endif
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ free(rt_rule);
+ return IPACM_FAILURE;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ free(rt_rule);
+ return rt_rule_entry->status;
+ }
+ dft_rt_rule_hdl[1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv6 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[1]);
+ }
+ }
+ else
+ {
+ if(wan_v4_addr_set)
+ {
+ /* check iface ipv4 same or not */
+ if(data->ipv4_addr == wan_v4_addr)
+ {
+ IPACMDBG_H("Already setup device (%s) ipv4 and it didn't change(0x%x)\n", dev_name, data->ipv4_addr);
+ return IPACM_SUCCESS;
+ }
+ else
+ {
+ IPACMDBG_H(" device (%s) ipv4 addr is changed\n", dev_name);
+ /* Delete default v4 RT rule */
+ IPACMDBG_H("Delete default v4 routing rules\n");
+ if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RT rule deletion failed!\n");
+ return IPACM_FAILURE;
+ }
+ }
+ }
+ /* only do one time */
+ if(!wan_v4_addr_set)
+ {
+ /* Add Natting iface to IPACM_Config if there is Rx/Tx property */
+ if (rx_prop != NULL || tx_prop != NULL)
+ {
+ IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING for ip-family %d \n", dev_name, IPA_IP_v4);
+ IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name, IPA_IP_v4);
+ }
+
+ rt_rule = (struct ipa_ioc_add_rt_rule *)
+ calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
+ NUM_RULES * sizeof(struct ipa_rt_rule_add));
+
+ if (!rt_rule)
+ {
+ IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
+
+ rt_rule->commit = 1;
+ rt_rule->num_rules = NUM_RULES;
+ rt_rule->ip = data->iptype;
+ rt_rule_entry = &rt_rule->rules[0];
+ strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
+ hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
+ if(m_header.GetHeaderHandle(&hdr) == false)
+ {
+ IPACMERR("Failed to get QMAP header.\n");
+ free(rt_rule);
+ return IPACM_FAILURE;
+ }
+ rt_rule_entry->rule.hdr_hdl = hdr.hdl;
+ rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
+ rt_rule_entry->at_rear = false;
+ rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
+ /* still need setup v4 default routing rule to A5*/
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
+ rt_rule_entry->rule.attrib.u.v4.dst_addr = data->ipv4_addr;
+ rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
+#ifdef FEATURE_IPA_V3
+ rt_rule_entry->rule.hashable = false;
+#endif
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ free(rt_rule);
+ return IPACM_FAILURE;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ free(rt_rule);
+ return rt_rule_entry->status;
+ }
+ dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
+ }
+
+ wan_v4_addr = data->ipv4_addr;
+ wan_v4_addr_set = true;
+ IPACMDBG_H("Receved wan ipv4-addr:0x%x\n",wan_v4_addr);
+ free(rt_rule);
+ }
+
+#ifdef FEATURE_IPACM_HAL
+ /* check if having pending set_upstream cache*/
+ OffloadMng = IPACM_OffloadManager::GetInstance();
+ if (OffloadMng == NULL) {
+ IPACMERR("failed to get IPACM_OffloadManager instance !\n");
+ } else {
+ IPACMDBG_H(" check iface %s if having set_upstream cache events\n", dev_name);
+ OffloadMng->search_framwork_cache(dev_name);
+ }
+#endif
+ IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6);
+
+ return res;
+}
void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
{
int ipa_interface_index;
@@ -565,9 +1004,9 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index);
if ((ipa_interface_index == ipa_if_num) && (m_is_sta_mode == Q6_WAN))
{
- is_xlat = true;
- IPACMDBG_H("WAN-LTE (%s) link up, iface: %d is_xlat: %d\n",
- IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,data->if_index, is_xlat);
+ is_xlat_local = true;
+ IPACMDBG_H("WAN-LTE (%s) link up, iface: %d is_xlat_local: %d\n",
+ IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,data->if_index, is_xlat_local);
}
break;
}
@@ -665,6 +1104,15 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
}
break;
+ case IPA_COALESCE_NOTICE:
+ {
+ if (m_is_sta_mode == Q6_WAN)
+ {
+ IPACMDBG_H("Received IPA_COALESCE_NOTICE (wan_mode:%d)\n", m_is_sta_mode);
+ handle_coalesce_evt();
+ }
+ }
+ break;
case IPA_LINK_DOWN_EVENT:
{
ipacm_event_data_fid *data = (ipacm_event_data_fid *)param;
@@ -680,7 +1128,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
delete this;
return;
}
- else if (m_is_sta_mode == ECM_WAN)
+ else if ((m_is_sta_mode == ECM_WAN) || (m_is_sta_mode == Q6_MHI_WAN))
{
IPACMDBG_H("Received IPA_LINK_DOWN_EVENT(wan_mode:%d)\n", m_is_sta_mode);
/* delete previous instance */
@@ -715,15 +1163,31 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
if( (data->iptype == IPA_IP_v4)
|| ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES)))
{
- IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
- handle_addr_evt(data);
+ if (m_is_sta_mode == Q6_MHI_WAN)
+ {
+ IPACMDBG_H("Got handle_addr_evt_mhi_q6 ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
+ handle_addr_evt_mhi_q6(data);
+ }
+ else
+ {
+ IPACMDBG_H("Got handle_addr_evt ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6);
+ handle_addr_evt(data);
+ }
/* checking if SW-RT_enable */
if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true &&
m_is_sta_mode != Q6_WAN)
{
/* handle software routing enable event*/
IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
- handle_software_routing_enable();
+
+ if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ handle_software_routing_enable(true);
+ }
+ else
+ {
+ handle_software_routing_enable(false);
+ }
}
}
@@ -763,7 +1227,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
#endif
if (active_v4 == false)
{
- handle_route_add_evt(data->iptype); //sky
+ handle_route_add_evt(data->iptype);
}
}
#ifdef FEATURE_IPA_ANDROID
@@ -824,6 +1288,11 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
install_wan_filtering_rule(false);
handle_route_del_evt_ex(IPA_IP_v4);
}
+ else if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ /* only need cleanup rt-rule*/
+ handle_route_del_evt(IPA_IP_v4);
+ }
else
{
del_dft_firewall_rules(IPA_IP_v4);
@@ -840,6 +1309,11 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
install_wan_filtering_rule(false);
handle_route_del_evt_ex(IPA_IP_v6);
}
+ else if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ /* only need cleanup rt-rule*/
+ handle_route_del_evt(IPA_IP_v6);
+ }
else
{
del_dft_firewall_rules(IPA_IP_v6);
@@ -889,6 +1363,12 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
install_wan_filtering_rule(false);
handle_route_del_evt_ex(IPA_IP_v4);
}
+ else if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ /* only need cleanup rt-rule*/
+ del_dft_firewall_rules(IPA_IP_v4);
+ handle_route_del_evt(IPA_IP_v4);
+ }
else
{
del_dft_firewall_rules(IPA_IP_v4);
@@ -918,6 +1398,13 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
install_wan_filtering_rule(false);
handle_route_del_evt_ex(IPA_IP_v6);
}
+ else if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ /* only need cleanup rt-rule*/
+ del_dft_firewall_rules(IPA_IP_v6);
+ handle_route_del_evt(IPA_IP_v6);
+ }
+
else
{
del_dft_firewall_rules(IPA_IP_v6);
@@ -962,7 +1449,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
handle_sta_header_add_evt();
handle_route_add_evt(data->iptype);
/* Add IPv6 routing table if XLAT is enabled */
- if(is_xlat && (m_is_sta_mode == Q6_WAN) && (active_v6 == false))
+ if(is_xlat_local && (m_is_sta_mode == Q6_WAN) && (active_v6 == false))
{
IPACMDBG_H("XLAT enabled: adding IPv6 routing table dev (%s)\n", dev_name);
handle_route_add_evt(IPA_IP_v6);
@@ -1051,7 +1538,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
install_wan_filtering_rule(false);
handle_route_del_evt_ex(IPA_IP_v4);
- if(is_xlat && active_v6 == true)
+ if(is_xlat_local && active_v6 == true)
{
IPACMDBG_H("XLAT enabled: Delete IPv6 routing table dev (%s)\n", dev_name);
del_wan_firewall_rule(IPA_IP_v6);
@@ -1153,9 +1640,13 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
{
install_wan_filtering_rule(true);
}
+ else if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ handle_software_routing_enable(true);
+ }
else
{
- handle_software_routing_enable();
+ handle_software_routing_enable(false);
}
break;
@@ -1168,9 +1659,13 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
install_wan_filtering_rule(false);
softwarerouting_act = false;
}
+ else if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ handle_software_routing_disable(true);
+ }
else
{
- handle_software_routing_disable();
+ handle_software_routing_disable(false);
}
break;
@@ -1228,7 +1723,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
break;
case IPA_WLAN_SWITCH_TO_SCC:
- if(IPACM_Wan::backhaul_is_sta_mode == true)
+ if(IPACM_Wan::backhaul_mode == WLAN_WAN)
{
IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_SCC\n");
if(ip_type == IPA_IP_MAX)
@@ -1247,7 +1742,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
break;
case IPA_WLAN_SWITCH_TO_MCC:
- if(IPACM_Wan::backhaul_is_sta_mode == true)
+ if(IPACM_Wan::backhaul_mode == WLAN_WAN)
{
IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_MCC\n");
if(ip_type == IPA_IP_MAX)
@@ -1266,7 +1761,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param)
break;
#ifdef FEATURE_IPACM_HAL
/* WA for WLAN to clean up NAT instance during SSR */
- case IPA_SSR_NOTICE: //sky
+ case IPA_SSR_NOTICE:
case IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE:
IPACMDBG_H("Received IPA_SSR_NOTICE event.\n");
if(m_is_sta_mode == WLAN_WAN)
@@ -1293,6 +1788,7 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
const int NUM = 1;
ipacm_cmd_q_data evt_data;
struct ipa_ioc_get_hdr hdr;
+ bool result;
#ifdef WAN_IOC_NOTIFY_WAN_STATE //resolve compile issue on 4.9 kernel
struct wan_ioctl_notify_wan_state wan_state;
int fd_wwan_ioctl;
@@ -1322,25 +1818,9 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
}
IPACMDBG_H("backhaul_is_wan_bridge ?: %d \n", IPACM_Wan::backhaul_is_wan_bridge);
- if (m_is_sta_mode !=Q6_WAN)
- {
- IPACM_Wan::backhaul_is_sta_mode = true;
- if((iptype==IPA_IP_v4) && (header_set_v4 != true))
- {
- header_partial_default_wan_v4 = true;
- IPACMDBG_H("STA ipv4-header haven't constructed \n");
- return IPACM_SUCCESS;
- }
- else if((iptype==IPA_IP_v6) && (header_set_v6 != true))
- {
- header_partial_default_wan_v6 = true;
- IPACMDBG_H("STA ipv6-header haven't constructed \n");
- return IPACM_SUCCESS;
- }
- }
- else
+ if (m_is_sta_mode ==Q6_WAN)
{
- IPACM_Wan::backhaul_is_sta_mode = false;
+ IPACM_Wan::backhaul_mode = m_is_sta_mode;
IPACMDBG_H("reset backhaul to LTE \n");
if (iface_query != NULL && iface_query->num_ext_props > 0)
@@ -1362,53 +1842,64 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
return IPACM_FAILURE;
}
}
-#if 0
- for (cnt=0; cnt<tx_prop->num_tx_props; cnt++)
- {
- if(tx_prop->tx[cnt].ip==iptype)
- break;
- }
-
- if(tx_prop->tx[cnt].hdr_name != NULL)
+ else if (m_is_sta_mode == Q6_MHI_WAN)
{
- memset(&sCopyHeader, 0, sizeof(sCopyHeader));
- memcpy(sCopyHeader.name,
- tx_prop->tx[cnt].hdr_name,
- sizeof(sCopyHeader.name));
-
- IPACMDBG_H("header name: %s\n", sCopyHeader.name);
- if (m_header.CopyHeader(&sCopyHeader) == false)
- {
- IPACMERR("ioctl copy header failed");
- return IPACM_FAILURE;
- }
- IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial);
- if(sCopyHeader.is_partial)
- {
- IPACMDBG_H("Not setup default WAN routing rules cuz the header is not complete\n");
- if(iptype==IPA_IP_v4)
+ if (iface_query != NULL && iface_query->num_ext_props > 0)
+ {
+ /* treat Q6_MHI_WAN as STA mode also */
+ IPACMDBG_H("Q6-MHI ipv4/v6-header already constructed \n");
+ IPACM_Wan::backhaul_mode = m_is_sta_mode;
+ IPACMDBG_H("Setting up QMAP ID %d.\n", ext_prop->ext[0].mux_id);
+ IPACM_Iface::ipacmcfg->SetQmapId(ext_prop->ext[0].mux_id);
+ /* sending mux-id info to PCIE-modem for UL */
+ if(false == m_filtering.AddOffloadFilteringRule(NULL, ext_prop->ext[0].mux_id, 0))
{
- header_partial_default_wan_v4 = true;
- }
- else
+ IPACMERR("Failed to send mux id info to modem.\n");
+ return IPACM_FAILURE;
+ }
+ /* send UL UDP frag filtering rule */
+ if(iptype==IPA_IP_v4 && add_offload_frag_rule())
{
- header_partial_default_wan_v6 = true;
+ IPACMERR("Failed to send DL frag rule to modem.\n");
+ return IPACM_FAILURE;
}
- return IPACM_SUCCESS;
- }
- else
- {
- if(iptype==IPA_IP_v4)
+
+ /* send ipv6 ICMP filtering rule */
+ if(iptype==IPA_IP_v6 && add_icmpv6_exception_rule())
{
- header_partial_default_wan_v4 = false;
- }
- else
+ IPACMERR("Failed to send ICMPv6 ex rule to modem.\n");
+ return IPACM_FAILURE;
+ }
+
+ /* send ipv4 TCP FIN filtering rule */
+ if(iptype==IPA_IP_v4 && add_tcp_fin_rst_exception_rule())
{
- header_partial_default_wan_v6 = false;
+ IPACMERR("Failed to send TCP FIN RST rule to modem.\n");
+ return IPACM_FAILURE;
}
- }
- }
-#endif
+ }
+ else
+ {
+ IPACMERR("iface_query is empty.\n");
+ return IPACM_FAILURE;
+ }
+ }
+ else
+ {
+ IPACM_Wan::backhaul_mode = m_is_sta_mode;
+ if((iptype==IPA_IP_v4) && (header_set_v4 != true))
+ {
+ header_partial_default_wan_v4 = true;
+ IPACMDBG_H("STA ipv4-header haven't constructed \n");
+ return IPACM_SUCCESS;
+ }
+ else if((iptype==IPA_IP_v6) && (header_set_v6 != true))
+ {
+ header_partial_default_wan_v6 = true;
+ IPACMDBG_H("STA ipv6-header haven't constructed \n");
+ return IPACM_SUCCESS;
+ }
+ }
rt_rule = (struct ipa_ioc_add_rt_rule *)
calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
@@ -1424,8 +1915,6 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
rt_rule->num_rules = (uint8_t)NUM;
rt_rule->ip = iptype;
-
- IPACMDBG_H(" WAN table created %s \n", rt_rule->rt_tbl_name);
rt_rule_entry = &rt_rule->rules[0];
rt_rule_entry->at_rear = true;
@@ -1453,15 +1942,34 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v6;
}
- if(IPACM_Iface::ipacmcfg->isMCC_Mode == true)
+ IPACMDBG_H(" WAN table created %s \n", rt_rule->rt_tbl_name);
+ /* replace the hdr handle for q6_PCIE*/
+ if(m_is_sta_mode == Q6_MHI_WAN)
{
- IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
- tx_prop->tx[tx_index].alt_dst_pipe);
- rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
+ memset(&hdr, 0, sizeof(hdr));
+ strlcpy(hdr.name, tx_prop->tx[tx_index].hdr_name, sizeof(hdr.name));
+ hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
+ if(m_header.GetHeaderHandle(&hdr) == false)
+ {
+ IPACMERR("Failed to get QMAP header.\n");
+ free(rt_rule);
+ return IPACM_FAILURE;
+ }
+ rt_rule_entry->rule.hdr_hdl = hdr.hdl;
+ rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
}
else
{
- rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
+ if(IPACM_Iface::ipacmcfg->isMCC_Mode == true)
+ {
+ IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n",
+ tx_prop->tx[tx_index].alt_dst_pipe);
+ rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe;
+ }
+ else
+ {
+ rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe;
+ }
}
memcpy(&rt_rule_entry->rule.attrib,
&tx_prop->tx[tx_index].attrib,
@@ -1473,10 +1981,21 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
rt_rule_entry->rule.attrib.u.v4.dst_addr = 0;
rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0;
#ifdef FEATURE_IPA_V3
-
rt_rule_entry->rule.hashable = true;
#endif
- if (false == m_routing.AddRoutingRule(rt_rule))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if((m_is_sta_mode == WLAN_WAN) && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_HW);
+ result = m_routing.AddRoutingRule_hw_index(rt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_HW);
+ } else {
+ result = m_routing.AddRoutingRule(rt_rule);
+ }
+#else
+ result = m_routing.AddRoutingRule(rt_rule);
+#endif
+ if (result == false)
{
IPACMERR("Routing rule addition failed!\n");
free(rt_rule);
@@ -1501,7 +2020,19 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
#ifdef FEATURE_IPA_V3
rt_rule_entry->rule.hashable = true;
#endif
- if (false == m_routing.AddRoutingRule(rt_rule))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if((m_is_sta_mode == WLAN_WAN) && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_HW);
+ result = m_routing.AddRoutingRule_hw_index(rt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + UL_HW);
+ } else {
+ result = m_routing.AddRoutingRule(rt_rule);
+ }
+#else
+ result = m_routing.AddRoutingRule(rt_rule);
+#endif
+ if (result == false)
{
IPACMERR("Routing rule addition failed!\n");
free(rt_rule);
@@ -1518,9 +2049,10 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
/* add a catch-all rule in wan dl routing table */
- if (iptype == IPA_IP_v6)
+ if (iptype == IPA_IP_v6 && m_is_sta_mode != Q6_MHI_WAN)
{
strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
+ IPACMDBG_H(" WAN table created %s \n", rt_rule->rt_tbl_name);
memset(rt_rule_entry, 0, sizeof(struct ipa_rt_rule_add));
rt_rule_entry->at_rear = true;
if(m_is_sta_mode == Q6_WAN)
@@ -1531,6 +2063,7 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
if(m_header.GetHeaderHandle(&hdr) == false)
{
IPACMERR("Failed to get QMAP header.\n");
+ free(rt_rule);
return IPACM_FAILURE;
}
rt_rule_entry->rule.hdr_hdl = hdr.hdl;
@@ -1582,6 +2115,7 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
}
memset(wanup_data, 0, sizeof(ipacm_event_iface_up));
+ /* handling filter rule construction */
if (iptype == IPA_IP_v4)
{
IPACM_Wan::wan_up = true;
@@ -1602,34 +2136,33 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
memcpy(wanup_data->ifname, dev_name, sizeof(wanup_data->ifname));
wanup_data->ipv4_addr = wan_v4_addr;
- if (m_is_sta_mode!=Q6_WAN)
- {
- wanup_data->is_sta = true;
- }
- else
- {
- wanup_data->is_sta = false;
- }
+ wanup_data->backhaul_type = m_is_sta_mode;
IPACMDBG_H("Posting IPA_HANDLE_WAN_UP with below information:\n");
IPACMDBG_H("if_name:%s, ipv4_address:0x%x, is sta mode:%d\n",
- wanup_data->ifname, wanup_data->ipv4_addr, wanup_data->is_sta);
+ wanup_data->ifname, wanup_data->ipv4_addr, wanup_data->backhaul_type);
memset(&evt_data, 0, sizeof(evt_data));
+ /* set backhaul type as xlat */
+ IPACM_Wan::is_xlat = is_xlat_local;
+
/* send xlat configuration for installing uplink rules */
- if(is_xlat && (m_is_sta_mode == Q6_WAN))
+ if(is_xlat_local && (m_is_sta_mode == Q6_WAN))
{
IPACM_Wan::xlat_mux_id = ext_prop->ext[0].mux_id;
wanup_data->xlat_mux_id = IPACM_Wan::xlat_mux_id;
IPACMDBG_H("Set xlat configuraiton with below information:\n");
- IPACMDBG_H("xlat_enabled: %d xlat_mux_id: %d \n",
- is_xlat, xlat_mux_id);
+ IPACMDBG_H("xlat_enabled: %d set xlat_mux_id: %d \n",
+ is_xlat_local, IPACM_Wan::xlat_mux_id);
}
- else
+ else /*temp put xlat = 0 for Q6_MHI_WAN*/
{
IPACM_Wan::xlat_mux_id = 0;
wanup_data->xlat_mux_id = 0;
- if(m_is_sta_mode == Q6_WAN)
+ if(m_is_sta_mode != WLAN_WAN) //both q6_wan/q6_mhi_wan
+ {
wanup_data->mux_id = ext_prop->ext[0].mux_id;
+ IPACMDBG_H("mux_id: %d\n", wanup_data->mux_id);
+ }
else
wanup_data->mux_id = 0;
IPACMDBG_H("No xlat configuration\n");
@@ -1664,17 +2197,10 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
}
memcpy(wanup_data->ifname, dev_name, sizeof(wanup_data->ifname));
- if (m_is_sta_mode!=Q6_WAN)
- {
- wanup_data->is_sta = true;
- }
- else
- {
- wanup_data->is_sta = false;
- }
+ wanup_data->backhaul_type = m_is_sta_mode;
memcpy(wanup_data->ipv6_prefix, ipv6_prefix, sizeof(wanup_data->ipv6_prefix));
IPACMDBG_H("Posting IPA_HANDLE_WAN_UP_V6 with below information:\n");
- IPACMDBG_H("if_name:%s, is sta mode: %d\n", wanup_data->ifname, wanup_data->is_sta);
+ IPACMDBG_H("if_name:%s, is sta mode: %d\n", wanup_data->ifname, wanup_data->backhaul_type);
IPACMDBG_H("ipv6 prefix: 0x%08x%08x.\n", ipv6_prefix[0], ipv6_prefix[1]);
memset(&evt_data, 0, sizeof(evt_data));
evt_data.event = IPA_HANDLE_WAN_UP_V6;
@@ -1685,20 +2211,22 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
post_wan_up_tether_evt(IPA_IP_v6, 0);
#endif
}
- if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
- {
+
+ if(IPACM_Iface::ipacmcfg->GetIPAVer() >= IPA_HW_None && IPACM_Iface::ipacmcfg->GetIPAVer() < IPA_HW_v4_0)
+ {
/* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */
IPACMDBG_H("dev %s add producer dependency\n", dev_name);
IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false);
#ifdef WAN_IOC_NOTIFY_WAN_STATE
- } else {
- if (m_is_sta_mode == Q6_WAN && ipa_pm_q6_check == 0)
+ } else {
+ if ((m_is_sta_mode == Q6_WAN && ipa_pm_q6_check == 0 ) || (m_is_sta_mode == Q6_MHI_WAN))
{
fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
if(fd_wwan_ioctl < 0)
{
IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
+ free(rt_rule);
return false;
}
IPACMDBG_H("send WAN_IOC_NOTIFY_WAN_STATE up to IPA_PM\n");
@@ -1711,10 +2239,9 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
}
ipa_pm_q6_check++;
IPACMDBG_H("update ipa_pm_q6_check to %d\n", ipa_pm_q6_check);
-
- }
+ }
#else
-}
+ }
#endif
if(rt_rule != NULL)
{
@@ -1739,22 +2266,16 @@ int IPACM_Wan::post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether)
memset(wanup_data, 0, sizeof(ipacm_event_iface_up_tehter));
wanup_data->if_index_tether = ipa_if_num_tether;
- if (m_is_sta_mode!=Q6_WAN)
- {
- wanup_data->is_sta = true;
- }
- else
- {
- wanup_data->is_sta = false;
- }
+ wanup_data->backhaul_type = m_is_sta_mode;
/* xlat mux-id*/
- if(is_xlat && (m_is_sta_mode == Q6_WAN))
+ if(is_xlat_local && (m_is_sta_mode == Q6_WAN))
wanup_data->xlat_mux_id = ext_prop->ext[0].mux_id;
else
wanup_data->xlat_mux_id = 0;
IPACMDBG_H("Posting IPA_HANDLE_WAN_UP_TETHER with below information:\n");
IPACMDBG_H("tether_if_name:%s, is sta mode:%d xlat_mux_id: %d\n",
- IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, wanup_data->is_sta, wanup_data->xlat_mux_id);
+ IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, wanup_data->backhaul_type, wanup_data->xlat_mux_id);
+
memset(&evt_data, 0, sizeof(evt_data));
if (iptype == IPA_IP_v4)
@@ -1806,17 +2327,10 @@ int IPACM_Wan::post_wan_down_tether_evt(ipa_ip_type iptype, int ipa_if_num_tethe
memset(wandown_data, 0, sizeof(ipacm_event_iface_up_tehter));
wandown_data->if_index_tether = ipa_if_num_tether;
- if (m_is_sta_mode!=Q6_WAN)
- {
- wandown_data->is_sta = true;
- }
- else
- {
- wandown_data->is_sta = false;
- }
+ wandown_data->backhaul_type = m_is_sta_mode;
IPACMDBG_H("Posting IPA_HANDLE_WAN_DOWN_TETHER with below information:\n");
IPACMDBG_H("tether_if_name:%s, is sta mode:%d\n",
- IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, wandown_data->is_sta);
+ IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, wandown_data->backhaul_type);
memset(&evt_data, 0, sizeof(evt_data));
if (iptype == IPA_IP_v4)
@@ -2000,6 +2514,7 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
{
struct ipa_flt_rule_add flt_rule_entry;
int i, rule_v4 = 0, rule_v6 = 0, len;
+ bool result;
IPACMDBG_H("ip-family: %d; \n", iptype);
@@ -2013,29 +2528,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(m_is_sta_mode != Q6_MHI_WAN)
{
- 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
+ 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++)
{
- rule_v6++;
+ 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");
+ IPACMDBG_H("in Q6_MHI_WAN mode, skip firewall, use default configuration \n");
}
-
/* construct ipa_ioc_add_flt_rule with N firewall rules */
ipa_ioc_add_flt_rule *m_pFilteringTable = NULL;
len = sizeof(struct ipa_ioc_add_flt_rule) + 1 * sizeof(struct ipa_flt_rule_add);
@@ -2068,7 +2589,19 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib));
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT;
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+ if (false == result)
{
IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
free(m_pFilteringTable);
@@ -2153,9 +2686,27 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000;
flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000;
- memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+ /* disble meta-data filtering */
+ if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
+ IPACMDBG_H("disable meta-data filtering 0x%x\n", flt_rule_entry.rule.attrib.attrib_mask);
+ }
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+ memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+ if (false == result)
{
IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
free(m_pFilteringTable);
@@ -2242,7 +2793,20 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
IPACMDBG_H("Filter rule attrib mask: 0x%x\n",
m_pFilteringTable->rules[0].rule.attrib.attrib_mask);
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+
+ if (false == result)
{
IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
free(m_pFilteringTable);
@@ -2266,7 +2830,20 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
IPACMDBG_H("Filter rule attrib mask: 0x%x\n",
m_pFilteringTable->rules[0].rule.attrib.attrib_mask);
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+
+ if (false == result)
{
IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
free(m_pFilteringTable);
@@ -2290,7 +2867,20 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
IPACMDBG_H("Filter rule attrib mask: 0x%x\n",
m_pFilteringTable->rules[0].rule.attrib.attrib_mask);
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+
+ if (false == result)
{
IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
free(m_pFilteringTable);
@@ -2366,7 +2956,20 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
IPACMDBG_H("Filter rule attrib mask: 0x%x\n",
m_pFilteringTable->rules[0].rule.attrib.attrib_mask);
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+
+ if (false == result)
{
IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n");
free(m_pFilteringTable);
@@ -2395,40 +2998,57 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
m_pFilteringTable->ip = IPA_IP_v6;
m_pFilteringTable->num_rules = (uint8_t)1;
- /* Construct ICMP rule */
- memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
- flt_rule_entry.at_rear = true;
- flt_rule_entry.flt_rule_hdl = -1;
- flt_rule_entry.status = -1;
- flt_rule_entry.rule.retain_hdr = 1;
- flt_rule_entry.rule.eq_attrib_type = 0;
- flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
+ if(m_is_sta_mode != Q6_MHI_WAN)
+ {
+ /* Construct ICMP rule */
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
+ flt_rule_entry.at_rear = true;
+ flt_rule_entry.flt_rule_hdl = -1;
+ flt_rule_entry.status = -1;
+ flt_rule_entry.rule.retain_hdr = 1;
+ flt_rule_entry.rule.eq_attrib_type = 0;
+ flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
#ifdef FEATURE_IPA_V3
flt_rule_entry.rule.hashable = true;
#endif
- memcpy(&flt_rule_entry.rule.attrib,
- &rx_prop->rx[0].attrib,
- sizeof(struct ipa_rule_attrib));
- 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(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+ memcpy(&flt_rule_entry.rule.attrib,
+ &rx_prop->rx[0].attrib,
+ sizeof(struct ipa_rule_attrib));
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
+ flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6;
+ memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
- {
- IPACMERR("Error Adding Filtering rules, aborting...\n");
- free(m_pFilteringTable);
- return IPACM_FAILURE;
+ if (false == result)
+ {
+ IPACMERR("Error Adding Filtering rules, aborting...\n");
+ free(m_pFilteringTable);
+ return IPACM_FAILURE;
+ }
+ else
+ {
+ IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
+ IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
+ }
+ /* copy filter hdls */
+ dft_wan_fl_hdl[2] = m_pFilteringTable->rules[0].flt_rule_hdl;
+ /* End of construct ICMP rule */
}
else
{
- IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
- IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status);
+ IPACMDBG_H("in Q6_MHI_WAN mode, skip ICMPv6 flt rule \n");
}
- /* copy filter hdls */
- dft_wan_fl_hdl[2] = m_pFilteringTable->rules[0].flt_rule_hdl;
-
- /* End of construct ICMP rule */
-
/* v6 default route */
memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v6)) //rt_tbl_wan_v6 rt_tbl_v6
@@ -2443,25 +3063,24 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.hdl;
/* firewall disable, all traffic are allowed */
- if(firewall_config.firewall_enable == true)
+ if(firewall_config.firewall_enable == true)
{
- flt_rule_entry.at_rear = true;
-
- /* default action for v6 is PASS_TO_ROUTE unless user set to exception*/
- if(firewall_config.rule_action_accept == true)
- {
- flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
- }
- else
- {
+ flt_rule_entry.at_rear = true;
+ /* default action for v6 is PASS_TO_ROUTE unless user set to exception*/
+ if(firewall_config.rule_action_accept == true)
+ {
+ flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
+ }
+ else
+ {
flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
- }
- }
+ }
+ }
else
{
flt_rule_entry.at_rear = true;
flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
- }
+ }
#ifdef FEATURE_IPA_V3
flt_rule_entry.rule.hashable = true;
#endif
@@ -2477,10 +3096,28 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000;
flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000;
flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000;
+ /* disble meta-data filtering */
+ if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA);
+ IPACMDBG_H("disable meta-data filtering 0x%x\n", flt_rule_entry.rule.attrib.attrib_mask);
+ }
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+ if (false == result)
{
IPACMERR("Error Adding Filtering rules, aborting...\n");
free(m_pFilteringTable);
@@ -2551,7 +3188,20 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
/* insert TCP rule*/
flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_TCP;
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+
+ if (false == result)
{
IPACMERR("Error Adding Filtering rules, aborting...\n");
free(m_pFilteringTable);
@@ -2570,7 +3220,19 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
/* insert UDP rule*/
flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_UDP;
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+ if (false == result)
{
IPACMERR("Error Adding Filtering rules, aborting...\n");
free(m_pFilteringTable);
@@ -2589,7 +3251,20 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
else
{
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+ if (false == result)
{
IPACMERR("Error Adding Filtering rules, aborting...\n");
free(m_pFilteringTable);
@@ -2627,7 +3302,19 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6;
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+ if (result == false)
{
IPACMERR("Error Adding Filtering rules, aborting...\n");
free(m_pFilteringTable);
@@ -2687,7 +3374,20 @@ int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype)
memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
- if (false == m_filtering.AddFilteringRule(m_pFilteringTable))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_ALL);
+ result = m_filtering.AddFilteringRule_hw_index(m_pFilteringTable, IPACM_Iface::ipacmcfg->hw_counter_offset+ DL_ALL);
+ } else {
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+ }
+#else
+ result = m_filtering.AddFilteringRule(m_pFilteringTable);
+#endif
+
+ if (result == false)
{
IPACMERR("Error Adding Filtering rules, aborting...\n");
free(m_pFilteringTable);
@@ -3991,7 +4691,7 @@ int IPACM_Wan::del_dft_firewall_rules(ipa_ip_type iptype)
if (num_firewall_v4 != 0)
{
if (m_filtering.DeleteFilteringHdls(firewall_hdl_v4,
- IPA_IP_v4, num_firewall_v4) == false)
+ IPA_IP_v4, num_firewall_v4) == false)
{
IPACMERR("Error Deleting Filtering rules, aborting...\n");
return IPACM_FAILURE;
@@ -4004,7 +4704,7 @@ int IPACM_Wan::del_dft_firewall_rules(ipa_ip_type iptype)
}
if (m_filtering.DeleteFilteringHdls(dft_wan_fl_hdl,
- IPA_IP_v4, 1) == false)
+ IPA_IP_v4, 1) == false)
{
IPACMERR("Error Deleting Filtering rules, aborting...\n");
return IPACM_FAILURE;
@@ -4025,7 +4725,7 @@ int IPACM_Wan::del_dft_firewall_rules(ipa_ip_type iptype)
if (num_firewall_v6 != 0)
{
if (m_filtering.DeleteFilteringHdls(firewall_hdl_v6,
- IPA_IP_v6, num_firewall_v6) == false)
+ IPA_IP_v6, num_firewall_v6) == false)
{
IPACMERR("Error Deleting Filtering rules, aborting...\n");
return IPACM_FAILURE;
@@ -4038,20 +4738,27 @@ int IPACM_Wan::del_dft_firewall_rules(ipa_ip_type iptype)
}
if (m_filtering.DeleteFilteringHdls(&dft_wan_fl_hdl[1],
- IPA_IP_v6, 1) == false)
+ IPA_IP_v6, 1) == false)
{
IPACMERR("Error Deleting Filtering rules, aborting...\n");
return IPACM_FAILURE;
}
- IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
- if (m_filtering.DeleteFilteringHdls(&dft_wan_fl_hdl[2],
- IPA_IP_v6, 1) == false)
+
+ if(m_is_sta_mode != Q6_MHI_WAN)
{
- IPACMERR("Error Deleting Filtering rules, aborting...\n");
- return IPACM_FAILURE;
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
+ if (m_filtering.DeleteFilteringHdls(&dft_wan_fl_hdl[2],
+ IPA_IP_v6, 1) == false)
+ {
+ IPACMERR("Error Deleting Filtering rules, aborting...\n");
+ return IPACM_FAILURE;
+ }
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
+ }
+ else
+ {
+ IPACMDBG_H("in Q6_MHI_WAN mode, skip ICMPv6 flt rule deletion\n");
}
- IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1);
-
if (is_ipv6_frag_firewall_flt_rule_installed &&
check_dft_firewall_rules_attr_mask(&firewall_config))
{
@@ -4065,7 +4772,6 @@ int IPACM_Wan::del_dft_firewall_rules(ipa_ip_type iptype)
}
num_firewall_v6 = 0;
}
-
return IPACM_SUCCESS;
}
@@ -4074,6 +4780,11 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype)
{
uint32_t tx_index;
ipacm_cmd_q_data evt_data;
+#ifdef WAN_IOC_NOTIFY_WAN_STATE
+ struct wan_ioctl_notify_wan_state wan_state;
+ int fd_wwan_ioctl;
+ memset(&wan_state, 0, sizeof(wan_state));
+#endif
IPACMDBG_H("got handle_route_del_evt for STA-mode with ip-family:%d \n", iptype);
@@ -4096,6 +4807,33 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype)
IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
}
+ else
+ {
+ /* change wan_state for Q6_MHI */
+#ifdef WAN_IOC_NOTIFY_WAN_STATE
+ IPACMDBG_H("ipa_pm_q6_check to %d\n", ipa_pm_q6_check);
+ if(ipa_pm_q6_check == 1 && m_is_sta_mode == Q6_MHI_WAN)
+ {
+ fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
+ if(fd_wwan_ioctl < 0)
+ {
+ IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME);
+ return false;
+ }
+ IPACMDBG_H("send WAN_IOC_NOTIFY_WAN_STATE down to IPA_PM\n");
+ if(ioctl(fd_wwan_ioctl, WAN_IOC_NOTIFY_WAN_STATE, &wan_state))
+ {
+ IPACMERR("Failed to send WAN_IOC_NOTIFY_WAN_STATE as up %d\n ", wan_state.up);
+ }
+ close(fd_wwan_ioctl);
+ }
+ if (ipa_pm_q6_check > 0)
+ ipa_pm_q6_check--;
+ else
+ IPACMERR(" ipa_pm_q6_check becomes negative !!!\n");
+#endif
+ }
+
for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++)
{
if(iptype != tx_prop->tx[tx_index].ip)
@@ -4128,7 +4866,7 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype)
}
/* Delete the default wan route*/
- if (iptype == IPA_IP_v6)
+ if (iptype == IPA_IP_v6 && m_is_sta_mode != Q6_MHI_WAN)
{
IPACMDBG_H("ip-type %d: default v6 wan RT-rule deleted\n",iptype);
if (m_routing.DeleteRoutingHdl(wan_route_rule_v6_hdl_a5[0], IPA_IP_v6) == false)
@@ -4149,14 +4887,7 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype)
if (iptype == IPA_IP_v4)
{
wandown_data->ipv4_addr = wan_v4_addr;
- if (m_is_sta_mode!=Q6_WAN)
- {
- wandown_data->is_sta = true;
- }
- else
- {
- wandown_data->is_sta = false;
- }
+ wandown_data->backhaul_type = m_is_sta_mode;
evt_data.event = IPA_HANDLE_WAN_DOWN;
evt_data.evt_data = (void *)wandown_data;
/* Insert IPA_HANDLE_WAN_DOWN to command queue */
@@ -4178,17 +4909,30 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype)
{
memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name));
}
- }
- else
- {
- if (m_is_sta_mode!=Q6_WAN)
+
+ /* Delete MHI frag rule */
+ if(delete_offload_frag_rule())
+ {
+ IPACMERR("Failed to delete DL frag rule \n");
+ return IPACM_FAILURE;
+ }
+ /* Delete MHI icmpv6 exception rule */
+ if(delete_icmpv6_exception_rule())
{
- wandown_data->is_sta = true;
+ IPACMERR("Failed to delete icmpv6 rule \n");
+ return IPACM_FAILURE;
}
- else
+ /* Delete tcp_fin_rst rule */
+ if(delete_tcp_fin_rst_exception_rule())
{
- wandown_data->is_sta = false;
+ IPACMERR("Failed to delete tcp_fin_rst rule \n");
+ return IPACM_FAILURE;
}
+ }
+ else
+ {
+
+ wandown_data->backhaul_type = m_is_sta_mode;
memcpy(wandown_data->ipv6_prefix, ipv6_prefix, sizeof(wandown_data->ipv6_prefix));
evt_data.event = IPA_HANDLE_WAN_DOWN_V6;
evt_data.evt_data = (void *)wandown_data;
@@ -4294,14 +5038,7 @@ int IPACM_Wan::handle_route_del_evt_ex(ipa_ip_type iptype)
if (iptype == IPA_IP_v4)
{
wandown_data->ipv4_addr = wan_v4_addr;
- if (m_is_sta_mode!=Q6_WAN)
- {
- wandown_data->is_sta = true;
- }
- else
- {
- wandown_data->is_sta = false;
- }
+ wandown_data->backhaul_type = m_is_sta_mode;
evt_data.event = IPA_HANDLE_WAN_DOWN;
evt_data.evt_data = (void *)wandown_data;
/* Insert IPA_HANDLE_WAN_DOWN to command queue */
@@ -4322,14 +5059,8 @@ int IPACM_Wan::handle_route_del_evt_ex(ipa_ip_type iptype)
}
else
{
- if (m_is_sta_mode!=Q6_WAN)
- {
- wandown_data->is_sta = true;
- }
- else
- {
- wandown_data->is_sta = false;
- }
+
+ wandown_data->backhaul_type = m_is_sta_mode;
memcpy(wandown_data->ipv6_prefix, ipv6_prefix, sizeof(wandown_data->ipv6_prefix));
evt_data.event = IPA_HANDLE_WAN_DOWN_V6;
evt_data.evt_data = (void *)wandown_data;
@@ -4522,6 +5253,18 @@ int IPACM_Wan::handle_down_evt()
handle_route_del_evt(IPA_IP_v4);
IPACMDBG_H("Delete default v4 routing rules\n");
+ if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ /* Delete default v4 RT rule */
+ IPACMDBG_H("Delete default v4 routing rules\n");
+ if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing v6-lan-RT rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+
#ifdef FEATURE_IPA_ANDROID
/* posting wan_down_tether for lan clients */
#ifdef FEATURE_IPACM_HAL
@@ -4551,6 +5294,19 @@ int IPACM_Wan::handle_down_evt()
}
handle_route_del_evt(IPA_IP_v6);
IPACMDBG_H("Delete default v6 routing rules\n");
+
+ if(m_is_sta_mode == Q6_MHI_WAN)
+ {
+ /* Delete default v6 RT rule */
+ IPACMDBG_H("Delete default v6 routing rules\n");
+ if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[1], IPA_IP_v6) == false)
+ {
+ IPACMERR("Routing v6-wan-RT rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+
#ifdef FEATURE_IPA_ANDROID
/* posting wan_down_tether for lan clients */
#ifdef FEATURE_IPACM_HAL
@@ -4572,26 +5328,14 @@ int IPACM_Wan::handle_down_evt()
#endif
}
- /* Delete default v4 RT rule */
- if (ip_type != IPA_IP_v6)
- {
- IPACMDBG_H("Delete default v4 routing rules\n");
- if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
- {
- IPACMERR("Routing rule deletion failed!\n");
- res = IPACM_FAILURE;
- goto fail;
- }
- }
-
- /* delete default v6 RT rule */
- if (ip_type != IPA_IP_v4)
+ if(m_is_sta_mode != Q6_MHI_WAN)
{
- IPACMDBG_H("Delete default v6 routing rules\n");
- /* May have multiple ipv6 iface-routing rules*/
- for (i = 0; i < 2*num_dft_rt_v6; i++)
+ /* Delete default v4 RT rule */
+ if (ip_type != IPA_IP_v6)
{
- if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
+ /* no need delete v4 RSC routing rules */
+ IPACMDBG_H("Delete default v4 routing rules\n");
+ if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
{
IPACMERR("Routing rule deletion failed!\n");
res = IPACM_FAILURE;
@@ -4599,130 +5343,143 @@ int IPACM_Wan::handle_down_evt()
}
}
- IPACMDBG_H("finished delete default v6 RT rules\n ");
- }
-
-
- /* clean wan-client header, routing rules */
- IPACMDBG_H("left %d wan clients need to be deleted \n ", num_wan_client);
- for (i = 0; i < num_wan_client; i++)
- {
- /* Del NAT rules before ipv4 RT rules are delete */
- if(get_client_memptr(wan_client, i)->ipv4_set == true)
+ /* delete default v6 RT rule */
+ if (ip_type != IPA_IP_v4)
+ {
+ IPACMDBG_H("Delete default v6 routing rules\n");
+ /* May have multiple ipv6 iface-routing rules*/
+ for (i = 0; i < 2*num_dft_rt_v6; i++)
{
- IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wan_client, i)->v4_addr);
- CtList->HandleSTAClientDelEvt(get_client_memptr(wan_client, i)->v4_addr);
+ if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
}
+ IPACMDBG_H("finished delete default v6 RT rules\n ");
+ }
+ /* clean wan-client header, routing rules */
+ IPACMDBG_H("left %d wan clients need to be deleted \n ", num_wan_client);
+ for (i = 0; i < num_wan_client; i++)
+ {
+ /* Del NAT rules before ipv4 RT rules are delete */
+ if(get_client_memptr(wan_client, i)->ipv4_set == true)
+ {
+ IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wan_client, i)->v4_addr);
+ CtList->HandleSTAClientDelEvt(get_client_memptr(wan_client, i)->v4_addr);
+ }
- if (delete_wan_rtrules(i, IPA_IP_v4))
+ if (delete_wan_rtrules(i, IPA_IP_v4))
+ {
+ IPACMERR("unbale to delete wan-client v4 route rules for index %d\n", i);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if (delete_wan_rtrules(i, IPA_IP_v6))
+ {
+ IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i);
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ IPACMDBG_H("Delete %d client header\n", num_wan_client);
+ if(get_client_memptr(wan_client, i)->ipv4_header_set == true)
+ {
+ if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, i)->hdr_hdl_v4)
+ == false)
+ {
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ if(get_client_memptr(wan_client, i)->ipv6_header_set == true)
+ {
+ if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, i)->hdr_hdl_v6)
+ == false)
+ {
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+ } /* end of for loop */
+ /* free the edm clients cache */
+ IPACMDBG_H("Free wan clients cache\n");
+
+ /* check software routing fl rule hdl */
+ if (softwarerouting_act == true)
+ {
+ if(m_is_sta_mode == Q6_MHI_WAN)
{
- IPACMERR("unbale to delete wan-client v4 route rules for index %d\n", i);
- res = IPACM_FAILURE;
- goto fail;
+ handle_software_routing_disable(true);
}
-
- if (delete_wan_rtrules(i, IPA_IP_v6))
+ else
{
- IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i);
- res = IPACM_FAILURE;
- goto fail;
+ handle_software_routing_disable(false);
}
-
- IPACMDBG_H("Delete %d client header\n", num_wan_client);
-
-
- if(get_client_memptr(wan_client, i)->ipv4_header_set == true)
+ }
+ /* free dft ipv4 filter rule handlers if any */
+ if (ip_type != IPA_IP_v6 && rx_prop != NULL)
+ {
+ if (dft_v4fl_rule_hdl[0] != 0)
{
- if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, i)->hdr_hdl_v4)
- == false)
+ if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl,
+ IPA_IP_v4,
+ IPV4_DEFAULT_FILTERTING_RULES) == false)
{
+ IPACMERR("Error Delete Filtering rules, aborting...\n");
res = IPACM_FAILURE;
goto fail;
}
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
+ IPACMDBG_H("finished delete default v4 filtering rules\n ");
}
-
- if(get_client_memptr(wan_client, i)->ipv6_header_set == true)
- {
- if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, i)->hdr_hdl_v6)
- == false)
+ }
+ /* free dft ipv6 filter rule handlers if any */
+ if (ip_type != IPA_IP_v4 && rx_prop != NULL)
+ {
+ if (dft_v6fl_rule_hdl[0] != 0)
{
- res = IPACM_FAILURE;
- goto fail;
- }
+ if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl,
+ IPA_IP_v6,
+ IPV6_DEFAULT_FILTERTING_RULES) == false)
+ {
+ IPACMERR("ErrorDeleting Filtering rule, aborting...\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
}
- } /* end of for loop */
-
- /* free the edm clients cache */
- IPACMDBG_H("Free wan clients cache\n");
-
- /* check software routing fl rule hdl */
- if (softwarerouting_act == true)
- {
- handle_software_routing_disable();
- }
-
- /* free dft ipv4 filter rule handlers if any */
- if (ip_type != IPA_IP_v6 && rx_prop != NULL)
- {
- if (dft_v4fl_rule_hdl[0] != 0)
- {
- if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl,
- IPA_IP_v4,
- IPV4_DEFAULT_FILTERTING_RULES) == false)
+ if(num_ipv6_dest_flt_rule > 0 && num_ipv6_dest_flt_rule <= MAX_DEFAULT_v6_ROUTE_RULES)
{
- IPACMERR("Error Delete Filtering rules, aborting...\n");
- res = IPACM_FAILURE;
- goto fail;
+ if(m_filtering.DeleteFilteringHdls(ipv6_dest_flt_rule_hdl, IPA_IP_v6, num_ipv6_dest_flt_rule) == false)
+ {
+ IPACMERR("Failed to delete ipv6 dest flt rules.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_ipv6_dest_flt_rule);
}
- IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES);
- IPACMDBG_H("finished delete default v4 filtering rules\n ");
+ IPACMDBG_H("finished delete default v6 filtering rules\n ");
}
- }
-
- /* free dft ipv6 filter rule handlers if any */
- if (ip_type != IPA_IP_v4 && rx_prop != NULL)
- {
- if (dft_v6fl_rule_hdl[0] != 0)
+ if(hdr_proc_hdl_dummy_v6)
{
- if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl,
- IPA_IP_v6,
- IPV6_DEFAULT_FILTERTING_RULES) == false)
+ if(m_header.DeleteHeaderProcCtx(hdr_proc_hdl_dummy_v6) == false)
{
- IPACMERR("ErrorDeleting Filtering rule, aborting...\n");
+ IPACMERR("Failed to delete hdr_proc_hdl_dummy_v6\n");
res = IPACM_FAILURE;
goto fail;
}
- IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES);
}
-
- if(num_ipv6_dest_flt_rule > 0 && num_ipv6_dest_flt_rule <= MAX_DEFAULT_v6_ROUTE_RULES)
+ if(hdr_hdl_dummy_v6)
{
- if(m_filtering.DeleteFilteringHdls(ipv6_dest_flt_rule_hdl, IPA_IP_v6, num_ipv6_dest_flt_rule) == false)
+ if (m_header.DeleteHeaderHdl(hdr_hdl_dummy_v6) == false)
{
- IPACMERR("Failed to delete ipv6 dest flt rules.\n");
+ IPACMERR("Failed to delete hdr_hdl_dummy_v6\n");
res = IPACM_FAILURE;
goto fail;
}
- IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_ipv6_dest_flt_rule);
- }
- IPACMDBG_H("finished delete default v6 filtering rules\n ");
- }
- if(hdr_proc_hdl_dummy_v6)
- {
- if(m_header.DeleteHeaderProcCtx(hdr_proc_hdl_dummy_v6) == false)
- {
- IPACMERR("Failed to delete hdr_proc_hdl_dummy_v6\n");
- res = IPACM_FAILURE;
- goto fail;
- }
- }
- if(hdr_hdl_dummy_v6)
- {
- if (m_header.DeleteHeaderHdl(hdr_hdl_dummy_v6) == false)
- {
- IPACMERR("Failed to delete hdr_hdl_dummy_v6\n");
- res = IPACM_FAILURE;
- goto fail;
}
}
fail:
@@ -4845,6 +5602,21 @@ int IPACM_Wan::handle_down_evt_ex()
install_wan_filtering_rule(false);
}
+ IPACMDBG_H("Delete default v4 coalesce routing rules\n");
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing rule RSC TCP deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing rule RSB UDP deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
{
IPACMERR("Routing rule deletion failed!\n");
@@ -4903,6 +5675,13 @@ int IPACM_Wan::handle_down_evt_ex()
for (i = 0; i < 2*num_dft_rt_v6; i++)
{
+ /* delete v6 colasce rules */
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Colasce Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
{
IPACMERR("Routing rule deletion failed!\n");
@@ -4987,6 +5766,21 @@ int IPACM_Wan::handle_down_evt_ex()
install_wan_filtering_rule(false);
}
+ IPACMDBG_H("Delete default v4 coalesce routing rules\n");
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing rule RSC TCP deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing rule RSB UDP deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
{
IPACMERR("Routing rule deletion failed!\n");
@@ -4996,6 +5790,13 @@ int IPACM_Wan::handle_down_evt_ex()
for (i = 0; i < 2*num_dft_rt_v6; i++)
{
+ /* delete v6 colasce rules */
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Colasce Routing rule deletion failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
{
IPACMERR("Routing rule deletion failed!\n");
@@ -5005,11 +5806,11 @@ int IPACM_Wan::handle_down_evt_ex()
}
}
- /* check software routing fl rule hdl */
- if (softwarerouting_act == true)
- {
- handle_software_routing_disable();
- }
+// /* check software routing fl rule hdl */
+// if (softwarerouting_act == true)
+// {
+// handle_software_routing_disable();
+// }
fail:
if (tx_prop != NULL)
@@ -5316,57 +6117,6 @@ fail:
return res;
}
-void IPACM_Wan::change_to_network_order(ipa_ip_type iptype, ipa_rule_attrib* attrib)
-{
- if(attrib == NULL)
- {
- IPACMERR("Attribute pointer is NULL.\n");
- return;
- }
-
- if(iptype == IPA_IP_v6)
- {
- int i;
- for(i=0; i<4; i++)
- {
- attrib->u.v6.src_addr[i] = htonl(attrib->u.v6.src_addr[i]);
- attrib->u.v6.src_addr_mask[i] = htonl(attrib->u.v6.src_addr_mask[i]);
- attrib->u.v6.dst_addr[i] = htonl(attrib->u.v6.dst_addr[i]);
- attrib->u.v6.dst_addr_mask[i] = htonl(attrib->u.v6.dst_addr_mask[i]);
- }
- }
- else
- {
- IPACMDBG_H("IP type is not IPv6, do nothing: %d\n", iptype);
- }
-
- return;
-}
-
-bool IPACM_Wan::is_global_ipv6_addr(uint32_t* ipv6_addr)
-{
- if(ipv6_addr == NULL)
- {
- IPACMERR("IPv6 address is empty.\n");
- return false;
- }
- IPACMDBG_H("Get ipv6 address with first word 0x%08x.\n", ipv6_addr[0]);
-
- uint32_t ipv6_link_local_prefix, ipv6_link_local_prefix_mask;
- ipv6_link_local_prefix = 0xFE800000;
- ipv6_link_local_prefix_mask = 0xFFC00000;
- if((ipv6_addr[0] & ipv6_link_local_prefix_mask) == (ipv6_link_local_prefix & ipv6_link_local_prefix_mask))
- {
- IPACMDBG_H("This IPv6 address is link local.\n");
- return false;
- }
- else
- {
- IPACMDBG_H("This IPv6 address is not link local.\n");
- return true;
- }
-}
-
/* handle STA WAN-client */
/* handle WAN client initial, construct full headers (tx property) */
int IPACM_Wan::handle_wan_hdr_init(uint8_t *mac_addr)
@@ -6430,3 +7180,736 @@ int IPACM_Wan::add_dummy_rx_hdr()
}
return IPACM_SUCCESS;
}
+
+int IPACM_Wan::handle_coalesce_evt()
+{
+ struct ipa_ioc_add_rt_rule *rt_rule = NULL;
+ struct ipa_rt_rule_add *rt_rule_entry;
+ const int NUM_RULES = 1;
+ int res = IPACM_SUCCESS;
+ struct ipa_ioc_get_hdr hdr;
+ uint32_t i;
+
+ if(wan_v4_addr_set)
+ {
+ /* Delete default RSC v4 RT rule */
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RSC TCP RT rule deletion failed!\n");
+ return IPACM_FAILURE;
+ }
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[1], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RSB UDP RT rule deletion failed!\n");
+ return IPACM_FAILURE;
+ }
+ /* Delete default v4 RT rule */
+ IPACMDBG_H("Delete default v4 routing rules\n");
+ if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false)
+ {
+ IPACMERR("Routing old RT rule deletion failed!\n");
+ return IPACM_FAILURE;
+ }
+
+ /* apply the new coalesce configuration */
+ rt_rule = (struct ipa_ioc_add_rt_rule *)
+ calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
+ NUM_RULES * sizeof(struct ipa_rt_rule_add));
+ if (!rt_rule)
+ {
+ IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
+ rt_rule->commit = 1;
+ rt_rule->num_rules = NUM_RULES;
+ rt_rule->ip = IPA_IP_v4;
+ rt_rule_entry = &rt_rule->rules[0];
+ rt_rule_entry->at_rear = false;
+ rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
+ /* still need setup v4 default routing rule to APPs*/
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name));
+ rt_rule_entry->rule.attrib.u.v4.dst_addr = wan_v4_addr;
+ rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF;
+#ifdef FEATURE_IPA_V3
+ rt_rule_entry->rule.hashable = false;
+#endif
+ /* query qmap header*/
+ memset(&hdr, 0, sizeof(hdr));
+ strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
+ hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
+ if(m_header.GetHeaderHandle(&hdr) == false)
+ {
+ IPACMERR("Failed to get QMAP header.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ rt_rule_entry->rule.hdr_hdl = hdr.hdl;
+ rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
+ /* default v4 rt-rule */
+#ifdef IPA_RT_SUPPORT_COAL
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ /* default v4 rt-rule */
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail;
+ }
+ dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]);
+
+ /* RSC TCP rule*/
+ rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL;
+ rt_rule_entry->rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
+#ifdef IPA_RT_SUPPORT_COAL
+ if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
+ rt_rule_entry->rule.coalesce = true;
+ else
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rsc tcp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail;
+ }
+ dft_coalesce_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv4 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[0],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable);
+
+ /* RSB UDP rule*/
+ rt_rule_entry->rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_UDP;
+#ifdef IPA_RT_SUPPORT_COAL
+ if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
+ rt_rule_entry->rule.coalesce = true;
+ else
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rsb udp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail;
+ }
+ dft_coalesce_rt_rule_hdl[1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv4 wan iface rsb udp rt-rule hdll=0x%x enable(%d)\n", dft_coalesce_rt_rule_hdl[1],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable);
+fail:
+ free(rt_rule);
+ }
+ /* v6 */
+ if (num_dft_rt_v6 !=0)
+ {
+ for (i = 0; i < 2*num_dft_rt_v6; i++)
+ {
+ /* delete v6 colasce rules */
+ if (m_routing.DeleteRoutingHdl(dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Colasce Routing rule deletion failed!\n");
+ return IPACM_FAILURE;
+ }
+ /* delete v6 default rules */
+ if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false)
+ {
+ IPACMERR("Routing rule deletion failed!\n");
+ return IPACM_FAILURE;
+ }
+ }
+
+ rt_rule = (struct ipa_ioc_add_rt_rule *)
+ calloc(1, sizeof(struct ipa_ioc_add_rt_rule) +
+ NUM_RULES * sizeof(struct ipa_rt_rule_add));
+ if (!rt_rule)
+ {
+ IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
+ rt_rule->commit = 1;
+ rt_rule->num_rules = NUM_RULES;
+ rt_rule->ip = IPA_IP_v6;
+
+ for (i = 0; i < num_dft_rt_v6; i++)
+ {
+ /* setup same rule for v6_wan table */
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name));
+ rt_rule_entry = &rt_rule->rules[0];
+ rt_rule_entry->at_rear = false;
+ rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR;
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = ipv6_addr[num_dft_rt_v6][0];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = ipv6_addr[num_dft_rt_v6][1];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = ipv6_addr[num_dft_rt_v6][2];
+ rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = ipv6_addr[num_dft_rt_v6][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 = false;
+#endif
+ strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name));
+ hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
+ if(m_header.GetHeaderHandle(&hdr) == false)
+ {
+ IPACMERR("Failed to get QMAP header.\n");
+ return IPACM_FAILURE;
+ }
+ rt_rule_entry->rule.hdr_hdl = hdr.hdl;
+ rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS;
+ /* legacy default v4 rt-rule */
+#ifdef IPA_RT_SUPPORT_COAL
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ /* legacy default v6 rt-rule */
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail2;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail2;
+ }
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*i] = rt_rule_entry->rt_rule_hdl;
+
+ /* setup same rule for v6_lan table*/
+ strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name));
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail2;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail2;
+ }
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, entry: %d %d\n",
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*i],
+ dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1],
+ MAX_DEFAULT_v4_ROUTE_RULES + 2*i,
+ MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1);
+ /* RSC TCP rule*/
+ rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
+ rt_rule_entry->rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_TCP;
+#ifdef IPA_RT_SUPPORT_COAL
+ if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable)
+ rt_rule_entry->rule.coalesce = true;
+ else
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail2;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rsc tcp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail2;
+ }
+ dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*i] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv6 wan iface rsc tcp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*i],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_tcp_enable);
+ /* RSB UDP rule*/
+ rt_rule_entry->rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_UDP;
+#ifdef IPA_RT_SUPPORT_COAL
+ if (IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable)
+ rt_rule_entry->rule.coalesce = true;
+ else
+ rt_rule_entry->rule.coalesce = false;
+#endif
+ if (false == m_routing.AddRoutingRule(rt_rule))
+ {
+ IPACMERR("Routing rule addition failed!\n");
+ res = IPACM_FAILURE;
+ goto fail2;
+ }
+ else if (rt_rule_entry->status)
+ {
+ IPACMERR("rsb udp rt rule adding failed. Result=%d\n", rt_rule_entry->status);
+ res = rt_rule_entry->status;
+ goto fail2;
+ }
+ dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1] = rt_rule_entry->rt_rule_hdl;
+ IPACMDBG_H("ipv6 wan iface rsb udp rt-rule hdll=0x%x\n enable(%d)", dft_coalesce_rt_rule_hdl[2*MAX_DEFAULT_v4_ROUTE_RULES + 2*i+1],
+ IPACM_Wan::coalesce_enable_info[ext_prop->ext[0].mux_id].coalesce_udp_enable);
+ }
+fail2:
+ free(rt_rule);
+ }
+ return res;
+}
+
+int IPACM_Wan::add_offload_frag_rule()
+{
+ int fd;
+ int len, res = IPACM_SUCCESS;
+ uint8_t mux_id;
+ ipa_ioc_add_flt_rule *pFilteringTable = NULL;
+
+ mux_id = ext_prop->ext[0].mux_id;
+ /* contruct filter rules to pcie modem */
+ struct ipa_flt_rule_add flt_rule_entry;
+ ipa_ioc_generate_flt_eq flt_eq;
+
+ /* construct rule */
+ IPACMDBG_H("adding MHi frag rule\n");
+ len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
+ pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->global = false;
+ pFilteringTable->ip = IPA_IP_v4;
+ pFilteringTable->num_rules = (uint8_t)1;
+
+ /* Configuring Fragment Filtering Rule */
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
+ flt_rule_entry.at_rear = false;
+ flt_rule_entry.flt_rule_hdl = -1;
+ flt_rule_entry.status = -1;
+
+ flt_rule_entry.rule.retain_hdr = 1;
+ flt_rule_entry.rule.to_uc = 0;
+ flt_rule_entry.rule.eq_attrib_type = 1;
+ flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
+#ifdef FEATURE_IPA_V3
+ flt_rule_entry.rule.hashable = true;
+#endif
+ IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask);
+ memcpy(&flt_rule_entry.rule.attrib,
+ &rx_prop->rx[0].attrib,
+ sizeof(flt_rule_entry.rule.attrib));
+
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT;
+
+ /* generate eq */
+ memset(&flt_eq, 0, sizeof(flt_eq));
+ memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
+ flt_eq.ip = IPA_IP_v4;
+
+ fd = open(IPA_DEVICE_NAME, O_RDWR);
+ if (fd < 0)
+ {
+ IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
+ free(pFilteringTable);
+ return IPACM_FAILURE;
+ }
+
+ if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) //define and cpy attribute to this struct
+ {
+ IPACMERR("Failed to get eq_attrib\n");
+ goto fail;
+ }
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &flt_eq.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+ memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+
+ /* add rule */
+ if(false == m_filtering.AddOffloadFilteringRule(pFilteringTable, mux_id, 1))
+ {
+ IPACMERR("Failed to install WAN DL filtering table.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ /* save handle */
+ mhi_dl_v4_frag_hdl = pFilteringTable->rules[0].flt_rule_hdl;
+
+fail:
+ close(fd);
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int IPACM_Wan::delete_offload_frag_rule()
+{
+ int res = IPACM_SUCCESS;
+ int len;
+ ipa_ioc_del_flt_rule *pFilteringTable = NULL;
+
+ struct ipa_flt_rule_del flt_rule_entry;
+
+ IPACMDBG_H("deleting MHI frag rule \n");
+ len = sizeof(struct ipa_ioc_del_flt_rule) + sizeof(struct ipa_flt_rule_del);
+ pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
+ return false;
+ }
+ memset(pFilteringTable, 0, len);
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = IPA_IP_v4;
+ pFilteringTable->num_hdls = (uint8_t)1;
+
+ if (mhi_dl_v4_frag_hdl == 0)
+ {
+ IPACMERR("invalid dl_v4_frag_hdl.\n");
+ res = false;
+ goto fail;
+ }
+
+ /* Configuring Software-Routing Filtering Rule */
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
+ flt_rule_entry.hdl = mhi_dl_v4_frag_hdl;
+
+ memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
+
+ if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Failed to delete DL offload frag rule.\n");
+ res = false;
+ goto fail;
+ }
+ mhi_dl_v4_frag_hdl = 0;
+
+fail:
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int IPACM_Wan::add_icmpv6_exception_rule()
+{
+ int fd;
+ int len, res = IPACM_SUCCESS;
+ uint8_t mux_id;
+ ipa_ioc_add_flt_rule *pFilteringTable = NULL;
+
+ mux_id = ext_prop->ext[0].mux_id;
+ /* contruct filter rules to pcie modem */
+ struct ipa_flt_rule_add flt_rule_entry;
+ ipa_ioc_generate_flt_eq flt_eq;
+
+ /* construct rule */
+ IPACMDBG_H("adding MHI icmpv6 rule\n");
+ len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
+ pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->global = false;
+ pFilteringTable->ip = IPA_IP_v6;
+ pFilteringTable->num_rules = (uint8_t)1;
+
+ /* Configuring ICMPv6 Filtering Rule */
+ 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 = false;
+ flt_rule_entry.flt_rule_hdl = -1;
+ flt_rule_entry.status = -1;
+ flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
+#ifdef FEATURE_IPA_V3
+ flt_rule_entry.rule.hashable = true;
+#endif
+ IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask);
+ memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib));
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
+ flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6;
+
+ /* generate eq */
+ memset(&flt_eq, 0, sizeof(flt_eq));
+ memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
+ flt_eq.ip = IPA_IP_v6;
+
+ fd = open(IPA_DEVICE_NAME, O_RDWR);
+ if (fd < 0)
+ {
+ IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
+ free(pFilteringTable);
+ return IPACM_FAILURE;
+ }
+
+ if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) //define and cpy attribute to this struct
+ {
+ IPACMERR("Failed to get eq_attrib\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &flt_eq.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+ memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+
+ /* add rule */
+ if(false == m_filtering.AddOffloadFilteringRule(pFilteringTable, mux_id, 1))
+ {
+ IPACMERR("Failed to install WAN DL filtering table.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ /* save handle */
+ icmpv6_exception_hdl = pFilteringTable->rules[0].flt_rule_hdl;
+
+fail:
+ close(fd);
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int IPACM_Wan::delete_icmpv6_exception_rule()
+{
+ int len, res = IPACM_SUCCESS;
+ ipa_ioc_del_flt_rule *pFilteringTable = NULL;
+
+ struct ipa_flt_rule_del flt_rule_entry;
+
+ IPACMDBG_H("deleting MHI icmpv6 rule \n");
+ len = sizeof(struct ipa_ioc_del_flt_rule) + sizeof(struct ipa_flt_rule_del);
+ pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = IPA_IP_v6;
+ pFilteringTable->num_hdls = (uint8_t)1;
+
+ if (icmpv6_exception_hdl == 0)
+ {
+ IPACMERR("invalid icmpv6_exception_hdl.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
+ flt_rule_entry.hdl = icmpv6_exception_hdl;
+
+ memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
+
+ if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Failed to delete MHI icmpv6 rule.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ icmpv6_exception_hdl = 0;
+
+fail:
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int IPACM_Wan::add_tcp_fin_rst_exception_rule()
+{
+ int fd;
+ int len, res = IPACM_SUCCESS;
+ uint8_t mux_id;
+ ipa_ioc_add_flt_rule *pFilteringTable = NULL;
+
+ mux_id = ext_prop->ext[0].mux_id;
+ /* contruct filter rules to pcie modem */
+ struct ipa_flt_rule_add flt_rule_entry;
+ ipa_ioc_generate_flt_eq flt_eq;
+
+ /* construct rule */
+ IPACMDBG_H("adding MHI TCP FIN RST rule\n");
+ len = sizeof(struct ipa_ioc_add_flt_rule) + (2 * sizeof(struct ipa_flt_rule_add));
+ pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->global = false;
+ pFilteringTable->ip = IPA_IP_v4;
+ pFilteringTable->num_rules = (uint8_t)2;
+
+ /* Configuring TCP FIN RST Filtering Rule */
+ 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 = false;
+ flt_rule_entry.flt_rule_hdl = -1;
+ flt_rule_entry.status = -1;
+ flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
+ /*
+ * need this since fin is last packet in an ongoing TCP connection
+ * so it will always match the previous hash and take MHIP path
+ */
+ flt_rule_entry.rule.hashable = false;
+
+ IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask);
+ memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, 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_TCP;
+
+ /* generate eq */
+ memset(&flt_eq, 0, sizeof(flt_eq));
+ memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
+ flt_eq.ip = IPA_IP_v4;
+
+ fd = open(IPA_DEVICE_NAME, O_RDWR);
+ if (fd < 0)
+ {
+ IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
+ free(pFilteringTable);
+ return IPACM_FAILURE;
+ }
+
+ if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) //define and cpy attribute to this struct
+ {
+ IPACMERR("Failed to get eq_attrib\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &flt_eq.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+
+ /* set the bit mask to use MEQ32_IHL offset */
+ #ifdef FEATURE_IPA_V3
+ flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<7);
+ #else
+ flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<8);
+ #endif
+
+ /* add offset to compare TCP flags */
+ flt_rule_entry.rule.eq_attrib.num_ihl_offset_meq_32 = 1;
+ flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12;
+
+ /* add TCP FIN RULE */
+ flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_FIN_SHIFT);
+ flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_FIN_SHIFT);
+ memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+
+ /* add TCP RST rule*/
+ flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_RST_SHIFT);
+ flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_RST_SHIFT);
+ memcpy(&(pFilteringTable->rules[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+
+ /* add rules */
+ if(false == m_filtering.AddOffloadFilteringRule(pFilteringTable, mux_id, 1))
+ {
+ IPACMERR("Failed to install WAN DL filtering table.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ /* save handle */
+ tcp_fin_hdl = pFilteringTable->rules[0].flt_rule_hdl;
+ tcp_rst_hdl = pFilteringTable->rules[1].flt_rule_hdl;
+
+fail:
+ close(fd);
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int IPACM_Wan::delete_tcp_fin_rst_exception_rule()
+{
+ int len, res = IPACM_SUCCESS;
+ ipa_ioc_del_flt_rule *pFilteringTable = NULL;
+
+ struct ipa_flt_rule_del flt_rule_entry;
+
+ IPACMDBG_H("deleting MHI TCP FIN RST rule \n");
+ len = sizeof(struct ipa_ioc_del_flt_rule) + (2 * sizeof(struct ipa_flt_rule_del));
+ pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = IPA_IP_v4;
+ pFilteringTable->num_hdls = (uint8_t)2;
+
+ if (tcp_fin_hdl == 0 || tcp_rst_hdl == 0)
+ {
+ IPACMERR("invalid tcp_fin_rst_hdl.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
+ flt_rule_entry.hdl = tcp_fin_hdl;
+
+ memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
+
+ flt_rule_entry.hdl = tcp_rst_hdl;
+
+ memcpy(&(pFilteringTable->hdl[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
+
+ if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Failed to delete MHI TCP FIN RST rule.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ tcp_fin_hdl = 0;
+ tcp_rst_hdl = 0;
+
+fail:
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 427aef3..395f951 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -295,7 +295,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
{
if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX)
{
- if(IPACM_Wan::backhaul_is_sta_mode == false)
+ if(IPACM_Wan::backhaul_mode == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4,
@@ -318,7 +318,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
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)
+ if(IPACM_Wan::backhaul_mode == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
@@ -350,7 +350,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
{
/* handle software routing enable event*/
IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name);
- handle_software_routing_enable();
+ handle_software_routing_enable(false);
}
}
}
@@ -366,7 +366,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No event data is found.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s xlat_mux_id: %d\n", data_wan_tether->is_sta,
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s xlat_mux_id: %d\n", data_wan_tether->backhaul_type,
data_wan_tether->if_index_tether,
IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name,
data_wan_tether->xlat_mux_id);
@@ -387,7 +387,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
if(is_downstream_set[IPA_IP_v4] == true)
{
IPACMDBG_H("Downstream was set before, adding UL rules.\n");
- if(data_wan_tether->is_sta == false)
+ if(data_wan_tether->backhaul_type == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
handle_wan_up_ex(ext_prop, IPA_IP_v4,
@@ -398,7 +398,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
}
}
#else
- if(data_wan_tether->is_sta == false)
+ if(data_wan_tether->backhaul_type == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
handle_wan_up_ex(ext_prop, IPA_IP_v4, 0);
@@ -418,7 +418,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No event data is found.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->backhaul_type,
data_wan_tether->if_index_tether,
IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
#ifndef FEATURE_IPACM_HAL
@@ -441,7 +441,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("Downstream was set before, adding UL rules.\n");
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)
+ if(data_wan_tether->backhaul_type == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
@@ -453,7 +453,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
}
}
#else
- if(data_wan_tether->is_sta == false)
+ if(data_wan_tether->backhaul_type == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
@@ -479,7 +479,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No rx prop.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->backhaul_type,
data_wan_tether->if_index_tether,
IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
#ifndef FEATURE_IPACM_HAL
@@ -499,11 +499,11 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
if(is_downstream_set[IPA_IP_v4] == true)
{
IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
- handle_wan_down(data_wan_tether->is_sta);
+ handle_wan_down(data_wan_tether->backhaul_type);
}
}
#else
- handle_wan_down(data_wan_tether->is_sta);
+ handle_wan_down(data_wan_tether->backhaul_type);
#endif
}
break;
@@ -521,7 +521,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No rx prop.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta,
+ IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->backhaul_type,
data_wan_tether->if_index_tether,
IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name);
#ifndef FEATURE_IPACM_HAL
@@ -543,13 +543,13 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("Downstream was set before, deleting UL rules.\n");
/* reset usb-client ipv6 rt-rules */
handle_wlan_client_reset_rt(IPA_IP_v6);
- handle_wan_down_v6(data_wan_tether->is_sta);
+ handle_wan_down_v6(data_wan_tether->backhaul_type);
}
}
#else
/* reset usb-client ipv6 rt-rules */
handle_wlan_client_reset_rt(IPA_IP_v6);
- handle_wan_down_v6(data_wan_tether->is_sta);
+ handle_wan_down_v6(data_wan_tether->backhaul_type);
#endif
}
break;
@@ -561,6 +561,25 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
if(ipa_interface_index == ipa_if_num)
{
IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n");
+#ifdef FEATURE_IPA_ANDROID
+ if (IPACM_Wan::isXlat() && (data->prefix.iptype == IPA_IP_v4))
+ {
+ /* indicate v4-offload */
+ IPACM_OffloadManager::num_offload_v4_tethered_iface++;
+ IPACMDBG_H("in xlat: update num_offload_v4_tethered_iface %d\n", IPACM_OffloadManager::num_offload_v4_tethered_iface);
+
+ /* xlat not support for 2st tethered iface */
+ if (IPACM_OffloadManager::num_offload_v4_tethered_iface > 1)
+ {
+ IPACMDBG_H("Not support 2st downstream iface %s for xlat, cur: %d\n", dev_name,
+ IPACM_OffloadManager::num_offload_v4_tethered_iface);
+ return;
+ }
+ }
+
+ IPACMDBG_H(" support downstream iface %s, cur %d\n", dev_name,
+ IPACM_OffloadManager::num_offload_v4_tethered_iface);
+#endif
if(data->prefix.iptype < IPA_IP_MAX && is_downstream_set[data->prefix.iptype] == false)
{
IPACMDBG_H("Add downstream for IP iptype %d.\n", data->prefix.iptype);
@@ -582,11 +601,12 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
install_ipv6_prefix_flt_rule(ipv6_prefix);
}
- if (IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
+ if (IPACM_Wan::backhaul_mode == Q6_WAN) /* LTE */
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(data->prefix.iptype);
if (data->prefix.iptype == IPA_IP_v4)
{
+ IPACMDBG_H("check getXlat_Mux_Id:%d\n", IPACM_Wan::getXlat_Mux_Id());
handle_wan_up_ex(ext_prop, data->prefix.iptype,
IPACM_Wan::getXlat_Mux_Id());
}
@@ -620,10 +640,10 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("Upstream was set before, deleting UL rules.\n");
if (data->prefix.iptype == IPA_IP_v4)
{
- handle_wan_down(IPACM_Wan::backhaul_is_sta_mode); /* LTE STA */
+ handle_wan_down(IPACM_Wan::backhaul_mode); /* LTE STA */
} else {
handle_wlan_client_reset_rt(IPA_IP_v6);
- handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode); /* LTE STA */
+ handle_wan_down_v6(IPACM_Wan::backhaul_mode); /* LTE STA */
}
}
}
@@ -640,10 +660,10 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No event data is found.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
+ IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
{
- if(data_wan->is_sta == false)
+ if(data_wan->backhaul_type == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4);
IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan->xlat_mux_id);
@@ -664,13 +684,13 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No event data is found.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
+ IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
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->backhaul_type == Q6_WAN)
{
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
IPACM_Lan::handle_wan_up_ex(ext_prop, IPA_IP_v6, 0);
@@ -690,12 +710,12 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMERR("No event data is found.\n");
return;
}
- IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta);
+ IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->backhaul_type);
if (rx_prop != NULL)
{
if(ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)
{
- handle_wan_down(data_wan->is_sta);
+ handle_wan_down(data_wan->backhaul_type);
}
}
break;
@@ -712,12 +732,12 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("Received IPA_WAN_V6_DOWN in WLAN-instance and need clean up client IPv6 address \n");
/* reset wifi-client ipv6 rt-rules */
handle_wlan_client_reset_rt(IPA_IP_v6);
- IPACMDBG_H("Backhaul is sta mode ? %d\n", data_wan->is_sta);
+ IPACMDBG_H("Backhaul is sta mode ? %d\n", data_wan->backhaul_type);
if (rx_prop != NULL)
{
if(ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)
{
- handle_wan_down_v6(data_wan->is_sta);
+ handle_wan_down_v6(data_wan->backhaul_type);
}
}
break;
@@ -845,13 +865,13 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
/* handle software routing enable event, iface will update softwarerouting_act to true*/
case IPA_SW_ROUTING_ENABLE:
IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n");
- IPACM_Iface::handle_software_routing_enable();
+ IPACM_Iface::handle_software_routing_enable(false);
break;
/* handle software routing disable event, iface will update softwarerouting_act to false*/
case IPA_SW_ROUTING_DISABLE:
IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n");
- IPACM_Iface::handle_software_routing_disable();
+ IPACM_Iface::handle_software_routing_disable(false);
break;
case IPA_WLAN_SWITCH_TO_SCC:
@@ -939,7 +959,7 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param)
IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n");
if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num))
{
- if(IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */
+ if(IPACM_Wan::backhaul_mode == Q6_WAN) /* LTE */
{
ipa_get_data_stats_resp_msg_v01 *data = (ipa_get_data_stats_resp_msg_v01 *)param;
if (data->ipa_stats_type != QMI_IPA_STATS_TYPE_PIPE_V01)
@@ -1441,6 +1461,7 @@ int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type ipt
uint32_t tx_index;
int wlan_index,v6_num;
const int NUM = 1;
+ bool result;
if(tx_prop == NULL)
{
@@ -1561,8 +1582,19 @@ int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type ipt
{
rt_rule_entry->rule.hashable = true;
}
-
- if (false == m_routing.AddRoutingRule(rt_rule))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_HW);
+ result = m_routing.AddRoutingRule_hw_index(rt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_HW);
+ } else {
+ result = m_routing.AddRoutingRule(rt_rule);
+ }
+#else
+ result = m_routing.AddRoutingRule(rt_rule);
+#endif
+ if (result == false)
{
IPACMERR("Routing rule addition failed!\n");
free(rt_rule);
@@ -1656,7 +1688,20 @@ int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type ipt
#ifdef FEATURE_IPA_V3
rt_rule_entry->rule.hashable = true;
#endif
- if (false == m_routing.AddRoutingRule(rt_rule))
+#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
+ /* use index hw-counter */
+ if(IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
+ {
+ IPACMDBG_H("hw-index-enable %d, counter %d\n", IPACM_Iface::ipacmcfg->hw_fnr_stats_support, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_HW);
+ result = m_routing.AddRoutingRule_hw_index(rt_rule, IPACM_Iface::ipacmcfg->hw_counter_offset + DL_HW);
+ } else {
+ result = m_routing.AddRoutingRule(rt_rule);
+ }
+#else
+ result = m_routing.AddRoutingRule(rt_rule);
+#endif
+
+ if (result == false)
{
IPACMERR("Routing rule addition failed!\n");
free(rt_rule);
@@ -1667,6 +1712,15 @@ int IPACM_Wlan::handle_wlan_client_route_rule(uint8_t *mac_addr, ipa_ip_type ipt
IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index,
get_client_memptr(wlan_client, wlan_index)->wifi_rt_hdl[tx_index].wifi_rt_rule_hdl_v6_wan[v6_num], iptype);
+
+ /* send client-v6 info to pcie modem only with global ipv6 with tx_index = 0 one time*/
+ if(is_global_ipv6_addr(get_client_memptr(wlan_client, wlan_index)->v6_addr[v6_num]) && (IPACM_Wan::backhaul_mode == Q6_MHI_WAN))
+ {
+ if (add_connection(wlan_index, v6_num))
+ {
+ IPACMERR("PCIE filter rule addition failed! (%d-client) %d v6-entry\n",wlan_index, v6_num);
+ }
+ }
}
}
@@ -1856,8 +1910,8 @@ int IPACM_Wlan::handle_down_evt()
/* delete wan filter rule */
if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL)
{
- IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
- IPACM_Lan::handle_wan_down(IPACM_Wan::backhaul_is_sta_mode);
+ IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_mode);
+ IPACM_Lan::handle_wan_down(IPACM_Wan::backhaul_mode);
#ifdef FEATURE_IPA_ANDROID
#ifndef FEATURE_IPACM_HAL
/* Clean-up tethered-iface list */
@@ -1868,8 +1922,8 @@ int IPACM_Wlan::handle_down_evt()
if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL)
{
- IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode);
- handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode);
+ IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_mode);
+ handle_wan_down_v6(IPACM_Wan::backhaul_mode);
#ifdef FEATURE_IPA_ANDROID
/* Clean-up tethered-iface list */
IPACM_Wan::delete_tether_iface(IPA_IP_v6, ipa_if_num);
@@ -2070,7 +2124,7 @@ fail:
if (softwarerouting_act == true && rx_prop != NULL )
{
IPACMDBG_H("Delete sw routing filtering rules\n");
- IPACM_Iface::handle_software_routing_disable();
+ IPACM_Iface::handle_software_routing_disable(false);
}
IPACMDBG_H("finished delete software-routing filtering rules\n ");
@@ -2411,3 +2465,148 @@ bool IPACM_Wlan::is_guest_ap()
{
return m_is_guest_ap;
}
+
+int IPACM_Wlan::add_connection(int client_index, int v6_num)
+{
+ int len, res = IPACM_SUCCESS;
+ uint8_t mux_id;
+ ipa_ioc_add_flt_rule *pFilteringTable = NULL;
+ int fd;
+
+ mux_id = IPACM_Iface::ipacmcfg->GetQmapId();
+ /* contruct filter rules to pcie modem */
+ struct ipa_flt_rule_add flt_rule_entry;
+ ipa_ioc_generate_flt_eq flt_eq;
+
+ IPACMDBG("\n");
+ len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add);
+ pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->global = false;
+ pFilteringTable->ip = IPA_IP_v6;
+ pFilteringTable->num_rules = (uint8_t)1;
+
+ /* Configuring Filtering Rule */
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
+ flt_rule_entry.at_rear = true;
+ flt_rule_entry.flt_rule_hdl = -1;
+ flt_rule_entry.status = -1;
+
+ flt_rule_entry.rule.retain_hdr = 1;
+ flt_rule_entry.rule.to_uc = 0;
+ flt_rule_entry.rule.eq_attrib_type = 1;
+ flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING;
+#ifdef FEATURE_IPA_V3
+ flt_rule_entry.rule.hashable = true;
+#endif
+ flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
+ flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][0];
+ flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][1];
+ flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][2];
+ flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][3];
+ 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] = 0xFFFFFFFF;
+ flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF;
+
+ IPACMDBG_H("ipv6 address got: 0x%x:%x:%x:%x\n", get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][0],
+ get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][1],
+ get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][2],
+ get_client_memptr(wlan_client, client_index)->v6_addr[v6_num][3]);
+
+ /* change to network order for modem */
+ change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib);
+
+ memset(&flt_eq, 0, sizeof(flt_eq));
+ memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib));
+ flt_eq.ip = IPA_IP_v6;
+
+ fd = open(IPA_DEVICE_NAME, O_RDWR);
+ if (fd < 0)
+ {
+ IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
+ free(pFilteringTable);
+ return IPACM_FAILURE;
+ }
+
+ if(0 != ioctl(fd, IPA_IOC_GENERATE_FLT_EQ, &flt_eq))
+ {
+ IPACMERR("Failed to get eq_attrib\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ memcpy(&flt_rule_entry.rule.eq_attrib,
+ &flt_eq.eq_attrib,
+ sizeof(flt_rule_entry.rule.eq_attrib));
+ memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
+
+ if(false == m_filtering.AddOffloadFilteringRule(pFilteringTable, mux_id, 0))
+ {
+ IPACMERR("Failed to install WAN DL filtering table.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+
+ get_client_memptr(wlan_client, client_index)->v6_rt_rule_id[v6_num] = pFilteringTable->rules[0].flt_rule_hdl;
+ IPACMDBG_H("%d-st client v6_num %d: id handle 0x%x\n", client_index, v6_num, get_client_memptr(wlan_client, client_index)->v6_rt_rule_id[v6_num]);
+
+fail:
+ close(fd);
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
+
+int IPACM_Wlan::del_connection(int client_index, int v6_num)
+{
+ int len, res = IPACM_SUCCESS;
+ ipa_ioc_del_flt_rule *pFilteringTable = NULL;
+
+ struct ipa_flt_rule_del flt_rule_entry;
+
+ IPACMDBG("\n");
+ len = sizeof(struct ipa_ioc_del_flt_rule) + sizeof(struct ipa_flt_rule_del);
+ pFilteringTable = (struct ipa_ioc_del_flt_rule*)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error Locate ipa_ioc_del_flt_rule memory...\n");
+ return IPACM_FAILURE;
+ }
+ memset(pFilteringTable, 0, len);
+
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = IPA_IP_v6;
+ pFilteringTable->num_hdls = (uint8_t)1;
+
+ /* Configuring Software-Routing Filtering Rule */
+ memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del));
+ flt_rule_entry.hdl = get_client_memptr(wlan_client, client_index)->v6_rt_rule_id[v6_num];
+
+ memcpy(&(pFilteringTable->hdl[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_del));
+
+ if(false == m_filtering.DelOffloadFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Failed to install WAN DL filtering table.\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ get_client_memptr(wlan_client, client_index)->v6_rt_rule_id[v6_num] = 0;
+
+fail:
+ if(pFilteringTable != NULL)
+ {
+ free(pFilteringTable);
+ }
+ return res;
+}
diff --git a/ipacm/src/IPACM_Xml.cpp b/ipacm/src/IPACM_Xml.cpp
index 4451906..d59bbb0 100644
--- a/ipacm/src/IPACM_Xml.cpp
+++ b/ipacm/src/IPACM_Xml.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013, The Linux Foundation. All rights reserved.
+Copyright (c) 2013, 2019, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -75,6 +75,7 @@ static char* IPACM_read_content_element
)
{
xmlNode* child_ptr;
+ uint32_t str_len;
for (child_ptr = element->children;
child_ptr != NULL;
@@ -82,7 +83,15 @@ static char* IPACM_read_content_element
{
if (child_ptr->type == XML_TEXT_NODE)
{
- return (char*)child_ptr->content;
+ str_len = strlen((char*)child_ptr->content);
+
+ if(str_len < MAX_XML_STR_LEN)
+ return (char*)child_ptr->content;
+ else
+ {
+ IPACMERR("Invalid string size\n");
+ break;
+ }
}
}
return NULL;