diff options
author | Michael Adisumarta <madisuma@codeaurora.org> | 2020-10-30 17:05:37 -0700 |
---|---|---|
committer | Michael Adisumarta <madisuma@codeaurora.org> | 2020-10-30 22:36:41 -0700 |
commit | a9392c9662a8aa140770b95f2c343c2bb791e8d2 (patch) | |
tree | 83bdc3aba20ad07a6a2ab07a44893cd98e89cc8d /ipacm/src | |
parent | 50b9701ad29f45ae0f49a189f58972e41cdbd1af (diff) | |
download | ipacfg-mgr-a9392c9662a8aa140770b95f2c343c2bb791e8d2.tar.gz |
ipacm: add dynamic support for IPA new MTU events
Handle new MTU events to replace modem PDN MTU for WANv4/v6
and replace the MTU rules if they are already installed.
Change-Id: I06c16db2300ccd572a99ab316d413fcbf9197986
Signed-off-by: Michael Adisumarta <madisuma@codeaurora.org>
Diffstat (limited to 'ipacm/src')
-rw-r--r-- | ipacm/src/IPACM_Iface.cpp | 2 | ||||
-rw-r--r-- | ipacm/src/IPACM_IfaceManager.cpp | 9 | ||||
-rw-r--r-- | ipacm/src/IPACM_Lan.cpp | 162 | ||||
-rw-r--r-- | ipacm/src/IPACM_Main.cpp | 30 | ||||
-rw-r--r-- | ipacm/src/IPACM_Wan.cpp | 231 | ||||
-rw-r--r-- | ipacm/src/IPACM_Wlan.cpp | 29 |
6 files changed, 394 insertions, 69 deletions
diff --git a/ipacm/src/IPACM_Iface.cpp b/ipacm/src/IPACM_Iface.cpp index 8282915..55cf71d 100644 --- a/ipacm/src/IPACM_Iface.cpp +++ b/ipacm/src/IPACM_Iface.cpp @@ -1009,7 +1009,7 @@ fail: return res; } -/* get ipa interface name */ +/* get ipa interface index from name */ int IPACM_Iface::ipa_get_if_index ( char * if_name, diff --git a/ipacm/src/IPACM_IfaceManager.cpp b/ipacm/src/IPACM_IfaceManager.cpp index 7ba5a80..1392a1a 100644 --- a/ipacm/src/IPACM_IfaceManager.cpp +++ b/ipacm/src/IPACM_IfaceManager.cpp @@ -291,6 +291,9 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param) IPACM_EvtDispatcher::registr(IPA_TETHERING_STATS_UPDATE_EVENT, lan); #endif IPACM_EvtDispatcher::registr(IPA_CRADLE_WAN_MODE_SWITCH, lan); +#ifdef IPA_MTU_EVENT_MAX + IPACM_EvtDispatcher::registr(IPA_MTU_UPDATE, lan); +#endif IPACM_EvtDispatcher::registr(IPA_LINK_DOWN_EVENT, lan); /* IPA_LAN_DELETE_SELF should be always last */ IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, lan); @@ -420,6 +423,9 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param) IPACM_EvtDispatcher::registr(IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE, wl); #endif IPACM_EvtDispatcher::registr(IPA_WIGIG_CLIENT_ADD_EVENT, wl); +#ifdef IPA_MTU_EVENT_MAX + IPACM_EvtDispatcher::registr(IPA_MTU_UPDATE, wl); +#endif /* IPA_LAN_DELETE_SELF should be always last */ IPACM_EvtDispatcher::registr(IPA_LAN_DELETE_SELF, wl); IPACMDBG_H("ipa_WLAN (%s):ipa_index (%d) instance open/registr ok\n", wl->dev_name, wl->ipa_if_num); @@ -464,6 +470,9 @@ int IPACM_IfaceManager::create_iface_instance(ipacm_ifacemgr_data *param) if(is_sta_mode == Q6_WAN) { IPACM_EvtDispatcher::registr(IPA_NETWORK_STATS_UPDATE_EVENT, w); +#ifdef IPA_MTU_EVENT_MAX + IPACM_EvtDispatcher::registr(IPA_MTU_SET, w); +#endif }; #else/* defined(FEATURE_IPA_ANDROID) */ IPACM_EvtDispatcher::registr(IPA_ROUTE_ADD_EVENT, w); diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp index 7e7e875..a6b2b90 100644 --- a/ipacm/src/IPACM_Lan.cpp +++ b/ipacm/src/IPACM_Lan.cpp @@ -1110,6 +1110,36 @@ void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) } break; +#ifdef IPA_MTU_EVENT_MAX + case IPA_MTU_UPDATE: + { + IPACMDBG_H("Received IPA_MTU_UPDATE"); + ipacm_event_mtu_info *evt_data = (ipacm_event_mtu_info *)param; + ipa_mtu_info *data = &(evt_data->mtu_info); + + /* IPA_IP_MAX means both ipv4 and ipv6 */ + if ((data->ip_type == IPA_IP_v4 || data->ip_type == IPA_IP_MAX) && IPACM_Wan::isWanUP(ipa_if_num)) + { + handle_private_subnet_android(IPA_IP_v4); + } + + /* IPA_IP_MAX means both ipv4 and ipv6 */ + if ((data->ip_type == IPA_IP_v6 || data->ip_type == IPA_IP_MAX) && IPACM_Wan::isWanUP_V6(ipa_if_num)) + { + /* check if the prefix + MTU rules are installed */ + if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1]) + { + modify_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); + } + else + { + IPACMERR("Failed to update prefix MTU rules, no prefix rules set"); + } + } + } + break; +#endif + default: break; } @@ -1641,9 +1671,9 @@ int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type) /* 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 (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1]) + { + modify_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); } } @@ -1912,9 +1942,9 @@ int IPACM_Lan::handle_wan_up_ex(ipacm_ext_prop *ext_prop, ipa_ip_type iptype, ui /* 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 (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1]) + { + modify_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); } } @@ -4293,8 +4323,13 @@ fail: return res; } -int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) +int IPACM_Lan::modify_ipv6_prefix_flt_rule(uint32_t* prefix) { + int len, res = IPACM_SUCCESS; + struct ipa_flt_rule_mdfy flt_rule_entry; + struct ipa_ioc_mdfy_flt_rule* flt_rule; + int rule_cnt = 1; + if(prefix == NULL) { IPACMERR("IPv6 prefix is empty.\n"); @@ -4302,12 +4337,114 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) } IPACMDBG_H("Receive IPv6 prefix: 0x%08x%08x.\n", prefix[0], prefix[1]); + uint16_t mtu = IPACM_Wan::queryMTU(ipa_if_num, IPA_IP_v6); + if (mtu > 0) + { + IPACMDBG_H("MTU is %d\n", mtu); + rule_cnt ++; + } + else + { + IPACMERR("MTU is 0"); + } + + + if(rx_prop == NULL) + { + IPACMERR("no rx props\n"); + return IPACM_FAILURE; + } + + len = sizeof(struct ipa_ioc_mdfy_flt_rule) + rule_cnt * sizeof(struct ipa_flt_rule_mdfy); + flt_rule = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); + if(!flt_rule) + { + IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); + return IPACM_FAILURE; + } + memset(flt_rule, 0, len); + + flt_rule->commit = 1; + flt_rule->ip = IPA_IP_v6; + flt_rule->num_rules = rule_cnt; + + memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_mdfy)); + 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 = 0; + flt_rule_entry.rule_hdl = ipv6_prefix_flt_rule_hdl[0]; + + memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); + flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; + flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = prefix[0]; + flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = prefix[1]; + flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x0; + flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x0; + flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; + flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; + flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x0; + flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x0; + memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_mdfy)); + + + flt_rule_entry.rule_hdl = ipv6_prefix_flt_rule_hdl[1]; + 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_mdfy)); + } + } + + + if(false == m_filtering.ModifyFilteringRule(flt_rule)) + { + IPACMERR("Failed to modify prefix filtering rules.\n"); + res = IPACM_FAILURE; + goto fail; + } + +fail: + if(flt_rule != NULL) + { + free(flt_rule); + } + return res; +} + +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; int rule_cnt = 1; + if(prefix == NULL) + { + IPACMERR("IPv6 prefix is empty.\n"); + return IPACM_FAILURE; + } + IPACMDBG_H("Receive IPv6 prefix: 0x%08x%08x.\n", prefix[0], prefix[1]); + uint16_t mtu = IPACM_Wan::queryMTU(ipa_if_num, IPA_IP_v6); if (mtu > 0) { @@ -4383,18 +4520,7 @@ int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) } } -#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) { diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp index ca75a4a..6bd117e 100644 --- a/ipacm/src/IPACM_Main.cpp +++ b/ipacm/src/IPACM_Main.cpp @@ -270,6 +270,10 @@ void* ipa_driver_msg_notifier(void *param) #endif ipacm_cmd_q_data new_neigh_evt; ipacm_event_data_all* new_neigh_data; +#ifdef IPA_MTU_EVENT_MAX + ipacm_event_mtu_info *mtu_event = NULL; + ipa_mtu_info *mtu_info; +#endif param = NULL; fd = open(IPA_DRIVER, O_RDWR); @@ -874,6 +878,32 @@ void* ipa_driver_msg_notifier(void *param) break; #endif +#ifdef IPA_MTU_EVENT_MAX + case IPA_SET_MTU: + mtu_event = (ipacm_event_mtu_info *)malloc(sizeof(*mtu_event)); + if(mtu_event == NULL) + { + IPACMERR("Failed to allocate memory.\n"); + return NULL; + } + mtu_info = &(mtu_event->mtu_info); + memcpy(mtu_info, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_mtu_info)); + IPACMDBG_H("Received IPA_SET_MTU if_name %s ip_type %d mtu_v4 %d mtu_v6 %d\n", + mtu_info->if_name, mtu_info->ip_type, mtu_info->mtu_v4, mtu_info->mtu_v6); + if (mtu_info->ip_type > IPA_IP_MAX) + { + IPACMERR("ip_type (%d) beyond the Max range (%d), abort\n", + mtu_info->ip_type, IPA_IP_MAX); + return NULL; + } + + ipa_get_if_index(mtu_info->if_name, &(mtu_event->if_index)); + + evt_data.event = IPA_MTU_SET; + evt_data.evt_data = mtu_event; + break; +#endif + default: IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type); continue; diff --git a/ipacm/src/IPACM_Wan.cpp b/ipacm/src/IPACM_Wan.cpp index 397c820..ad174c4 100644 --- a/ipacm/src/IPACM_Wan.cpp +++ b/ipacm/src/IPACM_Wan.cpp @@ -92,7 +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]; #endif -uint16_t IPACM_Wan::mtu_default_wan = DEFAULT_MTU_SIZE; +uint16_t IPACM_Wan::mtu_default_wan_v4 = DEFAULT_MTU_SIZE; +uint16_t IPACM_Wan::mtu_default_wan_v6 = DEFAULT_MTU_SIZE; IPACM_Wan::IPACM_Wan(int iface_index, ipacm_wan_iface_type is_sta_mode, @@ -132,7 +133,11 @@ IPACM_Wan::IPACM_Wan(int iface_index, ext_prop = NULL; is_ipv6_frag_firewall_flt_rule_installed = false; ipv6_frag_firewall_flt_rule_hdl = 0; - mtu_size = DEFAULT_MTU_SIZE; + + mtu_v4 = DEFAULT_MTU_SIZE; + mtu_v4_set = false; + mtu_v6 = DEFAULT_MTU_SIZE; + mtu_v6_set = false; num_wan_client = 0; header_name_count = 0; @@ -146,6 +151,53 @@ IPACM_Wan::IPACM_Wan(int iface_index, wan_client_len = 0; m_is_sta_mode = is_sta_mode; +#ifdef IPA_MTU_EVENT_MAX + /* Query WAN MTU to handle IPACM restart scenarios. */ + if(is_sta_mode == Q6_WAN) + { + int fd_wwan_ioctl; + ipa_mtu_info *mtu_info = (ipa_mtu_info *)malloc(sizeof(ipa_mtu_info)); + if (mtu_info) + { + memset(mtu_info, 0, sizeof(ipa_mtu_info)); + memcpy(mtu_info->if_name, dev_name, IPA_IFACE_NAME_LEN); + 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); + } + else + { + IPACMDBG_H("send WAN_IOC_GET_WAN_MTU for %s\n", mtu_info->if_name); + if(ioctl(fd_wwan_ioctl, WAN_IOC_GET_WAN_MTU, mtu_info)) + { + IPACMERR("Failed to send WAN_IOC_GET_WAN_MTU\n "); + } + else + { + /* Updated MTU values.*/ + if (mtu_info->mtu_v4) + { + mtu_v4 = mtu_info->mtu_v4; + mtu_v4_set = true; + IPACMDBG_H("Updated v4 mtu=[%d] for (%s)\n", + mtu_v4, mtu_info->if_name); + } + if (mtu_info->mtu_v6) + { + mtu_v6 = mtu_info->mtu_v6; + mtu_v6_set = true; + IPACMDBG_H("Updated v6 mtu=[%d] for (%s)\n", + mtu_v6, mtu_info->if_name); + } + } + close(fd_wwan_ioctl); + } + free(mtu_info); + } + } +#endif + if(iface_query != NULL) { IPACMDBG_H("index:%d constructor: Tx properties:%d\n", iface_index, iface_query->num_tx_props); @@ -1112,6 +1164,7 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) } } break; + case IPA_LINK_DOWN_EVENT: { ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; @@ -1721,54 +1774,117 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) } break; - case IPA_WLAN_SWITCH_TO_SCC: - if(IPACM_Wan::backhaul_mode == WLAN_WAN) + case IPA_WLAN_SWITCH_TO_SCC: + if(IPACM_Wan::backhaul_mode == WLAN_WAN) + { + IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_SCC\n"); + if(ip_type == IPA_IP_MAX) { - IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_SCC\n"); - if(ip_type == IPA_IP_MAX) - { - handle_wlan_SCC_MCC_switch(true, IPA_IP_v4); - handle_wlan_SCC_MCC_switch(true, IPA_IP_v6); - handle_wan_client_SCC_MCC_switch(true, IPA_IP_v4); - handle_wan_client_SCC_MCC_switch(true, IPA_IP_v6); - } - else - { - handle_wlan_SCC_MCC_switch(true, ip_type); - handle_wan_client_SCC_MCC_switch(true, ip_type); - } + handle_wlan_SCC_MCC_switch(true, IPA_IP_v4); + handle_wlan_SCC_MCC_switch(true, IPA_IP_v6); + handle_wan_client_SCC_MCC_switch(true, IPA_IP_v4); + handle_wan_client_SCC_MCC_switch(true, IPA_IP_v6); } - break; + else + { + handle_wlan_SCC_MCC_switch(true, ip_type); + handle_wan_client_SCC_MCC_switch(true, ip_type); + } + } + break; + + case IPA_WLAN_SWITCH_TO_MCC: + if(IPACM_Wan::backhaul_mode == WLAN_WAN) + { + IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_MCC\n"); + if(ip_type == IPA_IP_MAX) + { + handle_wlan_SCC_MCC_switch(false, IPA_IP_v4); + handle_wlan_SCC_MCC_switch(false, IPA_IP_v6); + handle_wan_client_SCC_MCC_switch(false, IPA_IP_v4); + handle_wan_client_SCC_MCC_switch(false, IPA_IP_v6); + } + else + { + handle_wlan_SCC_MCC_switch(false, ip_type); + handle_wan_client_SCC_MCC_switch(false, ip_type); + } + } + break; +#ifdef FEATURE_IPACM_HAL + /* WA for WLAN to clean up NAT instance during SSR */ + 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) + { + IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface + } + } + break; +#endif +#ifdef IPA_MTU_EVENT_MAX + case IPA_MTU_SET: + { + ipacm_event_mtu_info *data = (ipacm_event_mtu_info *)param; + ipa_mtu_info *mtu_info = &(data->mtu_info); + ipa_interface_index = iface_ipa_index_query(data->if_index); - case IPA_WLAN_SWITCH_TO_MCC: - if(IPACM_Wan::backhaul_mode == WLAN_WAN) + if (ipa_interface_index == ipa_if_num) + { + IPACMDBG_H("Received IPA_MTU_SET (Android) for interface (%d)\n", + ipa_interface_index); + if (mtu_info->ip_type == IPA_IP_v4 || mtu_info->ip_type == IPA_IP_MAX) { - IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_MCC\n"); - if(ip_type == IPA_IP_MAX) + /* Update v4_mtu. */ + mtu_v4 = mtu_info->mtu_v4; + mtu_v4_set = true; + + if (active_v4) { - handle_wlan_SCC_MCC_switch(false, IPA_IP_v4); - handle_wlan_SCC_MCC_switch(false, IPA_IP_v6); - handle_wan_client_SCC_MCC_switch(false, IPA_IP_v4); - handle_wan_client_SCC_MCC_switch(false, IPA_IP_v6); + /* upstream interface. update default MTU. */ + mtu_default_wan_v4 = mtu_v4; } - else + IPACMDBG_H("Updated v4 mtu=[%d] for (%s), upstream_mtu=[%d]\n", + mtu_v4, mtu_info->if_name, mtu_default_wan_v4); + } + if (mtu_info->ip_type == IPA_IP_v6 || mtu_info->ip_type == IPA_IP_MAX) + { + /* Update v4_mtu. */ + mtu_v6 = mtu_info->mtu_v6; + mtu_v6_set = true; + if (active_v6) { - handle_wlan_SCC_MCC_switch(false, ip_type); - handle_wan_client_SCC_MCC_switch(false, ip_type); + /* upstream interface. update default MTU. */ + mtu_default_wan_v6 = mtu_v6; } + IPACMDBG_H("Updated v6 mtu=[%d] for (%s), upstream_mtu=[%d]\n", + mtu_v6, mtu_info->if_name, mtu_default_wan_v6); } - break; -#ifdef FEATURE_IPACM_HAL - /* WA for WLAN to clean up NAT instance during SSR */ - 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) + + if (active_v4 || active_v6) { - IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface + ipacm_event_mtu_info *mtu_event; + ipacm_cmd_q_data evt_data; + mtu_event = (ipacm_event_mtu_info *)malloc(sizeof(*mtu_event)); + if(mtu_event == NULL) + { + IPACMERR("Failed to allocate memory.\n"); + return; + } + memcpy(&mtu_event->mtu_info, mtu_info, sizeof(ipa_mtu_info)); + evt_data.event = IPA_MTU_UPDATE; + evt_data.evt_data = mtu_event; + /* finish command queue */ + IPACMDBG_H("Posting IPA_MTU_UPDATE event\n"); + IPACM_EvtDispatcher::PostEvt(&evt_data); } - break; + } + } + break; #endif + default: break; } @@ -1779,7 +1895,6 @@ void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) /* wan default route/filter rule configuration */ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) { - /* add default WAN route */ struct ipa_ioc_add_rt_rule *rt_rule = NULL; struct ipa_rt_rule_add *rt_rule_entry; @@ -1817,8 +1932,14 @@ 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); - /* query MTU size of the interface */ - query_mtu_size(); + /* query MTU size of the interface if MTU is not set via ioctl. */ + if (!mtu_v4_set && !mtu_v6_set) + { + if(query_mtu_size()) + { + IPACMERR("Failed to query mtu"); + } + } if (m_is_sta_mode ==Q6_WAN) { @@ -2104,11 +2225,6 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type 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; wanup_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up)); if (wanup_data == NULL) @@ -2122,6 +2238,10 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) /* handling filter rule construction */ if (iptype == IPA_IP_v4) { + /* set mtu_default_wan to current default wan instance */ + mtu_default_wan_v4 = mtu_v4; + IPACMDBG_H("replace the mtu_wan to %d\n", mtu_default_wan_v4); + IPACM_Wan::wan_up = true; active_v4 = true; memcpy(IPACM_Wan::wan_up_dev_name, @@ -2181,6 +2301,10 @@ int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) } else { + /* set mtu_default_wan to current default wan instance */ + mtu_default_wan_v6 = mtu_v6; + IPACMDBG_H("replace the mtu_wan to %d\n", mtu_default_wan_v6); + memcpy(backhaul_ipv6_prefix, ipv6_prefix, sizeof(backhaul_ipv6_prefix)); IPACMDBG_H("Setup backhaul ipv6 prefix to be 0x%08x%08x.\n", backhaul_ipv6_prefix[0], backhaul_ipv6_prefix[1]); @@ -5453,8 +5577,13 @@ int IPACM_Wan::handle_down_evt_ex() goto fail; } +#ifndef IPA_MTU_EVENT_MAX /* reset the mtu size */ - mtu_size = DEFAULT_MTU_SIZE; + mtu_v4 = DEFAULT_MTU_SIZE; + mtu_v4_set = false; + mtu_v6 = DEFAULT_MTU_SIZE; + mtu_v6_set = false; +#endif if(ip_type == IPA_IP_v4) { @@ -7828,10 +7957,12 @@ int IPACM_Wan::query_mtu_size() 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); + if (if_mtu.ifr_mtu <= DEFAULT_MTU_SIZE) { + mtu_v4 = mtu_v6 = if_mtu.ifr_mtu; + }else { + mtu_v4 = mtu_v6 = DEFAULT_MTU_SIZE; } + IPACMDBG_H("Updated mtu=[%d] for (%s)\n", mtu_v4, dev_name); close(fd); return IPACM_SUCCESS; diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp index 689cc78..460b6c0 100644 --- a/ipacm/src/IPACM_Wlan.cpp +++ b/ipacm/src/IPACM_Wlan.cpp @@ -651,6 +651,35 @@ void IPACM_Wlan::event_callback(ipa_cm_event_id event, void *param) } break; } +#ifdef IPA_MTU_EVENT_MAX + case IPA_MTU_UPDATE: + { + IPACMDBG_H("Received IPA_MTU_UPDATE"); + ipacm_event_mtu_info *evt_data = (ipacm_event_mtu_info *)param; + ipa_mtu_info *data = &(evt_data->mtu_info); + + /* IPA_IP_MAX means both ipv4 and ipv6 */ + if ((data->ip_type == IPA_IP_v4 || data->ip_type == IPA_IP_MAX) && IPACM_Wan::isWanUP(ipa_if_num)) + { + handle_private_subnet_android(IPA_IP_v4); + } + + /* IPA_IP_MAX means both ipv4 and ipv6 */ + if ((data->ip_type == IPA_IP_v6 || data->ip_type == IPA_IP_MAX) && IPACM_Wan::isWanUP_V6(ipa_if_num)) + { + //check if the prefix + MTU rules are installed + if (ipv6_prefix_flt_rule_hdl[0] && ipv6_prefix_flt_rule_hdl[1]) { + modify_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); + } + else + { + IPACMERR("failed to update prefix MTU rules, no prefix rules set"); + } + } + } + break; +#endif + #else case IPA_HANDLE_WAN_UP: IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n"); |