"LA.UM.8.2.r1-06300-sdm660.0"

Change-Id: I04700deece31db26973552e77ec9a64907ee0852
This commit is contained in:
Max Weffers 2020-04-07 10:49:42 +02:00 committed by OdSazib
parent b87dec2474
commit 4c2ff8b4b8
No known key found for this signature in database
GPG key ID: CB336514F9F5CF69
11 changed files with 299 additions and 214 deletions

View file

@ -94,7 +94,7 @@ public:
ipacm_alg *alg_table; ipacm_alg *alg_table;
/* Store private subnet configuration from XML file */ /* Store private subnet configuration from XML file */
ipa_private_subnet private_subnet_table[IPA_MAX_PRIVATE_SUBNET_ENTRIES]; ipa_private_subnet private_subnet_table[IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES];
/* Store the non nat iface names */ /* Store the non nat iface names */
NatIfaces *pNatIfaces; NatIfaces *pNatIfaces;

View file

@ -77,6 +77,7 @@ extern "C"
#define IPA_MAX_IFACE_ENTRIES 20 #define IPA_MAX_IFACE_ENTRIES 20
#define IPA_MAX_PRIVATE_SUBNET_ENTRIES 3 #define IPA_MAX_PRIVATE_SUBNET_ENTRIES 3
#define IPA_MAX_MTU_ENTRIES 3
#define IPA_MAX_ALG_ENTRIES 20 #define IPA_MAX_ALG_ENTRIES 20
#define IPA_MAX_RM_ENTRY 6 #define IPA_MAX_RM_ENTRY 6
@ -106,6 +107,7 @@ extern "C"
#define TCP_SYN_SHIFT 17 #define TCP_SYN_SHIFT 17
#define TCP_RST_SHIFT 18 #define TCP_RST_SHIFT 18
#define NUM_IPV6_PREFIX_FLT_RULE 1 #define NUM_IPV6_PREFIX_FLT_RULE 1
#define NUM_IPV6_PREFIX_MTU_RULE 1
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
Return values indicating error status Return values indicating error status
@ -124,6 +126,7 @@ extern "C"
#define IPA_MAC_ADDR_SIZE 6 #define IPA_MAC_ADDR_SIZE 6
#define IPA_MAX_NUM_SW_PDNS 15 #define IPA_MAX_NUM_SW_PDNS 15
#define DEFAULT_MTU_SIZE 1500
/*=========================================================================== /*===========================================================================
GLOBAL DEFINITIONS AND DECLARATIONS GLOBAL DEFINITIONS AND DECLARATIONS
===========================================================================*/ ===========================================================================*/

View file

@ -1,5 +1,5 @@
/* /*
Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
@ -59,7 +59,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define IPV4_DEFAULT_FILTERTING_RULES 3 #define IPV4_DEFAULT_FILTERTING_RULES 3
#ifdef FEATURE_IPA_ANDROID #ifdef FEATURE_IPA_ANDROID
#define IPV6_DEFAULT_FILTERTING_RULES 8 #define IPV6_DEFAULT_FILTERTING_RULES 5
#else #else
#define IPV6_DEFAULT_FILTERTING_RULES 4 #define IPV6_DEFAULT_FILTERTING_RULES 4
#endif #endif

View file

@ -113,7 +113,7 @@ public:
uint32_t lan_wan_fl_rule_hdl[IPA_WAN_DEFAULT_FILTER_RULE_HANDLES]; uint32_t lan_wan_fl_rule_hdl[IPA_WAN_DEFAULT_FILTER_RULE_HANDLES];
/* store private-subnet filter rule handlers */ /* store private-subnet filter rule handlers */
uint32_t private_fl_rule_hdl[IPA_MAX_PRIVATE_SUBNET_ENTRIES]; uint32_t private_fl_rule_hdl[IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES];
/* LAN-iface's callback function */ /* LAN-iface's callback function */
void event_callback(ipa_cm_event_id event, void *data); void event_callback(ipa_cm_event_id event, void *data);
@ -258,7 +258,7 @@ protected:
uint32_t ipv4_icmp_flt_rule_hdl[NUM_IPV4_ICMP_FLT_RULE]; uint32_t ipv4_icmp_flt_rule_hdl[NUM_IPV4_ICMP_FLT_RULE];
uint32_t ipv6_prefix_flt_rule_hdl[NUM_IPV6_PREFIX_FLT_RULE]; uint32_t ipv6_prefix_flt_rule_hdl[NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_PREFIX_MTU_RULE];
uint32_t ipv6_icmp_flt_rule_hdl[NUM_IPV6_ICMP_FLT_RULE]; uint32_t ipv6_icmp_flt_rule_hdl[NUM_IPV6_ICMP_FLT_RULE];
int num_wan_ul_fl_rule_v4; int num_wan_ul_fl_rule_v4;
@ -464,6 +464,8 @@ private:
/* for pcie modem */ /* for pcie modem */
virtual int add_connection(int client_index, int v6_num); virtual int add_connection(int client_index, int v6_num);
virtual int del_connection(int client_index, int v6_num); virtual int del_connection(int client_index, int v6_num);
int construct_mtu_rule(struct ipa_flt_rule *rule, enum ipa_ip_type iptype, uint16_t mtu);
}; };
#endif /* IPACM_LAN_H */ #endif /* IPACM_LAN_H */

View file

@ -105,6 +105,8 @@ public:
static bool wan_up; static bool wan_up;
static bool wan_up_v6; static bool wan_up_v6;
static uint8_t xlat_mux_id; static uint8_t xlat_mux_id;
static uint16_t mtu_default_wan;
uint16_t mtu_size;
/* IPACM interface name */ /* IPACM interface name */
static char wan_up_dev_name[IF_NAME_LEN]; static char wan_up_dev_name[IF_NAME_LEN];
static uint32_t curr_wan_ip; static uint32_t curr_wan_ip;
@ -137,6 +139,26 @@ public:
#endif #endif
} }
static uint16_t queryMTU(int ipa_if_num_tether, enum ipa_ip_type iptype)
{
if (iptype == IPA_IP_v4)
{
if (isWanUP(ipa_if_num_tether))
{
return mtu_default_wan;
}
}
else if (iptype == IPA_IP_v6)
{
if (isWanUP_V6(ipa_if_num_tether))
{
return mtu_default_wan;
}
}
return DEFAULT_MTU_SIZE;
}
static bool isWanUP_V6(int ipa_if_num_tether) static bool isWanUP_V6(int ipa_if_num_tether)
{ {
#ifdef FEATURE_IPA_ANDROID #ifdef FEATURE_IPA_ANDROID
@ -623,8 +645,6 @@ private:
int add_dft_filtering_rule(struct ipa_flt_rule_add* rules, int rule_offset, ipa_ip_type iptype); int add_dft_filtering_rule(struct ipa_flt_rule_add* rules, int rule_offset, ipa_ip_type iptype);
int add_tcpv6_filtering_rule(struct ipa_flt_rule_add* rules, int rule_offset);
int install_wan_filtering_rule(bool is_sw_routing); int install_wan_filtering_rule(bool is_sw_routing);
void handle_wlan_SCC_MCC_switch(bool, ipa_ip_type); void handle_wlan_SCC_MCC_switch(bool, ipa_ip_type);
@ -653,6 +673,9 @@ private:
int add_tcp_fin_rst_exception_rule(); int add_tcp_fin_rst_exception_rule();
int delete_tcp_fin_rst_exception_rule(); int delete_tcp_fin_rst_exception_rule();
/* Query mtu size */
int query_mtu_size();
}; };
#endif /* IPACM_WAN_H */ #endif /* IPACM_WAN_H */

View file

@ -195,6 +195,12 @@ int NatApp::AddTable(uint32_t pub_ip, uint8_t mux_id)
} }
} }
/* configure NAT initialization paramater */
pub_ip_addr = pub_ip;
pub_mux_id = mux_id;
IPACMDBG(" Set pub_mux_id: %d\t", pub_mux_id);
/* Add back the cached NAT-entry */ /* Add back the cached NAT-entry */
if (pub_ip == pub_ip_addr_pre) if (pub_ip == pub_ip_addr_pre)
{ {
@ -222,6 +228,8 @@ int NatApp::AddTable(uint32_t pub_ip, uint8_t mux_id)
/* send connections info to pcie modem only with DL direction */ /* 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)) if ((CtList->backhaul_mode == Q6_MHI_WAN) && (cache[cnt].dst_nat == true || cache[cnt].protocol == IPPROTO_TCP))
{ {
/* propagate pub_ip info */
cache[cnt].public_ip = pub_ip;
ret = AddConnection(&cache[cnt]); ret = AddConnection(&cache[cnt]);
if(ret > 0) if(ret > 0)
{ {
@ -246,9 +254,6 @@ 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; return 0;
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
@ -938,73 +938,17 @@ int IPACM_Iface::init_fl_rule(ipa_ip_type iptype)
memcpy(&(m_pFilteringTable->rules[3]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); memcpy(&(m_pFilteringTable->rules[3]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
#ifdef FEATURE_IPA_ANDROID #ifdef FEATURE_IPA_ANDROID
/* Add the ipv6 tcp fragment filtering rule. */ /* Add the ipv6 tcp/udp fragment filtering rule for MTU */
IPACMDBG_H("Adding IPv6 TCP fragment filter rule\n"); IPACMDBG_H("Adding IPv6 fragment filter rule\n");
flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_DST_ADDR); flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_DST_ADDR);
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR;
flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_TCP;
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT; flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT;
memcpy(&(m_pFilteringTable->rules[4]), &flt_rule_entry, memcpy(&(m_pFilteringTable->rules[4]), &flt_rule_entry,
sizeof(struct ipa_flt_rule_add)); sizeof(struct ipa_flt_rule_add));
IPACMDBG_H("Add TCP ctrl rules: total num %d\n", IPV6_DEFAULT_FILTERTING_RULES);
memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
flt_rule_entry.at_rear = true;
flt_rule_entry.flt_rule_hdl = -1;
flt_rule_entry.status = -1;
flt_rule_entry.rule.retain_hdr = 1;
flt_rule_entry.rule.to_uc = 0;
flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION;
flt_rule_entry.rule.eq_attrib_type = 1;
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap = 0;
if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA)
{
#ifdef FEATURE_IPA_V3
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<9);
#else
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<14);
#endif
flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1;
flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0;
flt_rule_entry.rule.eq_attrib.metadata_meq32.value = rx_prop->rx[0].attrib.meta_data;
flt_rule_entry.rule.eq_attrib.metadata_meq32.mask = rx_prop->rx[0].attrib.meta_data_mask;
}
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<1);
flt_rule_entry.rule.eq_attrib.protocol_eq_present = 1;
flt_rule_entry.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP;
#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
flt_rule_entry.rule.eq_attrib.num_ihl_offset_meq_32 = 1;
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12;
/* add TCP FIN rule*/
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_FIN_SHIFT);
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_FIN_SHIFT);
memcpy(&(m_pFilteringTable->rules[5]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
/* add TCP SYN rule*/
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_SYN_SHIFT);
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_SYN_SHIFT);
memcpy(&(m_pFilteringTable->rules[6]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
/* add TCP RST rule*/
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_RST_SHIFT);
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_RST_SHIFT);
memcpy(&(m_pFilteringTable->rules[7]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
#endif #endif
#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
/* use index hw-counter */ /* use index hw-counter */

View file

@ -129,8 +129,8 @@ IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index)
memset(ipv4_icmp_flt_rule_hdl, 0, NUM_IPV4_ICMP_FLT_RULE * sizeof(uint32_t)); memset(ipv4_icmp_flt_rule_hdl, 0, NUM_IPV4_ICMP_FLT_RULE * sizeof(uint32_t));
memset(private_fl_rule_hdl, 0, IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(uint32_t)); memset(private_fl_rule_hdl, 0, (IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES) * sizeof(uint32_t));
memset(ipv6_prefix_flt_rule_hdl, 0, NUM_IPV6_PREFIX_FLT_RULE * sizeof(uint32_t)); memset(ipv6_prefix_flt_rule_hdl, 0, (NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_PREFIX_MTU_RULE) * sizeof(uint32_t));
memset(ipv6_icmp_flt_rule_hdl, 0, NUM_IPV6_ICMP_FLT_RULE * sizeof(uint32_t)); memset(ipv6_icmp_flt_rule_hdl, 0, NUM_IPV6_ICMP_FLT_RULE * sizeof(uint32_t));
memset(ipv6_prefix, 0, sizeof(ipv6_prefix)); memset(ipv6_prefix, 0, sizeof(ipv6_prefix));
@ -881,6 +881,11 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param)
{ {
memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix)); memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix));
install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix); install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix);
/* MTU might have changed. Need to update ipv4 MTU rule if up */
if (IPACM_Wan::isWanUP(ipa_if_num))
handle_private_subnet_android(IPA_IP_v4);
if (data_wan->backhaul_type == Q6_WAN) if (data_wan->backhaul_type == Q6_WAN)
{ {
ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6); ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6);
@ -1306,6 +1311,9 @@ int IPACM_Lan::handle_wan_down(ipacm_wan_iface_type backhaul_mode)
sta_ul_v4_set = false; sta_ul_v4_set = false;
} }
/* clean MTU rules if needed */
handle_private_subnet_android(IPA_IP_v4);
close(fd); close(fd);
return IPACM_SUCCESS; return IPACM_SUCCESS;
} }
@ -1644,6 +1652,18 @@ int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type)
if(ip_type == IPA_IP_v4) if(ip_type == IPA_IP_v4)
{ {
/* add MTU rules for ipv4 */
handle_private_subnet_android(IPA_IP_v4);
/* Update ipv6 MTU here if WAN_v6 is up and filter rules were installed */
if (IPACM_Wan::isWanUP_V6(ipa_if_num))
{
if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1] ) {
delete_ipv6_prefix_flt_rule();
install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
}
}
if(sta_ul_v4_set == true) if(sta_ul_v4_set == true)
{ {
IPACMDBG_H("Filetring rule for IPV4 of STA mode is already configured, sta_ul_v4_set: %d\n",sta_ul_v4_set); IPACMDBG_H("Filetring rule for IPV4 of STA mode is already configured, sta_ul_v4_set: %d\n",sta_ul_v4_set);
@ -1886,6 +1906,18 @@ 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); ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id);
modem_ul_v6_set = true; modem_ul_v6_set = true;
} else if (iptype ==IPA_IP_v4 && modem_ul_v4_set == false) { } else if (iptype ==IPA_IP_v4 && modem_ul_v4_set == false) {
/* add MTU rules for ipv4 */
handle_private_subnet_android(IPA_IP_v4);
/* Update ipv6 MTU here if WAN_v6 is up and filter rules were installed */
if (IPACM_Wan::isWanUP_V6(ipa_if_num))
{
if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1] ) {
delete_ipv6_prefix_flt_rule();
install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix);
}
}
IPACMDBG_H("check getXlat_Mux_Id:%d\n", IPACM_Wan::getXlat_Mux_Id()); 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); 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); ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id);
@ -3059,13 +3091,13 @@ int IPACM_Lan::handle_down_evt()
} }
#ifdef FEATURE_IPA_ANDROID #ifdef FEATURE_IPA_ANDROID
if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES) == false) if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES) == false)
{ {
IPACMERR("Error deleting private subnet IPv4 flt rules.\n"); IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
res = IPACM_FAILURE; res = IPACM_FAILURE;
goto fail; goto fail;
} }
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES); IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES);
#else #else
if (m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet) == false) if (m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet) == false)
{ {
@ -4044,7 +4076,7 @@ int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)
ipa_ioc_add_flt_rule* pFilteringTable; ipa_ioc_add_flt_rule* pFilteringTable;
bool result; bool result;
len = sizeof(struct ipa_ioc_add_flt_rule) + IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(struct ipa_flt_rule_add); len = sizeof(struct ipa_ioc_add_flt_rule) + (IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES) * sizeof(struct ipa_flt_rule_add);
pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len);
if (pFilteringTable == NULL) if (pFilteringTable == NULL)
@ -4058,7 +4090,7 @@ int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)
pFilteringTable->ep = rx_prop->rx[0].src_pipe; pFilteringTable->ep = rx_prop->rx[0].src_pipe;
pFilteringTable->global = false; pFilteringTable->global = false;
pFilteringTable->ip = iptype; pFilteringTable->ip = iptype;
pFilteringTable->num_rules = IPA_MAX_PRIVATE_SUBNET_ENTRIES; pFilteringTable->num_rules = IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES;
memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add));
@ -4081,7 +4113,7 @@ int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)
flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0;
flt_rule.rule.attrib.u.v4.dst_addr = ~0; flt_rule.rule.attrib.u.v4.dst_addr = ~0;
for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++) for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES; i++)
{ {
memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add));
} }
@ -4107,9 +4139,9 @@ int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype)
} }
else else
{ {
IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES); IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES);
/* copy filter rule hdls */ /* copy filter rule hdls */
for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++) for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES; i++)
{ {
if (pFilteringTable->rules[i].status == 0) if (pFilteringTable->rules[i].status == 0)
{ {
@ -4135,6 +4167,9 @@ int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype)
int i, len, res = IPACM_SUCCESS; int i, len, res = IPACM_SUCCESS;
struct ipa_flt_rule_mdfy flt_rule; struct ipa_flt_rule_mdfy flt_rule;
struct ipa_ioc_mdfy_flt_rule* pFilteringTable; struct ipa_ioc_mdfy_flt_rule* pFilteringTable;
int mtu_rule_cnt = 0;
uint16_t mtu[IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES] = { };
int mtu_rule_idx = IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
if (rx_prop == NULL) if (rx_prop == NULL)
{ {
@ -4149,12 +4184,24 @@ int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype)
} }
else else
{ {
for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++) for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES; i++)
{ {
reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]); reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]);
} }
len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_mdfy); /* check how many MTU rules we need to add */
for(i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++)
{
mtu[i] = IPACM_Wan::queryMTU(ipa_if_num, IPA_IP_v4);
if (mtu[i] > 0)
mtu_rule_cnt++;
else
IPACMDBG_H("MTU is zero\n");
}
IPACMDBG_H("total %d MTU rules are needed\n", mtu_rule_cnt);
len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet + mtu_rule_cnt) * sizeof(struct ipa_flt_rule_mdfy);
pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len);
if (!pFilteringTable) if (!pFilteringTable)
{ {
@ -4165,7 +4212,7 @@ int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype)
pFilteringTable->commit = 1; pFilteringTable->commit = 1;
pFilteringTable->ip = iptype; pFilteringTable->ip = iptype;
pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet; pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet + mtu_rule_cnt;
/* Make LAN-traffic always go A5, use default IPA-RT table */ /* Make LAN-traffic always go A5, use default IPA-RT table */
if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4)) if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4))
@ -4185,16 +4232,32 @@ int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype)
flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl; flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl;
IPACMDBG_H("Private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name); IPACMDBG_H("Private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name);
memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++) for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++)
{ {
/* add private subnet rule for ipv4 */
flt_rule.rule.action = IPA_PASS_TO_ROUTING;
flt_rule.rule.eq_attrib_type = 0;
flt_rule.rule_hdl = private_fl_rule_hdl[i]; flt_rule.rule_hdl = private_fl_rule_hdl[i];
memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR;
flt_rule.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask; flt_rule.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask;
flt_rule.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr; flt_rule.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr;
memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
IPACMDBG_H(" IPACM private subnet_addr as: 0x%x entry(%d)\n", flt_rule.rule.attrib.u.v4.dst_addr, i); IPACMDBG_H(" IPACM private subnet_addr as: 0x%x entry(%d)\n", flt_rule.rule.attrib.u.v4.dst_addr, i);
/* add corresponding MTU rule for ipv4 */
if (mtu[i] > 0)
{
flt_rule.rule_hdl = private_fl_rule_hdl[mtu_rule_idx + i];
memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib));
flt_rule.rule.attrib.u.v4.src_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask;
flt_rule.rule.attrib.u.v4.src_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr;
flt_rule.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
if (construct_mtu_rule(&flt_rule.rule, IPA_IP_v4, mtu[i]))
IPACMERR("Failed to modify MTU filtering rule.\n");
memcpy(&(pFilteringTable->rules[mtu_rule_idx + i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
IPACMDBG_H("Adding MTU rule for private subnet 0x%x.\n", flt_rule.rule.attrib.u.v4.src_addr);
}
} }
if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
@ -4225,12 +4288,17 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix)
struct ipa_ioc_add_flt_rule* flt_rule; struct ipa_ioc_add_flt_rule* flt_rule;
struct ipa_flt_rule_add flt_rule_entry; struct ipa_flt_rule_add flt_rule_entry;
bool result; bool result;
int rule_cnt = 1;
uint16_t mtu = IPACM_Wan::queryMTU(ipa_if_num, IPA_IP_v6);
if (mtu > 0)
rule_cnt ++;
if(rx_prop != NULL) if(rx_prop != NULL)
{ {
len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); len = sizeof(struct ipa_ioc_add_flt_rule) + rule_cnt * sizeof(struct ipa_flt_rule_add);
flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len); flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(rule_cnt, len);
if (!flt_rule) if (!flt_rule)
{ {
IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); IPACMERR("Error Locate ipa_flt_rule_add memory...\n");
@ -4241,7 +4309,7 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix)
flt_rule->ep = rx_prop->rx[0].src_pipe; flt_rule->ep = rx_prop->rx[0].src_pipe;
flt_rule->global = false; flt_rule->global = false;
flt_rule->ip = IPA_IP_v6; flt_rule->ip = IPA_IP_v6;
flt_rule->num_rules = 1; flt_rule->num_rules = rule_cnt;
memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
@ -4267,6 +4335,30 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix)
flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x0; flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x0;
memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); // this will remove the IPA_FLT_DST_ADDR
flt_rule_entry.rule.attrib.u.v6.src_addr[3] = prefix[0];
flt_rule_entry.rule.attrib.u.v6.src_addr[2] = prefix[1];
flt_rule_entry.rule.attrib.u.v6.src_addr[1] = 0x0;
flt_rule_entry.rule.attrib.u.v6.src_addr[0] = 0x0;
flt_rule_entry.rule.attrib.u.v6.src_addr_mask[3] = 0xFFFFFFFF;
flt_rule_entry.rule.attrib.u.v6.src_addr_mask[2] = 0xFFFFFFFF;
flt_rule_entry.rule.attrib.u.v6.src_addr_mask[1] = 0x0;
flt_rule_entry.rule.attrib.u.v6.src_addr_mask[0] = 0x0;
flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR;
/* Add an MTU rule with every new private prefix */
if (mtu > 0)
{
if (construct_mtu_rule(&flt_rule_entry.rule, IPA_IP_v6, mtu))
{
IPACMERR("Failed to add MTU filtering rule.\n")
}
else
{
memcpy(&(flt_rule->rules[1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
}
}
#ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
/* use index hw-counter */ /* use index hw-counter */
if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support) if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->hw_fnr_stats_support)
@ -4288,9 +4380,14 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix)
} }
else else
{ {
IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 2);
ipv6_prefix_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl; ipv6_prefix_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl;
IPACMDBG_H("IPv6 prefix filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[0]); IPACMDBG_H("IPv6 prefix filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[0]);
if (rule_cnt > 1)
{
ipv6_prefix_flt_rule_hdl[1] = flt_rule->rules[1].flt_rule_hdl;
IPACMDBG_H("IPv6 prefix MTU filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[1]);
}
free(flt_rule); free(flt_rule);
} }
} }
@ -4299,12 +4396,12 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix)
void IPACM_Lan::delete_ipv6_prefix_flt_rule() void IPACM_Lan::delete_ipv6_prefix_flt_rule()
{ {
if(m_filtering.DeleteFilteringHdls(ipv6_prefix_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE) == false) if(m_filtering.DeleteFilteringHdls(ipv6_prefix_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_PREFIX_MTU_RULE) == false)
{ {
IPACMERR("Failed to delete ipv6 prefix flt rule.\n"); IPACMERR("Failed to delete ipv6 prefix flt rules.\n");
return; return;
} }
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE); IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE + NUM_IPV6_PREFIX_MTU_RULE);
return; return;
} }
@ -6336,3 +6433,68 @@ fail:
} }
return res; return res;
} }
int IPACM_Lan::construct_mtu_rule(struct ipa_flt_rule *rule, ipa_ip_type iptype, uint16_t mtu)
{
int res = IPACM_SUCCESS;
int fd;
ipa_ioc_generate_flt_eq flt_eq;
if (rule == NULL)
{
IPACMERR("rule is empty");
return IPACM_FAILURE;
}
if (mtu == 0)
{
IPACMERR("mtu is uninitialized");
return IPACM_FAILURE;
}
IPACMDBG_H("Adding MTU rule for iptype = %d\n", iptype);
rule->eq_attrib_type = 1;
rule->eq_attrib.rule_eq_bitmap = 0;
rule->action = IPA_PASS_TO_EXCEPTION;
rule->rt_tbl_hdl = -1;
/* generate eq */
memset(&flt_eq, 0, sizeof(flt_eq));
memcpy(&flt_eq.attrib, &rule->attrib, sizeof(flt_eq.attrib));
flt_eq.ip = iptype;
fd = open(IPA_DEVICE_NAME, O_RDWR);
if (fd < 0)
{
IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
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(&rule->eq_attrib,
&flt_eq.eq_attrib, sizeof(rule->eq_attrib));
//add IHL offsets
#ifdef FEATURE_IPA_V3
rule->eq_attrib.rule_eq_bitmap |= (1<<10);
#else
rule->eq_attrib.rule_eq_bitmap |= (1<<4);
#endif
rule->eq_attrib.num_ihl_offset_range_16 = 1;
if (iptype == IPA_IP_v4)
rule->eq_attrib.ihl_offset_range_16[0].offset = 0x82;
else
rule->eq_attrib.ihl_offset_range_16[0].offset = 0x84;
rule->eq_attrib.ihl_offset_range_16[0].range_low = mtu + 1;
rule->eq_attrib.ihl_offset_range_16[0].range_high = UINT16_MAX; //0xFFFF
fail:
close(fd);
return res;
}

View file

@ -1,5 +1,5 @@
/* /*
Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
@ -52,6 +52,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "linux/ipa_qmi_service_v01.h" #include "linux/ipa_qmi_service_v01.h"
#ifdef FEATURE_IPACM_HAL #ifdef FEATURE_IPACM_HAL
#include "IPACM_OffloadManager.h" #include "IPACM_OffloadManager.h"
#include <IPACM_Netlink.h>
#endif #endif
bool IPACM_Wan::wan_up = false; bool IPACM_Wan::wan_up = false;
@ -91,6 +92,8 @@ int IPACM_Wan::ipa_if_num_tether_v4[IPA_MAX_IFACE_ENTRIES];
int IPACM_Wan::ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES]; int IPACM_Wan::ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES];
#endif #endif
uint16_t IPACM_Wan::mtu_default_wan = DEFAULT_MTU_SIZE;
IPACM_Wan::IPACM_Wan(int iface_index, IPACM_Wan::IPACM_Wan(int iface_index,
ipacm_wan_iface_type is_sta_mode, ipacm_wan_iface_type is_sta_mode,
uint8_t *mac_addr) : IPACM_Iface(iface_index) uint8_t *mac_addr) : IPACM_Iface(iface_index)
@ -129,6 +132,7 @@ IPACM_Wan::IPACM_Wan(int iface_index,
ext_prop = NULL; ext_prop = NULL;
is_ipv6_frag_firewall_flt_rule_installed = false; is_ipv6_frag_firewall_flt_rule_installed = false;
ipv6_frag_firewall_flt_rule_hdl = 0; ipv6_frag_firewall_flt_rule_hdl = 0;
mtu_size = DEFAULT_MTU_SIZE;
num_wan_client = 0; num_wan_client = 0;
header_name_count = 0; header_name_count = 0;
@ -1818,6 +1822,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); IPACMDBG_H("backhaul_is_wan_bridge ?: %d \n", IPACM_Wan::backhaul_is_wan_bridge);
/* query MTU size of the interface */
query_mtu_size();
if (m_is_sta_mode ==Q6_WAN) if (m_is_sta_mode ==Q6_WAN)
{ {
IPACM_Wan::backhaul_mode = m_is_sta_mode; IPACM_Wan::backhaul_mode = m_is_sta_mode;
@ -2105,6 +2112,11 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
wan_route_rule_v6_hdl_a5[0], 0, iptype); wan_route_rule_v6_hdl_a5[0], 0, iptype);
} }
/* set mtu_default_wan to current default wan instance */
mtu_default_wan = mtu_size;
IPACMDBG_H("replace the mtu_default_wan to %d\n", mtu_default_wan);
ipacm_event_iface_up *wanup_data; ipacm_event_iface_up *wanup_data;
wanup_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up)); wanup_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up));
if (wanup_data == NULL) if (wanup_data == NULL)
@ -2218,8 +2230,9 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
IPACMDBG_H("dev %s add producer dependency\n", dev_name); 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]); 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); 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 #ifdef WAN_IOC_NOTIFY_WAN_STATE
} else { else {
if ((m_is_sta_mode == Q6_WAN && ipa_pm_q6_check == 0 ) || (m_is_sta_mode == Q6_MHI_WAN)) 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); fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR);
@ -2240,9 +2253,8 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype)
ipa_pm_q6_check++; ipa_pm_q6_check++;
IPACMDBG_H("update ipa_pm_q6_check to %d\n", ipa_pm_q6_check); IPACMDBG_H("update ipa_pm_q6_check to %d\n", ipa_pm_q6_check);
} }
#else
}
#endif #endif
if(rt_rule != NULL) if(rt_rule != NULL)
{ {
free(rt_rule); free(rt_rule);
@ -4261,9 +4273,6 @@ int IPACM_Wan::config_wan_firewall_rule(ipa_ip_type iptype)
} }
else if(iptype == IPA_IP_v6) else if(iptype == IPA_IP_v6)
{ {
#ifdef FEATURE_IPA_ANDROID
add_tcpv6_filtering_rule(flt_rule_v6, IPACM_Wan::num_v6_flt_rule);
#endif
IPACM_Wan::num_v6_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6; IPACM_Wan::num_v6_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6;
if(IPACM_FAILURE == add_icmp_alg_rules(flt_rule_v6, IPACM_Wan::num_v6_flt_rule, IPA_IP_v6)) if(IPACM_FAILURE == add_icmp_alg_rules(flt_rule_v6, IPACM_Wan::num_v6_flt_rule, IPA_IP_v6))
{ {
@ -4550,104 +4559,6 @@ fail:
return res; return res;
} }
int IPACM_Wan::add_tcpv6_filtering_rule(struct ipa_flt_rule_add *rules, int rule_offset)
{
struct ipa_ioc_get_rt_tbl_indx rt_tbl_idx;
struct ipa_flt_rule_add flt_rule_entry;
struct ipa_ioc_generate_flt_eq flt_eq;
int res = IPACM_SUCCESS;
if(rules == NULL)
{
IPACMERR("No filtering table available.\n");
return IPACM_FAILURE;
}
if(rx_prop == NULL)
{
IPACMERR("No tx property.\n");
return IPACM_FAILURE;
}
memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx));
strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX);
rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0';
rt_tbl_idx.ip = IPA_IP_v6;
if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx))
{
IPACMERR("Failed to get routing table index from name\n");
res = IPACM_FAILURE;
goto fail;
}
IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx);
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;
flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx;
#ifdef FEATURE_IPA_ANDROID
IPACMDBG_H("Add TCP ctrl rules: total num %d\n", IPA_V2_NUM_TCP_WAN_FILTER_RULE_IPV6);
#endif
memcpy(&flt_rule_entry.rule.attrib,
&rx_prop->rx[0].attrib,
sizeof(flt_rule_entry.rule.attrib));
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(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));
flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<1);
flt_rule_entry.rule.eq_attrib.protocol_eq_present = 1;
flt_rule_entry.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP;
#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
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(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
/* add TCP SYN rule*/
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_SYN_SHIFT);
flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_SYN_SHIFT);
memcpy(&(rules[rule_offset + 1]), &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(&(rules[rule_offset + 2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add));
#ifdef FEATURE_IPA_ANDROID
IPACM_Wan::num_v6_flt_rule += IPA_V2_NUM_TCP_WAN_FILTER_RULE_IPV6;
IPACMDBG_H("Constructed %d ICMP filtering rules for ip type %d\n", IPA_V2_NUM_TCP_WAN_FILTER_RULE_IPV6, IPA_IP_v6);
#endif
fail:
return res;
}
int IPACM_Wan::del_wan_firewall_rule(ipa_ip_type iptype) int IPACM_Wan::del_wan_firewall_rule(ipa_ip_type iptype)
{ {
if(iptype == IPA_IP_v4) if(iptype == IPA_IP_v4)
@ -4785,6 +4696,7 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype)
int fd_wwan_ioctl; int fd_wwan_ioctl;
memset(&wan_state, 0, sizeof(wan_state)); memset(&wan_state, 0, sizeof(wan_state));
#endif #endif
int ret = IPACM_SUCCESS;
IPACMDBG_H("got handle_route_del_evt for STA-mode with ip-family:%d \n", iptype); IPACMDBG_H("got handle_route_del_evt for STA-mode with ip-family:%d \n", iptype);
@ -4914,24 +4826,19 @@ int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype)
if(delete_offload_frag_rule()) if(delete_offload_frag_rule())
{ {
IPACMERR("Failed to delete DL frag rule \n"); IPACMERR("Failed to delete DL frag rule \n");
return IPACM_FAILURE; ret = IPACM_FAILURE;
}
/* Delete MHI icmpv6 exception rule */
if(delete_icmpv6_exception_rule())
{
IPACMERR("Failed to delete icmpv6 rule \n");
return IPACM_FAILURE;
} }
/* Delete tcp_fin_rst rule */ /* Delete tcp_fin_rst rule */
if(delete_tcp_fin_rst_exception_rule()) if(delete_tcp_fin_rst_exception_rule())
{ {
IPACMERR("Failed to delete tcp_fin_rst rule \n"); IPACMERR("Failed to delete tcp_fin_rst rule \n");
return IPACM_FAILURE; ret = IPACM_FAILURE;
} }
return ret;
} }
else else
{ {
wandown_data->backhaul_type = m_is_sta_mode; wandown_data->backhaul_type = m_is_sta_mode;
memcpy(wandown_data->ipv6_prefix, ipv6_prefix, sizeof(wandown_data->ipv6_prefix)); memcpy(wandown_data->ipv6_prefix, ipv6_prefix, sizeof(wandown_data->ipv6_prefix));
evt_data.event = IPA_HANDLE_WAN_DOWN_V6; evt_data.event = IPA_HANDLE_WAN_DOWN_V6;
@ -4950,6 +4857,13 @@ 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)); memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name));
} }
/* Delete MHI icmpv6 exception rule */
if(delete_icmpv6_exception_rule())
{
IPACMERR("Failed to delete icmpv6 rule \n");
return IPACM_FAILURE;
}
} }
} }
else else
@ -4989,8 +4903,9 @@ int IPACM_Wan::handle_route_del_evt_ex(ipa_ip_type iptype)
IPACMDBG_H("dev %s delete producer dependency\n", dev_name); IPACMDBG_H("dev %s delete producer dependency\n", dev_name);
IPACMDBG_H("depend Got pipe %d rm index : %d \n", tx_prop->tx[0].dst_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); 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]); IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]);
}
#ifdef WAN_IOC_NOTIFY_WAN_STATE #ifdef WAN_IOC_NOTIFY_WAN_STATE
} else { else {
IPACMDBG_H("ipa_pm_q6_check to %d\n", ipa_pm_q6_check); IPACMDBG_H("ipa_pm_q6_check to %d\n", ipa_pm_q6_check);
if(ipa_pm_q6_check == 1) if(ipa_pm_q6_check == 1)
{ {
@ -5012,8 +4927,6 @@ int IPACM_Wan::handle_route_del_evt_ex(ipa_ip_type iptype)
else else
IPACMERR(" ipa_pm_q6_check becomes negative !!!\n"); IPACMERR(" ipa_pm_q6_check becomes negative !!!\n");
} }
#else
}
#endif #endif
/* Delete the default route*/ /* Delete the default route*/
if (iptype == IPA_IP_v6) if (iptype == IPA_IP_v6)
@ -5554,6 +5467,9 @@ int IPACM_Wan::handle_down_evt_ex()
goto fail; goto fail;
} }
/* reset the mtu size */
mtu_size = DEFAULT_MTU_SIZE;
if(ip_type == IPA_IP_v4) if(ip_type == IPA_IP_v4)
{ {
num_ipv4_modem_pdn--; num_ipv4_modem_pdn--;
@ -7913,3 +7829,33 @@ fail:
} }
return res; return res;
} }
int IPACM_Wan::query_mtu_size()
{
int fd;
struct ifreq if_mtu;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if ( fd < 0 ) {
IPACMERR("ipacm: socket open failed [%d]\n", fd);
return IPACM_FAILURE;
}
strlcpy(if_mtu.ifr_name, dev_name, IFNAMSIZ);
IPACMDBG_H("device name: %s\n", dev_name);
if_mtu.ifr_name[IFNAMSIZ - 1] = '\0';
if ( ioctl(fd, SIOCGIFMTU, &if_mtu) < 0 ) {
IPACMERR("ioctl failed to get mtu\n");
close(fd);
return IPACM_FAILURE;
}
IPACMDBG_H("mtu=[%d]\n", if_mtu.ifr_mtu);
if (if_mtu.ifr_mtu < DEFAULT_MTU_SIZE) {
mtu_size = if_mtu.ifr_mtu;
IPACMDBG_H("replaced mtu=[%d] for (%s)\n", mtu_size, dev_name);
}
close(fd);
return IPACM_SUCCESS;
}

View file

@ -1955,16 +1955,16 @@ int IPACM_Wlan::handle_down_evt()
} }
/* delete private-ipv4 filter rules */ /* delete private-ipv4 filter rules */
#ifdef FEATURE_IPA_ANDROID #ifdef FEATURE_IPA_ANDROID
if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES) == false) if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES) == false)
{ {
IPACMERR("Error deleting private subnet IPv4 flt rules.\n"); IPACMERR("Error deleting private subnet IPv4 flt rules.\n");
res = IPACM_FAILURE; res = IPACM_FAILURE;
goto fail; goto fail;
} }
IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES); IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES);
#else #else
num_private_subnet_fl_rule = IPACM_Iface::ipacmcfg->ipa_num_private_subnet > IPA_MAX_PRIVATE_SUBNET_ENTRIES? num_private_subnet_fl_rule = IPACM_Iface::ipacmcfg->ipa_num_private_subnet > (IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES)?
IPA_MAX_PRIVATE_SUBNET_ENTRIES : IPACM_Iface::ipacmcfg->ipa_num_private_subnet; (IPA_MAX_PRIVATE_SUBNET_ENTRIES + IPA_MAX_MTU_ENTRIES) : IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, num_private_subnet_fl_rule) == false) if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, num_private_subnet_fl_rule) == false)
{ {
IPACMERR("Error deleting private subnet flt rules, aborting...\n"); IPACMERR("Error deleting private subnet flt rules, aborting...\n");