1 /* 2 Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are 6 met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above 10 copyright notice, this list of conditions and the following 11 disclaimer in the documentation and/or other materials provided 12 with the distribution. 13 * Neither the name of The Linux Foundation nor the names of its 14 contributors may be used to endorse or promote products derived 15 from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 /*! 30 @file 31 IPACM_Wan.cpp 32 33 @brief 34 This file implements the WAN iface functionality. 35 36 @Author 37 Skylar Chang 38 39 */ 40 #include <string.h> 41 #include <fcntl.h> 42 #include <sys/ioctl.h> 43 #include <IPACM_Wan.h> 44 #include <IPACM_Xml.h> 45 #include <IPACM_Log.h> 46 #include "IPACM_EvtDispatcher.h" 47 #include <IPACM_IfaceManager.h> 48 #include "linux/rmnet_ipa_fd_ioctl.h" 49 #include "IPACM_Config.h" 50 #include "IPACM_Defs.h" 51 #include <IPACM_ConntrackListener.h> 52 #include "linux/ipa_qmi_service_v01.h" 53 #ifdef FEATURE_IPACM_HAL 54 #include "IPACM_OffloadManager.h" 55 #endif 56 57 bool IPACM_Wan::wan_up = false; 58 bool IPACM_Wan::wan_up_v6 = false; 59 uint8_t IPACM_Wan::xlat_mux_id = 0; 60 61 uint32_t IPACM_Wan::curr_wan_ip = 0; 62 int IPACM_Wan::num_v4_flt_rule = 0; 63 int IPACM_Wan::num_v6_flt_rule = 0; 64 65 struct ipa_flt_rule_add IPACM_Wan::flt_rule_v4[IPA_MAX_FLT_RULE]; 66 struct ipa_flt_rule_add IPACM_Wan::flt_rule_v6[IPA_MAX_FLT_RULE]; 67 68 char IPACM_Wan::wan_up_dev_name[IF_NAME_LEN]; 69 70 bool IPACM_Wan::backhaul_is_sta_mode = false; 71 bool IPACM_Wan::is_ext_prop_set = false; 72 73 int IPACM_Wan::num_ipv4_modem_pdn = 0; 74 int IPACM_Wan::num_ipv6_modem_pdn = 0; 75 76 bool IPACM_Wan::embms_is_on = false; 77 bool IPACM_Wan::backhaul_is_wan_bridge = false; 78 79 uint32_t IPACM_Wan::backhaul_ipv6_prefix[2]; 80 81 #ifdef FEATURE_IPA_ANDROID 82 uint32_t IPACM_Wan::ipa_if_num_tether_v4_total = 0; 83 uint32_t IPACM_Wan::ipa_if_num_tether_v6_total = 0; 84 85 int IPACM_Wan::ipa_if_num_tether_v4[IPA_MAX_IFACE_ENTRIES]; 86 int IPACM_Wan::ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES]; 87 #endif 88 89 IPACM_Wan::IPACM_Wan(int iface_index, 90 ipacm_wan_iface_type is_sta_mode, 91 uint8_t *mac_addr) : IPACM_Iface(iface_index) 92 { 93 num_firewall_v4 = 0; 94 num_firewall_v6 = 0; 95 wan_route_rule_v4_hdl = NULL; 96 wan_route_rule_v6_hdl = NULL; 97 wan_route_rule_v6_hdl_a5 = NULL; 98 wan_client = NULL; 99 mac_addr = NULL; 100 101 if(iface_query != NULL) 102 { 103 wan_route_rule_v4_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t)); 104 wan_route_rule_v6_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t)); 105 wan_route_rule_v6_hdl_a5 = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t)); 106 IPACMDBG_H("IPACM->IPACM_Wan(%d) constructor: Tx:%d\n", ipa_if_num, iface_query->num_tx_props); 107 } 108 m_is_sta_mode = is_sta_mode; 109 110 wan_v4_addr_set = false; 111 wan_v4_addr_gw_set = false; 112 wan_v6_addr_gw_set = false; 113 active_v4 = false; 114 active_v6 = false; 115 header_set_v4 = false; 116 header_set_v6 = false; 117 header_partial_default_wan_v4 = false; 118 header_partial_default_wan_v6 = false; 119 hdr_hdl_sta_v4 = 0; 120 hdr_hdl_sta_v6 = 0; 121 num_ipv6_dest_flt_rule = 0; 122 memset(ipv6_dest_flt_rule_hdl, 0, MAX_DEFAULT_v6_ROUTE_RULES*sizeof(uint32_t)); 123 memset(ipv6_prefix, 0, sizeof(ipv6_prefix)); 124 memset(wan_v6_addr_gw, 0, sizeof(wan_v6_addr_gw)); 125 ext_prop = NULL; 126 is_ipv6_frag_firewall_flt_rule_installed = false; 127 ipv6_frag_firewall_flt_rule_hdl = 0; 128 129 num_wan_client = 0; 130 header_name_count = 0; 131 memset(invalid_mac, 0, sizeof(invalid_mac)); 132 133 is_xlat = false; 134 hdr_hdl_dummy_v6 = 0; 135 hdr_proc_hdl_dummy_v6 = 0; 136 is_default_gateway = false; 137 m_fd_ipa = 0; 138 wan_client_len = 0; 139 140 if(iface_query != NULL) 141 { 142 wan_client_len = (sizeof(ipa_wan_client)) + (iface_query->num_tx_props * sizeof(wan_client_rt_hdl)); 143 wan_client = (ipa_wan_client *)calloc(IPA_MAX_NUM_WAN_CLIENTS, wan_client_len); 144 if (wan_client == NULL) 145 { 146 IPACMERR("unable to allocate memory\n"); 147 return; 148 } 149 IPACMDBG_H("index:%d constructor: Tx properties:%d\n", iface_index, iface_query->num_tx_props); 150 } 151 152 153 if(m_is_sta_mode == Q6_WAN) 154 { 155 IPACMDBG_H("The new WAN interface is modem.\n"); 156 is_default_gateway = false; 157 query_ext_prop(); 158 } 159 else 160 { 161 IPACMDBG_H("The new WAN interface is WLAN STA.\n"); 162 } 163 164 m_fd_ipa = open(IPA_DEVICE_NAME, O_RDWR); 165 if(0 == m_fd_ipa) 166 { 167 IPACMERR("Failed to open %s\n",IPA_DEVICE_NAME); 168 } 169 170 if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == EMBMS_IF) 171 { 172 IPACMDBG(" IPACM->IPACM_Wan_eMBMS(%d)\n", ipa_if_num); 173 embms_is_on = true; 174 install_wan_filtering_rule(false); 175 /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */ 176 if(tx_prop != NULL) 177 { 178 IPACMDBG_H("dev %s add producer dependency\n", dev_name); 179 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]); 180 IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false); 181 } 182 } 183 else 184 { 185 IPACMDBG(" IPACM->IPACM_Wan(%d)\n", ipa_if_num); 186 } 187 return; 188 } 189 190 IPACM_Wan::~IPACM_Wan() 191 { 192 IPACM_EvtDispatcher::deregistr(this); 193 IPACM_IfaceManager::deregistr(this); 194 return; 195 } 196 197 /* handle new_address event */ 198 int IPACM_Wan::handle_addr_evt(ipacm_event_data_addr *data) 199 { 200 struct ipa_ioc_add_rt_rule *rt_rule = NULL; 201 struct ipa_rt_rule_add *rt_rule_entry; 202 struct ipa_ioc_add_flt_rule *flt_rule; 203 struct ipa_flt_rule_add flt_rule_entry; 204 struct ipa_ioc_get_hdr hdr; 205 206 const int NUM_RULES = 1; 207 uint32_t num_ipv6_addr; 208 int res = IPACM_SUCCESS,len; 209 #ifdef FEATURE_IPACM_HAL 210 IPACM_OffloadManager* OffloadMng; 211 #endif 212 213 memset(&hdr, 0, sizeof(hdr)); 214 if(tx_prop == NULL || rx_prop == NULL) 215 { 216 IPACMDBG_H("Either tx or rx property is NULL, return.\n"); 217 return IPACM_SUCCESS; 218 } 219 220 /* Update the IP Type. */ 221 config_ip_type(data->iptype); 222 223 if (data->iptype == IPA_IP_v6) 224 { 225 for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++) 226 { 227 if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) && 228 (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) && 229 (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) && 230 (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3])) 231 { 232 IPACMDBG_H("find matched ipv6 address, index:%d \n", num_ipv6_addr); 233 return IPACM_SUCCESS; 234 break; 235 } 236 } 237 rt_rule = (struct ipa_ioc_add_rt_rule *) 238 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + 239 NUM_RULES * sizeof(struct ipa_rt_rule_add)); 240 241 if (!rt_rule) 242 { 243 IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n"); 244 return IPACM_FAILURE; 245 } 246 247 rt_rule->commit = 1; 248 rt_rule->num_rules = NUM_RULES; 249 rt_rule->ip = data->iptype; 250 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name)); 251 252 rt_rule_entry = &rt_rule->rules[0]; 253 if(m_is_sta_mode == Q6_WAN) 254 { 255 strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name)); 256 hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 257 if(m_header.GetHeaderHandle(&hdr) == false) 258 { 259 IPACMERR("Failed to get QMAP header.\n"); 260 return IPACM_FAILURE; 261 } 262 rt_rule_entry->rule.hdr_hdl = hdr.hdl; 263 } 264 rt_rule_entry->at_rear = false; 265 if(m_is_sta_mode == Q6_WAN) 266 { 267 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS; 268 } 269 else 270 { 271 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; 272 } 273 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; 274 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0]; 275 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1]; 276 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = data->ipv6_addr[2]; 277 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = data->ipv6_addr[3]; 278 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; 279 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; 280 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; 281 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; 282 ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0]; 283 ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1]; 284 ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2]; 285 ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3]; 286 #ifdef FEATURE_IPA_V3 287 rt_rule_entry->rule.hashable = false; 288 #endif 289 if (false == m_routing.AddRoutingRule(rt_rule)) 290 { 291 IPACMERR("Routing rule addition failed!\n"); 292 res = IPACM_FAILURE; 293 goto fail; 294 } 295 else if (rt_rule_entry->status) 296 { 297 IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status); 298 res = rt_rule_entry->status; 299 goto fail; 300 } 301 dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl; 302 303 /* setup same rule for v6_wan table*/ 304 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name)); 305 if (false == m_routing.AddRoutingRule(rt_rule)) 306 { 307 IPACMERR("Routing rule addition failed!\n"); 308 res = IPACM_FAILURE; 309 goto fail; 310 } 311 else if (rt_rule_entry->status) 312 { 313 IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status); 314 res = rt_rule_entry->status; 315 goto fail; 316 } 317 dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl; 318 319 IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, num_dft_rt_v6: %d \n", 320 dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6], 321 dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],num_dft_rt_v6); 322 323 /* add default filtering rules when wan-iface get global v6-prefix */ 324 if (num_dft_rt_v6 == 1) 325 { 326 if(m_is_sta_mode == Q6_WAN) 327 { 328 modem_ipv6_pdn_index = num_ipv6_modem_pdn; 329 num_ipv6_modem_pdn++; 330 IPACMDBG_H("Now the number of modem ipv6 pdn is %d.\n", num_ipv6_modem_pdn); 331 init_fl_rule_ex(data->iptype); 332 } 333 else 334 { 335 init_fl_rule(data->iptype); 336 } 337 } 338 339 /* add WAN DL interface IP specific flt rule for IPv6 when backhaul is not Q6 */ 340 if(m_is_sta_mode != Q6_WAN) 341 { 342 if(rx_prop != NULL && is_global_ipv6_addr(data->ipv6_addr) 343 && num_ipv6_dest_flt_rule < MAX_DEFAULT_v6_ROUTE_RULES) 344 { 345 len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); 346 347 flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len); 348 if (!flt_rule) 349 { 350 IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); 351 return IPACM_FAILURE; 352 } 353 354 flt_rule->commit = 1; 355 flt_rule->ep = rx_prop->rx[0].src_pipe; 356 flt_rule->global = false; 357 flt_rule->ip = IPA_IP_v6; 358 flt_rule->num_rules = 1; 359 360 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 361 362 flt_rule_entry.rule.retain_hdr = 1; 363 flt_rule_entry.rule.to_uc = 0; 364 flt_rule_entry.rule.eq_attrib_type = 0; 365 flt_rule_entry.at_rear = true; 366 flt_rule_entry.flt_rule_hdl = -1; 367 flt_rule_entry.status = -1; 368 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 369 #ifdef FEATURE_IPA_V3 370 flt_rule_entry.rule.hashable = true; 371 #endif 372 memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); 373 374 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 375 memcpy(flt_rule_entry.rule.attrib.u.v6.dst_addr, data->ipv6_addr, sizeof(flt_rule_entry.rule.attrib.u.v6.dst_addr)); 376 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; 377 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; 378 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; 379 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; 380 memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 381 382 if (m_filtering.AddFilteringRule(flt_rule) == false) 383 { 384 IPACMERR("Error Adding Filtering rule, aborting...\n"); 385 free(flt_rule); 386 res = IPACM_FAILURE; 387 goto fail; 388 } 389 else 390 { 391 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 392 ipv6_dest_flt_rule_hdl[num_ipv6_dest_flt_rule] = flt_rule->rules[0].flt_rule_hdl; 393 IPACMDBG_H("IPv6 dest filter rule %d HDL:0x%x\n", num_ipv6_dest_flt_rule, ipv6_dest_flt_rule_hdl[num_ipv6_dest_flt_rule]); 394 num_ipv6_dest_flt_rule++; 395 free(flt_rule); 396 } 397 } 398 } 399 /* store ipv6 prefix if the ipv6 address is not link local */ 400 if(is_global_ipv6_addr(data->ipv6_addr)) 401 { 402 memcpy(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)); 403 } 404 num_dft_rt_v6++; 405 } 406 else 407 { 408 if(wan_v4_addr_set) 409 { 410 /* check iface ipv4 same or not */ 411 if(data->ipv4_addr == wan_v4_addr) 412 { 413 IPACMDBG_H("Already setup device (%s) ipv4 and it didn't change(0x%x)\n", dev_name, data->ipv4_addr); 414 return IPACM_SUCCESS; 415 } 416 else 417 { 418 IPACMDBG_H(" device (%s) ipv4 addr is changed\n", dev_name); 419 /* Delete default v4 RT rule */ 420 IPACMDBG_H("Delete default v4 routing rules\n"); 421 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false) 422 { 423 IPACMERR("Routing old RT rule deletion failed!\n"); 424 res = IPACM_FAILURE; 425 goto fail; 426 } 427 } 428 } 429 430 rt_rule = (struct ipa_ioc_add_rt_rule *) 431 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + 432 NUM_RULES * sizeof(struct ipa_rt_rule_add)); 433 434 if (!rt_rule) 435 { 436 IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n"); 437 return IPACM_FAILURE; 438 } 439 440 rt_rule->commit = 1; 441 rt_rule->num_rules = NUM_RULES; 442 rt_rule->ip = data->iptype; 443 rt_rule_entry = &rt_rule->rules[0]; 444 if(m_is_sta_mode == Q6_WAN) 445 { 446 strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name)); 447 hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 448 if(m_header.GetHeaderHandle(&hdr) == false) 449 { 450 IPACMERR("Failed to get QMAP header.\n"); 451 return IPACM_FAILURE; 452 } 453 rt_rule_entry->rule.hdr_hdl = hdr.hdl; 454 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS; 455 } 456 else 457 { 458 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; 459 } 460 rt_rule_entry->at_rear = false; 461 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; 462 /* still need setup v4 default routing rule to A5*/ 463 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name)); 464 rt_rule_entry->rule.attrib.u.v4.dst_addr = data->ipv4_addr; 465 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; 466 #ifdef FEATURE_IPA_V3 467 rt_rule_entry->rule.hashable = false; 468 #endif 469 if (false == m_routing.AddRoutingRule(rt_rule)) 470 { 471 IPACMERR("Routing rule addition failed!\n"); 472 res = IPACM_FAILURE; 473 goto fail; 474 } 475 else if (rt_rule_entry->status) 476 { 477 IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status); 478 res = rt_rule_entry->status; 479 goto fail; 480 } 481 dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl; 482 IPACMDBG_H("ipv4 wan iface rt-rule hdll=0x%x\n", dft_rt_rule_hdl[0]); 483 /* initial multicast/broadcast/fragment filter rule */ 484 485 /* only do one time */ 486 if(!wan_v4_addr_set) 487 { 488 /* initial multicast/broadcast/fragment filter rule */ 489 if(m_is_sta_mode == Q6_WAN) 490 { 491 modem_ipv4_pdn_index = num_ipv4_modem_pdn; 492 num_ipv4_modem_pdn++; 493 IPACMDBG_H("Now the number of modem ipv4 pdn is %d.\n", num_ipv4_modem_pdn); 494 init_fl_rule_ex(data->iptype); 495 } 496 else 497 { 498 init_fl_rule(data->iptype); 499 } 500 } 501 502 wan_v4_addr = data->ipv4_addr; 503 wan_v4_addr_set = true; 504 505 if (m_is_sta_mode == Q6_WAN) 506 curr_wan_ip = data->ipv4_addr; 507 508 IPACMDBG_H("Receved wan ipv4-addr:0x%x\n",wan_v4_addr); 509 } 510 511 #ifdef FEATURE_IPACM_HAL 512 /* check if having pending add_downstream cache*/ 513 OffloadMng = IPACM_OffloadManager::GetInstance(); 514 if (OffloadMng == NULL) { 515 IPACMERR("failed to get IPACM_OffloadManager instance !\n"); 516 } else { 517 IPACMDBG_H(" check iface %s if having add_downstream cache events\n", dev_name); 518 OffloadMng->search_framwork_cache(dev_name); 519 } 520 #endif 521 IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6); 522 523 fail: 524 free(rt_rule); 525 526 return res; 527 } 528 529 void IPACM_Wan::event_callback(ipa_cm_event_id event, void *param) 530 { 531 int ipa_interface_index; 532 533 switch (event) 534 { 535 case IPA_WLAN_LINK_DOWN_EVENT: 536 { 537 if(m_is_sta_mode == WLAN_WAN) 538 { 539 ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; 540 ipa_interface_index = iface_ipa_index_query(data->if_index); 541 if (ipa_interface_index == ipa_if_num) 542 { 543 IPACMDBG_H("Received IPA_WLAN_LINK_DOWN_EVENT\n"); 544 handle_down_evt(); 545 /* reset the STA-iface category to unknown */ 546 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat = UNKNOWN_IF; 547 IPACMDBG_H("IPA_WAN_STA (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num); 548 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface 549 delete this; 550 return; 551 } 552 } 553 } 554 break; 555 556 case IPA_WAN_XLAT_CONNECT_EVENT: 557 { 558 IPACMDBG_H("Recieved IPA_WAN_XLAT_CONNECT_EVENT\n"); 559 ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; 560 ipa_interface_index = IPACM_Iface::iface_ipa_index_query(data->if_index); 561 if ((ipa_interface_index == ipa_if_num) && (m_is_sta_mode == Q6_WAN)) 562 { 563 is_xlat = true; 564 IPACMDBG_H("WAN-LTE (%s) link up, iface: %d is_xlat: %d\n", 565 IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name,data->if_index, is_xlat); 566 } 567 break; 568 } 569 case IPA_CFG_CHANGE_EVENT: 570 { 571 if ( (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == ipa_if_cate) && 572 (m_is_sta_mode ==ECM_WAN)) 573 { 574 IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT and category did not change(wan_mode:%d)\n", m_is_sta_mode); 575 IPACMDBG_H("Now the cradle wan mode is %d.\n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode); 576 if(is_default_gateway == true) 577 { 578 if(backhaul_is_wan_bridge == false && IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == BRIDGE) 579 { 580 IPACMDBG_H("Cradle wan mode switch to bridge mode.\n"); 581 backhaul_is_wan_bridge = true; 582 } 583 else if(backhaul_is_wan_bridge == true && IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER) 584 { 585 IPACMDBG_H("Cradle wan mode switch to router mode.\n"); 586 backhaul_is_wan_bridge = false; 587 } 588 else 589 { 590 IPACMDBG_H("No cradle mode switch, return.\n"); 591 return; 592 } 593 /* post wan mode change event to LAN/WLAN */ 594 if(IPACM_Wan::wan_up == true) 595 { 596 IPACMDBG_H("This interface is default GW.\n"); 597 ipacm_cmd_q_data evt_data; 598 memset(&evt_data, 0, sizeof(evt_data)); 599 600 ipacm_event_cradle_wan_mode *data_wan_mode = NULL; 601 data_wan_mode = (ipacm_event_cradle_wan_mode *)malloc(sizeof(ipacm_event_cradle_wan_mode)); 602 if(data_wan_mode == NULL) 603 { 604 IPACMERR("unable to allocate memory.\n"); 605 return; 606 } 607 data_wan_mode->cradle_wan_mode = IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode; 608 evt_data.event = IPA_CRADLE_WAN_MODE_SWITCH; 609 evt_data.evt_data = data_wan_mode; 610 IPACMDBG_H("Posting IPA_CRADLE_WAN_MODE_SWITCH event.\n"); 611 IPACM_EvtDispatcher::PostEvt(&evt_data); 612 } 613 /* update the firewall flt rule actions */ 614 if(active_v4) 615 { 616 del_dft_firewall_rules(IPA_IP_v4); 617 config_dft_firewall_rules(IPA_IP_v4); 618 } 619 if(active_v6) 620 { 621 del_dft_firewall_rules(IPA_IP_v6); 622 config_dft_firewall_rules(IPA_IP_v6); 623 } 624 } 625 else 626 { 627 IPACMDBG_H("This interface is not default GW, ignore.\n"); 628 } 629 } 630 else if ( (IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != ipa_if_cate) && 631 (m_is_sta_mode ==ECM_WAN)) 632 { 633 IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT and category changed(wan_mode:%d)\n", m_is_sta_mode); 634 /* posting link-up event for cradle use-case */ 635 ipacm_cmd_q_data evt_data; 636 memset(&evt_data, 0, sizeof(evt_data)); 637 638 ipacm_event_data_fid *data_fid = NULL; 639 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); 640 if(data_fid == NULL) 641 { 642 IPACMERR("unable to allocate memory for IPA_USB_LINK_UP_EVENT data_fid\n"); 643 return; 644 } 645 if(IPACM_Iface::ipa_get_if_index(dev_name, &(data_fid->if_index))) 646 { 647 IPACMERR("Error while getting interface index for %s device", dev_name); 648 } 649 evt_data.event = IPA_USB_LINK_UP_EVENT; 650 evt_data.evt_data = data_fid; 651 IPACMDBG_H("Posting event:%d\n", evt_data.event); 652 IPACM_EvtDispatcher::PostEvt(&evt_data); 653 654 /* delete previous instance */ 655 handle_down_evt(); 656 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface 657 delete this; 658 return; 659 } 660 } 661 break; 662 663 case IPA_LINK_DOWN_EVENT: 664 { 665 ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; 666 ipa_interface_index = iface_ipa_index_query(data->if_index); 667 if (ipa_interface_index == ipa_if_num) 668 { 669 if(m_is_sta_mode == Q6_WAN) 670 { 671 IPACMDBG_H("Received IPA_LINK_DOWN_EVENT\n"); 672 handle_down_evt_ex(); 673 IPACMDBG_H("IPA_WAN_Q6 (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num); 674 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface 675 delete this; 676 return; 677 } 678 else if (m_is_sta_mode == ECM_WAN) 679 { 680 IPACMDBG_H("Received IPA_LINK_DOWN_EVENT(wan_mode:%d)\n", m_is_sta_mode); 681 /* delete previous instance */ 682 handle_down_evt(); 683 IPACMDBG_H("IPA_WAN_CRADLE (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num); 684 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface 685 delete this; 686 return; 687 } 688 } 689 } 690 break; 691 692 case IPA_ADDR_ADD_EVENT: 693 { 694 ipacm_event_data_addr *data = (ipacm_event_data_addr *)param; 695 ipa_interface_index = iface_ipa_index_query(data->if_index); 696 697 if ( (data->iptype == IPA_IP_v4 && data->ipv4_addr == 0) || 698 (data->iptype == IPA_IP_v6 && 699 data->ipv6_addr[0] == 0 && data->ipv6_addr[1] == 0 && 700 data->ipv6_addr[2] == 0 && data->ipv6_addr[3] == 0) ) 701 { 702 IPACMDBG_H("Invalid address, ignore IPA_ADDR_ADD_EVENT event\n"); 703 return; 704 } 705 706 if (ipa_interface_index == ipa_if_num) 707 { 708 IPACMDBG_H("Get IPA_ADDR_ADD_EVENT: IF ip type %d, incoming ip type %d\n", ip_type, data->iptype); 709 /* check v4 not setup before, v6 can have 2 iface ip */ 710 if( (data->iptype == IPA_IP_v4) 711 || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES))) 712 { 713 IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6); 714 handle_addr_evt(data); 715 /* checking if SW-RT_enable */ 716 if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true && 717 m_is_sta_mode != Q6_WAN) 718 { 719 /* handle software routing enable event*/ 720 IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); 721 handle_software_routing_enable(); 722 } 723 724 } 725 } 726 } 727 break; 728 729 730 case IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT: 731 { 732 ipacm_event_data_iptype *data = (ipacm_event_data_iptype *)param; 733 ipa_interface_index = iface_ipa_index_query(data->if_index); 734 #ifndef FEATURE_IPACM_HAL 735 /* add the check see if tether_iface is valid or not */ 736 if (iface_ipa_index_query(data->if_index_tether) == INVALID_IFACE) 737 { 738 IPACMERR("UPSTREAM_ROUTE_ADD tether_if(%d), not valid ignore\n", INVALID_IFACE); 739 return; 740 } 741 #endif 742 if (ipa_interface_index == ipa_if_num) 743 { 744 IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT (Android) for ip-type (%d)\n", data->iptype); 745 /* The special below condition is to handle default gateway */ 746 if ((data->iptype == IPA_IP_v4) && (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)) 747 { 748 if (active_v4 == false) 749 { 750 #ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN 751 IPACMDBG_H("adding routing table(upstream), dev (%s) ip-type(%d) default gw (%x)\n", dev_name,data->iptype, wan_v4_addr_gw); 752 wan_v4_addr_gw = data->ipv4_addr_gw; 753 wan_v4_addr_gw_set = true; 754 /* Check & construct STA header */ 755 handle_sta_header_add_evt(); 756 #else 757 IPACMDBG_H("adding routing table(upstream), dev (%s) ip-type(%d)\n", dev_name,data->iptype); 758 #endif 759 handle_route_add_evt(data->iptype); //sky 760 } 761 #ifdef FEATURE_IPA_ANDROID 762 #ifdef FEATURE_IPACM_HAL 763 post_wan_up_tether_evt(data->iptype, 0); 764 #else 765 /* using ipa_if_index, not netdev_index */ 766 post_wan_up_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether)); 767 #endif 768 #endif 769 } 770 else if ((data->iptype == IPA_IP_v6) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)) 771 { 772 if(ipv6_prefix[0] == 0 && ipv6_prefix[1] == 0) 773 { 774 IPACMDBG_H("IPv6 default route comes earlier than global IP, ignore.\n"); 775 return; 776 } 777 778 if (active_v6 == false) 779 { 780 IPACMDBG_H("\n get default v6 route (dst:00.00.00.00) upstream\n"); 781 #ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN 782 IPACMDBG_H(" IPV6 gateway: %08x:%08x:%08x:%08x \n", 783 data->ipv6_addr_gw[0], data->ipv6_addr_gw[1], data->ipv6_addr_gw[2], data->ipv6_addr_gw[3]); 784 wan_v6_addr_gw[0] = data->ipv6_addr_gw[0]; 785 wan_v6_addr_gw[1] = data->ipv6_addr_gw[1]; 786 wan_v6_addr_gw[2] = data->ipv6_addr_gw[2]; 787 wan_v6_addr_gw[3] = data->ipv6_addr_gw[3]; 788 wan_v6_addr_gw_set = true; 789 /* Check & construct STA header */ 790 handle_sta_header_add_evt(); 791 #endif 792 handle_route_add_evt(data->iptype); 793 } 794 #ifdef FEATURE_IPA_ANDROID 795 #ifdef FEATURE_IPACM_HAL 796 post_wan_up_tether_evt(data->iptype, 0); 797 #else 798 /* using ipa_if_index, not netdev_index */ 799 post_wan_up_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether)); 800 #endif 801 #endif 802 } 803 } 804 else /* double check if current default iface is not itself */ 805 { 806 if ((data->iptype == IPA_IP_v4) && (active_v4 == true)) 807 { 808 IPACMDBG_H("Received v4 IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT for other iface (%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); 809 IPACMDBG_H("need clean default v4 route (dst:0.0.0.0) for old iface (%s)\n", dev_name); 810 wan_v4_addr_gw_set = false; 811 if(m_is_sta_mode == Q6_WAN) 812 { 813 del_wan_firewall_rule(IPA_IP_v4); 814 install_wan_filtering_rule(false); 815 handle_route_del_evt_ex(IPA_IP_v4); 816 } 817 else 818 { 819 del_dft_firewall_rules(IPA_IP_v4); 820 handle_route_del_evt(IPA_IP_v4); 821 } 822 } 823 else if ((data->iptype == IPA_IP_v6) && (active_v6 == true)) 824 { 825 IPACMDBG_H("Received v6 IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT for other iface (%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); 826 IPACMDBG_H("need clean default v6 route for old iface (%s)\n", dev_name); 827 if(m_is_sta_mode == Q6_WAN) 828 { 829 del_wan_firewall_rule(IPA_IP_v6); 830 install_wan_filtering_rule(false); 831 handle_route_del_evt_ex(IPA_IP_v6); 832 } 833 else 834 { 835 del_dft_firewall_rules(IPA_IP_v6); 836 handle_route_del_evt(IPA_IP_v6); 837 } 838 } 839 } 840 } 841 break; 842 843 case IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT: 844 { 845 ipacm_event_data_iptype *data = (ipacm_event_data_iptype *)param; 846 ipa_interface_index = iface_ipa_index_query(data->if_index); 847 #ifndef FEATURE_IPACM_HAL 848 /* add the check see if tether_iface is valid or not */ 849 if (iface_ipa_index_query(data->if_index_tether) == INVALID_IFACE) 850 { 851 IPACMERR("UPSTREAM_ROUTE_DEL tether_if(%d), not valid ignore\n", INVALID_IFACE); 852 return; 853 } 854 #endif 855 if (ipa_interface_index == ipa_if_num) 856 { 857 IPACMDBG_H("Received IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT\n"); 858 if ((data->iptype == IPA_IP_v4) && (active_v4 == true)) 859 { 860 IPACMDBG_H("get del default v4 route (dst:0.0.0.0)\n"); 861 wan_v4_addr_gw_set = false; 862 #ifdef FEATURE_IPA_ANDROID 863 #ifdef FEATURE_IPACM_HAL 864 post_wan_down_tether_evt(data->iptype, 0); 865 #else 866 /* using ipa_if_index, not netdev_index */ 867 post_wan_down_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether)); 868 /* no any ipv4 tether iface support*/ 869 if(IPACM_Wan::ipa_if_num_tether_v4_total != 0) 870 { 871 IPACMDBG_H("still have tether ipv4 client on upsteam iface\n"); 872 return; 873 } 874 #endif 875 #endif 876 if(m_is_sta_mode == Q6_WAN) 877 { 878 del_wan_firewall_rule(IPA_IP_v4); 879 install_wan_filtering_rule(false); 880 handle_route_del_evt_ex(IPA_IP_v4); 881 } 882 else 883 { 884 del_dft_firewall_rules(IPA_IP_v4); 885 handle_route_del_evt(IPA_IP_v4); 886 } 887 } 888 else if ((data->iptype == IPA_IP_v6) && (active_v6 == true)) 889 { 890 #ifdef FEATURE_IPA_ANDROID 891 #ifdef FEATURE_IPACM_HAL 892 post_wan_down_tether_evt(data->iptype, 0); 893 #else 894 895 /* using ipa_if_index, not netdev_index */ 896 post_wan_down_tether_evt(data->iptype, iface_ipa_index_query(data->if_index_tether)); 897 /* no any ipv6 tether iface support*/ 898 if(IPACM_Wan::ipa_if_num_tether_v6_total != 0) 899 { 900 IPACMDBG_H("still have tether ipv6 client on upsteam iface\n"); 901 return; 902 } 903 #endif 904 #endif 905 if(m_is_sta_mode == Q6_WAN) 906 { 907 del_wan_firewall_rule(IPA_IP_v6); 908 install_wan_filtering_rule(false); 909 handle_route_del_evt_ex(IPA_IP_v6); 910 } 911 else 912 { 913 del_dft_firewall_rules(IPA_IP_v6); 914 handle_route_del_evt(IPA_IP_v6); 915 } 916 } 917 } 918 } 919 break; 920 case IPA_NETWORK_STATS_UPDATE_EVENT: 921 { 922 ipa_get_apn_data_stats_resp_msg_v01 *data = (ipa_get_apn_data_stats_resp_msg_v01 *)param; 923 if (!data->apn_data_stats_list_valid) 924 { 925 IPACMERR("not valid APN\n"); 926 return; 927 } 928 else 929 { 930 handle_network_stats_update(data); 931 } 932 } 933 break; 934 case IPA_ROUTE_ADD_EVENT: 935 { 936 ipacm_event_data_addr *data = (ipacm_event_data_addr *)param; 937 ipa_interface_index = iface_ipa_index_query(data->if_index); 938 if (ipa_interface_index == ipa_if_num) 939 { 940 IPACMDBG_H("Received IPA_ROUTE_ADD_EVENT\n"); 941 IPACMDBG_H("ipv4 addr 0x%x\n", data->ipv4_addr); 942 IPACMDBG_H("ipv4 addr mask 0x%x\n", data->ipv4_addr_mask); 943 944 /* The special below condition is to handle default gateway */ 945 if ((data->iptype == IPA_IP_v4) && (!data->ipv4_addr) && (!data->ipv4_addr_mask) && (active_v4 == false) 946 && (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX)) 947 { 948 wan_v4_addr_gw = data->ipv4_addr_gw; 949 wan_v4_addr_gw_set = true; 950 IPACMDBG_H("adding routing table, dev (%s) ip-type(%d), default gw (%x)\n", dev_name,data->iptype, wan_v4_addr_gw); 951 /* Check & construct STA header */ 952 handle_sta_header_add_evt(); 953 handle_route_add_evt(data->iptype); 954 /* Add IPv6 routing table if XLAT is enabled */ 955 if(is_xlat && (m_is_sta_mode == Q6_WAN) && (active_v6 == false)) 956 { 957 IPACMDBG_H("XLAT enabled: adding IPv6 routing table dev (%s)\n", dev_name); 958 handle_route_add_evt(IPA_IP_v6); 959 } 960 } 961 else if ((data->iptype == IPA_IP_v6) && 962 (!data->ipv6_addr[0]) && (!data->ipv6_addr[1]) && (!data->ipv6_addr[2]) && (!data->ipv6_addr[3]) && 963 (active_v6 == false) && (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX)) 964 { 965 if(ipv6_prefix[0] == 0 && ipv6_prefix[1] == 0) 966 { 967 IPACMDBG_H("IPv6 default route comes earlier than global IP, ignore.\n"); 968 return; 969 } 970 971 IPACMDBG_H("\n get default v6 route (dst:00.00.00.00)\n"); 972 IPACMDBG_H(" IPV6 dst: %08x:%08x:%08x:%08x \n", 973 data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); 974 IPACMDBG_H(" IPV6 gateway: %08x:%08x:%08x:%08x \n", 975 data->ipv6_addr_gw[0], data->ipv6_addr_gw[1], data->ipv6_addr_gw[2], data->ipv6_addr_gw[3]); 976 wan_v6_addr_gw[0] = data->ipv6_addr_gw[0]; 977 wan_v6_addr_gw[1] = data->ipv6_addr_gw[1]; 978 wan_v6_addr_gw[2] = data->ipv6_addr_gw[2]; 979 wan_v6_addr_gw[3] = data->ipv6_addr_gw[3]; 980 wan_v6_addr_gw_set = true; 981 /* Check & construct STA header */ 982 handle_sta_header_add_evt(); 983 handle_route_add_evt(data->iptype); 984 } 985 } 986 else /* double check if current default iface is not itself */ 987 { 988 if ((data->iptype == IPA_IP_v4) && (!data->ipv4_addr) && (!data->ipv4_addr_mask) && (active_v4 == true)) 989 { 990 IPACMDBG_H("Received v4 IPA_ROUTE_ADD_EVENT for other iface (%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); 991 IPACMDBG_H("ipv4 addr 0x%x\n", data->ipv4_addr); 992 IPACMDBG_H("ipv4 addr mask 0x%x\n", data->ipv4_addr_mask); 993 IPACMDBG_H("need clean default v4 route (dst:0.0.0.0) for old iface (%s)\n", dev_name); 994 wan_v4_addr_gw_set = false; 995 if(m_is_sta_mode == Q6_WAN) 996 { 997 del_wan_firewall_rule(IPA_IP_v4); 998 install_wan_filtering_rule(false); 999 handle_route_del_evt_ex(IPA_IP_v4); 1000 } 1001 else 1002 { 1003 del_dft_firewall_rules(IPA_IP_v4); 1004 handle_route_del_evt(IPA_IP_v4); 1005 } 1006 } 1007 else if ((data->iptype == IPA_IP_v6) && (!data->ipv6_addr[0]) && (!data->ipv6_addr[1]) && (!data->ipv6_addr[2]) && (!data->ipv6_addr[3]) && (active_v6 == true)) 1008 { 1009 IPACMDBG_H("Received v6 IPA_ROUTE_ADD_EVENT for other iface (%s)\n", IPACM_Iface::ipacmcfg->iface_table[ipa_interface_index].iface_name); 1010 IPACMDBG_H("need clean default v6 route for old iface (%s)\n", dev_name); 1011 if(m_is_sta_mode == Q6_WAN) 1012 { 1013 del_wan_firewall_rule(IPA_IP_v6); 1014 install_wan_filtering_rule(false); 1015 handle_route_del_evt_ex(IPA_IP_v6); 1016 } 1017 else 1018 { 1019 del_dft_firewall_rules(IPA_IP_v6); 1020 handle_route_del_evt(IPA_IP_v6); 1021 } 1022 } 1023 } 1024 } 1025 break; 1026 1027 case IPA_ROUTE_DEL_EVENT: 1028 { 1029 ipacm_event_data_addr *data = (ipacm_event_data_addr *)param; 1030 ipa_interface_index = iface_ipa_index_query(data->if_index); 1031 if (ipa_interface_index == ipa_if_num) 1032 { 1033 IPACMDBG_H("Received IPA_ROUTE_DEL_EVENT\n"); 1034 if ((data->iptype == IPA_IP_v4) && (!data->ipv4_addr) && (!data->ipv4_addr_mask) && (active_v4 == true)) 1035 { 1036 IPACMDBG_H("get del default v4 route (dst:0.0.0.0)\n"); 1037 wan_v4_addr_gw_set = false; 1038 if(m_is_sta_mode == Q6_WAN) 1039 { 1040 del_wan_firewall_rule(IPA_IP_v4); 1041 install_wan_filtering_rule(false); 1042 handle_route_del_evt_ex(IPA_IP_v4); 1043 1044 if(is_xlat && active_v6 == true) 1045 { 1046 IPACMDBG_H("XLAT enabled: Delete IPv6 routing table dev (%s)\n", dev_name); 1047 del_wan_firewall_rule(IPA_IP_v6); 1048 install_wan_filtering_rule(false); 1049 handle_route_del_evt_ex(IPA_IP_v6); 1050 } 1051 } 1052 else 1053 { 1054 del_dft_firewall_rules(IPA_IP_v4); 1055 handle_route_del_evt(IPA_IP_v4); 1056 } 1057 } 1058 else if ((data->iptype == IPA_IP_v6) && (!data->ipv6_addr[0]) && (!data->ipv6_addr[1]) && (!data->ipv6_addr[2]) && (!data->ipv6_addr[3]) && (active_v6 == true)) 1059 { 1060 1061 IPACMDBG_H("get del default v6 route (dst:00.00.00.00)\n"); 1062 if(m_is_sta_mode == Q6_WAN) 1063 { 1064 del_wan_firewall_rule(IPA_IP_v6); 1065 install_wan_filtering_rule(false); 1066 handle_route_del_evt_ex(IPA_IP_v6); 1067 } 1068 else 1069 { 1070 del_dft_firewall_rules(IPA_IP_v6); 1071 handle_route_del_evt(IPA_IP_v6); 1072 } 1073 } 1074 } 1075 } 1076 break; 1077 1078 case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT: 1079 { 1080 ipacm_event_data_all *data = (ipacm_event_data_all *)param; 1081 ipa_interface_index = iface_ipa_index_query(data->if_index); 1082 1083 if (ipa_interface_index == ipa_if_num) 1084 { 1085 IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n"); 1086 1087 if (m_is_sta_mode == WLAN_WAN) 1088 { 1089 if (data->iptype == IPA_IP_v4 && data->ipv4_addr == wan_v4_addr) 1090 { 1091 IPACMDBG_H("Ignore IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n"); 1092 IPACMDBG_H("for its own ipv4 address\n"); 1093 return; 1094 } 1095 else if (data->iptype == IPA_IP_v6) 1096 { 1097 for (uint32_t num_ipv6_addr = 0; num_ipv6_addr < num_dft_rt_v6; num_ipv6_addr++) 1098 { 1099 if ((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) && 1100 (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) && 1101 (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) && 1102 (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3])) 1103 { 1104 IPACMDBG_H("Ignore IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT in STA mode\n"); 1105 IPACMDBG_H("for its own ipv6 address\n"); 1106 return; 1107 } 1108 } 1109 } 1110 } 1111 1112 IPACMDBG_H("wan-iface got client \n"); 1113 /* first construc WAN-client full header */ 1114 if(memcmp(data->mac_addr, 1115 invalid_mac, 1116 sizeof(data->mac_addr)) == 0) 1117 { 1118 IPACMDBG_H("Received invalid Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 1119 data->mac_addr[0], data->mac_addr[1], data->mac_addr[2], 1120 data->mac_addr[3], data->mac_addr[4], data->mac_addr[5]); 1121 return; 1122 } 1123 1124 handle_wan_hdr_init(data->mac_addr); 1125 IPACMDBG_H("construct wan-client header and route rules \n"); 1126 /* Associate with IP and construct RT-rule */ 1127 if (handle_wan_client_ipaddr(data) == IPACM_FAILURE) 1128 { 1129 return; 1130 } 1131 handle_wan_client_route_rule(data->mac_addr, data->iptype); 1132 /* Check & construct STA header */ 1133 handle_sta_header_add_evt(); 1134 return; 1135 } 1136 } 1137 break; 1138 1139 case IPA_SW_ROUTING_ENABLE: 1140 IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n"); 1141 /* handle software routing enable event */ 1142 if(m_is_sta_mode == Q6_WAN) 1143 { 1144 install_wan_filtering_rule(true); 1145 } 1146 else 1147 { 1148 handle_software_routing_enable(); 1149 } 1150 break; 1151 1152 case IPA_SW_ROUTING_DISABLE: 1153 IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n"); 1154 /* handle software routing disable event */ 1155 if(m_is_sta_mode == Q6_WAN) 1156 { 1157 /* send current DL rules to modem */ 1158 install_wan_filtering_rule(false); 1159 softwarerouting_act = false; 1160 } 1161 else 1162 { 1163 handle_software_routing_disable(); 1164 } 1165 break; 1166 1167 case IPA_FIREWALL_CHANGE_EVENT: 1168 IPACMDBG_H("Received IPA_FIREWALL_CHANGE_EVENT\n"); 1169 1170 if(m_is_sta_mode == Q6_WAN) 1171 { 1172 if(is_default_gateway == false) 1173 { 1174 IPACMDBG_H("Interface %s is not default gw, return.\n", dev_name); 1175 return; 1176 } 1177 1178 if(ip_type == IPA_IP_v4) 1179 { 1180 del_wan_firewall_rule(IPA_IP_v4); 1181 config_wan_firewall_rule(IPA_IP_v4); 1182 install_wan_filtering_rule(false); 1183 } 1184 else if(ip_type == IPA_IP_v6) 1185 { 1186 del_wan_firewall_rule(IPA_IP_v6); 1187 config_wan_firewall_rule(IPA_IP_v6); 1188 install_wan_filtering_rule(false); 1189 } 1190 else if(ip_type == IPA_IP_MAX) 1191 { 1192 del_wan_firewall_rule(IPA_IP_v4); 1193 config_wan_firewall_rule(IPA_IP_v4); 1194 1195 del_wan_firewall_rule(IPA_IP_v6); 1196 config_wan_firewall_rule(IPA_IP_v6); 1197 install_wan_filtering_rule(false); 1198 } 1199 else 1200 { 1201 IPACMERR("IP type is not expected.\n"); 1202 } 1203 } 1204 else 1205 { 1206 if (active_v4) 1207 { 1208 del_dft_firewall_rules(IPA_IP_v4); 1209 config_dft_firewall_rules(IPA_IP_v4); 1210 } 1211 if (active_v6) 1212 { 1213 1214 del_dft_firewall_rules(IPA_IP_v6); 1215 config_dft_firewall_rules(IPA_IP_v6); 1216 } 1217 } 1218 break; 1219 1220 case IPA_WLAN_SWITCH_TO_SCC: 1221 if(IPACM_Wan::backhaul_is_sta_mode == true) 1222 { 1223 IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_SCC\n"); 1224 if(ip_type == IPA_IP_MAX) 1225 { 1226 handle_wlan_SCC_MCC_switch(true, IPA_IP_v4); 1227 handle_wlan_SCC_MCC_switch(true, IPA_IP_v6); 1228 handle_wan_client_SCC_MCC_switch(true, IPA_IP_v4); 1229 handle_wan_client_SCC_MCC_switch(true, IPA_IP_v6); 1230 } 1231 else 1232 { 1233 handle_wlan_SCC_MCC_switch(true, ip_type); 1234 handle_wan_client_SCC_MCC_switch(true, ip_type); 1235 } 1236 } 1237 break; 1238 1239 case IPA_WLAN_SWITCH_TO_MCC: 1240 if(IPACM_Wan::backhaul_is_sta_mode == true) 1241 { 1242 IPACMDBG_H("Received IPA_WLAN_SWITCH_TO_MCC\n"); 1243 if(ip_type == IPA_IP_MAX) 1244 { 1245 handle_wlan_SCC_MCC_switch(false, IPA_IP_v4); 1246 handle_wlan_SCC_MCC_switch(false, IPA_IP_v6); 1247 handle_wan_client_SCC_MCC_switch(false, IPA_IP_v4); 1248 handle_wan_client_SCC_MCC_switch(false, IPA_IP_v6); 1249 } 1250 else 1251 { 1252 handle_wlan_SCC_MCC_switch(false, ip_type); 1253 handle_wan_client_SCC_MCC_switch(false, ip_type); 1254 } 1255 } 1256 break; 1257 1258 default: 1259 break; 1260 } 1261 1262 return; 1263 } 1264 1265 /* wan default route/filter rule configuration */ 1266 int IPACM_Wan::handle_route_add_evt(ipa_ip_type iptype) 1267 { 1268 1269 /* add default WAN route */ 1270 struct ipa_ioc_add_rt_rule *rt_rule = NULL; 1271 struct ipa_rt_rule_add *rt_rule_entry; 1272 uint32_t tx_index = 0; 1273 const int NUM = 1; 1274 ipacm_cmd_q_data evt_data; 1275 struct ipa_ioc_get_hdr hdr; 1276 1277 IPACMDBG_H("ip-type:%d\n", iptype); 1278 1279 /* copy header from tx-property, see if partial or not */ 1280 /* assume all tx-property uses the same header name for v4 or v6*/ 1281 1282 if(tx_prop == NULL) 1283 { 1284 IPACMDBG_H("No tx properties, ignore default route setting\n"); 1285 return IPACM_SUCCESS; 1286 } 1287 1288 is_default_gateway = true; 1289 IPACMDBG_H("Default route is added to iface %s.\n", dev_name); 1290 1291 if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == BRIDGE) 1292 { 1293 IPACM_Wan::backhaul_is_wan_bridge = true; 1294 } 1295 else 1296 { 1297 IPACM_Wan::backhaul_is_wan_bridge = false; 1298 } 1299 IPACMDBG_H("backhaul_is_wan_bridge ?: %d \n", IPACM_Wan::backhaul_is_wan_bridge); 1300 1301 if (m_is_sta_mode !=Q6_WAN) 1302 { 1303 IPACM_Wan::backhaul_is_sta_mode = true; 1304 if((iptype==IPA_IP_v4) && (header_set_v4 != true)) 1305 { 1306 header_partial_default_wan_v4 = true; 1307 IPACMDBG_H("STA ipv4-header haven't constructed \n"); 1308 return IPACM_SUCCESS; 1309 } 1310 else if((iptype==IPA_IP_v6) && (header_set_v6 != true)) 1311 { 1312 header_partial_default_wan_v6 = true; 1313 IPACMDBG_H("STA ipv6-header haven't constructed \n"); 1314 return IPACM_SUCCESS; 1315 } 1316 } 1317 else 1318 { 1319 IPACM_Wan::backhaul_is_sta_mode = false; 1320 IPACMDBG_H("reset backhaul to LTE \n"); 1321 1322 if (iface_query != NULL && iface_query->num_ext_props > 0) 1323 { 1324 if(ext_prop == NULL) 1325 { 1326 IPACMERR("Extended property is empty.\n"); 1327 return IPACM_FAILURE; 1328 } 1329 else 1330 { 1331 IPACM_Iface::ipacmcfg->SetQmapId(ext_prop->ext[0].mux_id); 1332 IPACMDBG_H("Setting up QMAP ID %d.\n", ext_prop->ext[0].mux_id); 1333 } 1334 } 1335 else 1336 { 1337 IPACMERR("iface_query is empty.\n"); 1338 return IPACM_FAILURE; 1339 } 1340 } 1341 #if 0 1342 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++) 1343 { 1344 if(tx_prop->tx[cnt].ip==iptype) 1345 break; 1346 } 1347 1348 if(tx_prop->tx[cnt].hdr_name != NULL) 1349 { 1350 memset(&sCopyHeader, 0, sizeof(sCopyHeader)); 1351 memcpy(sCopyHeader.name, 1352 tx_prop->tx[cnt].hdr_name, 1353 sizeof(sCopyHeader.name)); 1354 1355 IPACMDBG_H("header name: %s\n", sCopyHeader.name); 1356 if (m_header.CopyHeader(&sCopyHeader) == false) 1357 { 1358 IPACMERR("ioctl copy header failed"); 1359 return IPACM_FAILURE; 1360 } 1361 IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); 1362 if(sCopyHeader.is_partial) 1363 { 1364 IPACMDBG_H("Not setup default WAN routing rules cuz the header is not complete\n"); 1365 if(iptype==IPA_IP_v4) 1366 { 1367 header_partial_default_wan_v4 = true; 1368 } 1369 else 1370 { 1371 header_partial_default_wan_v6 = true; 1372 } 1373 return IPACM_SUCCESS; 1374 } 1375 else 1376 { 1377 if(iptype==IPA_IP_v4) 1378 { 1379 header_partial_default_wan_v4 = false; 1380 } 1381 else 1382 { 1383 header_partial_default_wan_v6 = false; 1384 } 1385 } 1386 } 1387 #endif 1388 1389 rt_rule = (struct ipa_ioc_add_rt_rule *) 1390 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + 1391 NUM * sizeof(struct ipa_rt_rule_add)); 1392 1393 if (!rt_rule) 1394 { 1395 IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n"); 1396 return IPACM_FAILURE; 1397 } 1398 1399 rt_rule->commit = 1; 1400 rt_rule->num_rules = (uint8_t)NUM; 1401 rt_rule->ip = iptype; 1402 1403 1404 IPACMDBG_H(" WAN table created %s \n", rt_rule->rt_tbl_name); 1405 rt_rule_entry = &rt_rule->rules[0]; 1406 rt_rule_entry->at_rear = true; 1407 1408 if(m_is_sta_mode != Q6_WAN) 1409 { 1410 IPACMDBG_H(" WAN instance is in STA mode \n"); 1411 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) 1412 { 1413 if(iptype != tx_prop->tx[tx_index].ip) 1414 { 1415 IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n", 1416 tx_index, tx_prop->tx[tx_index].ip,iptype); 1417 continue; 1418 } 1419 1420 /* use the STA-header handler */ 1421 if (iptype == IPA_IP_v4) 1422 { 1423 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name, sizeof(rt_rule->rt_tbl_name)); 1424 rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v4; 1425 } 1426 else 1427 { 1428 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name)); 1429 rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v6; 1430 } 1431 1432 if(IPACM_Iface::ipacmcfg->isMCC_Mode == true) 1433 { 1434 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n", 1435 tx_prop->tx[tx_index].alt_dst_pipe); 1436 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe; 1437 } 1438 else 1439 { 1440 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; 1441 } 1442 memcpy(&rt_rule_entry->rule.attrib, 1443 &tx_prop->tx[tx_index].attrib, 1444 sizeof(rt_rule_entry->rule.attrib)); 1445 1446 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 1447 if (iptype == IPA_IP_v4) 1448 { 1449 rt_rule_entry->rule.attrib.u.v4.dst_addr = 0; 1450 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0; 1451 #ifdef FEATURE_IPA_V3 1452 1453 rt_rule_entry->rule.hashable = true; 1454 #endif 1455 if (false == m_routing.AddRoutingRule(rt_rule)) 1456 { 1457 IPACMERR("Routing rule addition failed!\n"); 1458 free(rt_rule); 1459 return IPACM_FAILURE; 1460 } 1461 wan_route_rule_v4_hdl[tx_index] = rt_rule_entry->rt_rule_hdl; 1462 IPACMDBG_H("Got ipv4 wan-route rule hdl:0x%x,tx:%d,ip-type: %d \n", 1463 wan_route_rule_v4_hdl[tx_index], 1464 tx_index, 1465 iptype); 1466 } 1467 else 1468 { 1469 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0; 1470 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0; 1471 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0; 1472 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0; 1473 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0; 1474 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0; 1475 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0; 1476 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0; 1477 #ifdef FEATURE_IPA_V3 1478 rt_rule_entry->rule.hashable = true; 1479 #endif 1480 if (false == m_routing.AddRoutingRule(rt_rule)) 1481 { 1482 IPACMERR("Routing rule addition failed!\n"); 1483 free(rt_rule); 1484 return IPACM_FAILURE; 1485 } 1486 wan_route_rule_v6_hdl[tx_index] = rt_rule_entry->rt_rule_hdl; 1487 IPACMDBG_H("Set ipv6 wan-route rule hdl for v6_lan_table:0x%x,tx:%d,ip-type: %d \n", 1488 wan_route_rule_v6_hdl[tx_index], 1489 tx_index, 1490 iptype); 1491 } 1492 } 1493 } 1494 1495 /* add a catch-all rule in wan dl routing table */ 1496 1497 if (iptype == IPA_IP_v6) 1498 { 1499 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name)); 1500 memset(rt_rule_entry, 0, sizeof(struct ipa_rt_rule_add)); 1501 rt_rule_entry->at_rear = true; 1502 if(m_is_sta_mode == Q6_WAN) 1503 { 1504 memset(&hdr, 0, sizeof(hdr)); 1505 strlcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name)); 1506 hdr.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 1507 if(m_header.GetHeaderHandle(&hdr) == false) 1508 { 1509 IPACMERR("Failed to get QMAP header.\n"); 1510 return IPACM_FAILURE; 1511 } 1512 rt_rule_entry->rule.hdr_hdl = hdr.hdl; 1513 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_WAN_CONS; 1514 } 1515 else 1516 { 1517 /* create dummy ethernet header for v6 RX path */ 1518 IPACMDBG_H("Construct dummy ethernet_header\n"); 1519 if (add_dummy_rx_hdr()) 1520 { 1521 IPACMERR("Construct dummy ethernet_header failed!\n"); 1522 free(rt_rule); 1523 return IPACM_FAILURE; 1524 } 1525 rt_rule_entry->rule.hdr_proc_ctx_hdl = hdr_proc_hdl_dummy_v6; 1526 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; 1527 } 1528 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; 1529 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0; 1530 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0; 1531 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0; 1532 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0; 1533 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0; 1534 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0; 1535 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0; 1536 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0; 1537 #ifdef FEATURE_IPA_V3 1538 rt_rule_entry->rule.hashable = true; 1539 #endif 1540 if (false == m_routing.AddRoutingRule(rt_rule)) 1541 { 1542 IPACMERR("Routing rule addition failed!\n"); 1543 free(rt_rule); 1544 return IPACM_FAILURE; 1545 } 1546 wan_route_rule_v6_hdl_a5[0] = rt_rule_entry->rt_rule_hdl; 1547 IPACMDBG_H("Set ipv6 wan-route rule hdl for v6_wan_table:0x%x,tx:%d,ip-type: %d \n", 1548 wan_route_rule_v6_hdl_a5[0], 0, iptype); 1549 } 1550 1551 ipacm_event_iface_up *wanup_data; 1552 wanup_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up)); 1553 if (wanup_data == NULL) 1554 { 1555 IPACMERR("Unable to allocate memory\n"); 1556 free(rt_rule); 1557 return IPACM_FAILURE; 1558 } 1559 memset(wanup_data, 0, sizeof(ipacm_event_iface_up)); 1560 1561 if (iptype == IPA_IP_v4) 1562 { 1563 IPACM_Wan::wan_up = true; 1564 active_v4 = true; 1565 memcpy(IPACM_Wan::wan_up_dev_name, 1566 dev_name, 1567 sizeof(IPACM_Wan::wan_up_dev_name)); 1568 1569 if(m_is_sta_mode == Q6_WAN) 1570 { 1571 config_wan_firewall_rule(IPA_IP_v4); 1572 install_wan_filtering_rule(false); 1573 } 1574 else 1575 { 1576 config_dft_firewall_rules(IPA_IP_v4); 1577 } 1578 1579 memcpy(wanup_data->ifname, dev_name, sizeof(wanup_data->ifname)); 1580 wanup_data->ipv4_addr = wan_v4_addr; 1581 if (m_is_sta_mode!=Q6_WAN) 1582 { 1583 wanup_data->is_sta = true; 1584 } 1585 else 1586 { 1587 wanup_data->is_sta = false; 1588 } 1589 IPACMDBG_H("Posting IPA_HANDLE_WAN_UP with below information:\n"); 1590 IPACMDBG_H("if_name:%s, ipv4_address:0x%x, is sta mode:%d\n", 1591 wanup_data->ifname, wanup_data->ipv4_addr, wanup_data->is_sta); 1592 memset(&evt_data, 0, sizeof(evt_data)); 1593 1594 /* send xlat configuration for installing uplink rules */ 1595 if(is_xlat && (m_is_sta_mode == Q6_WAN)) 1596 { 1597 IPACM_Wan::xlat_mux_id = ext_prop->ext[0].mux_id; 1598 wanup_data->xlat_mux_id = IPACM_Wan::xlat_mux_id; 1599 IPACMDBG_H("Set xlat configuraiton with below information:\n"); 1600 IPACMDBG_H("xlat_enabled: %d xlat_mux_id: %d \n", 1601 is_xlat, xlat_mux_id); 1602 } 1603 else 1604 { 1605 IPACM_Wan::xlat_mux_id = 0; 1606 wanup_data->xlat_mux_id = 0; 1607 IPACMDBG_H("No xlat configuratio:\n"); 1608 } 1609 evt_data.event = IPA_HANDLE_WAN_UP; 1610 evt_data.evt_data = (void *)wanup_data; 1611 IPACM_EvtDispatcher::PostEvt(&evt_data); 1612 } 1613 else 1614 { 1615 memcpy(backhaul_ipv6_prefix, ipv6_prefix, sizeof(backhaul_ipv6_prefix)); 1616 IPACMDBG_H("Setup backhaul ipv6 prefix to be 0x%08x%08x.\n", backhaul_ipv6_prefix[0], backhaul_ipv6_prefix[1]); 1617 1618 IPACM_Wan::wan_up_v6 = true; 1619 active_v6 = true; 1620 memcpy(IPACM_Wan::wan_up_dev_name, 1621 dev_name, 1622 sizeof(IPACM_Wan::wan_up_dev_name)); 1623 1624 if(m_is_sta_mode == Q6_WAN) 1625 { 1626 config_wan_firewall_rule(IPA_IP_v6); 1627 install_wan_filtering_rule(false); 1628 } 1629 else 1630 { 1631 config_dft_firewall_rules(IPA_IP_v6); 1632 } 1633 1634 memcpy(wanup_data->ifname, dev_name, sizeof(wanup_data->ifname)); 1635 if (m_is_sta_mode!=Q6_WAN) 1636 { 1637 wanup_data->is_sta = true; 1638 } 1639 else 1640 { 1641 wanup_data->is_sta = false; 1642 } 1643 memcpy(wanup_data->ipv6_prefix, ipv6_prefix, sizeof(wanup_data->ipv6_prefix)); 1644 IPACMDBG_H("Posting IPA_HANDLE_WAN_UP_V6 with below information:\n"); 1645 IPACMDBG_H("if_name:%s, is sta mode: %d\n", wanup_data->ifname, wanup_data->is_sta); 1646 IPACMDBG_H("ipv6 prefix: 0x%08x%08x.\n", ipv6_prefix[0], ipv6_prefix[1]); 1647 memset(&evt_data, 0, sizeof(evt_data)); 1648 evt_data.event = IPA_HANDLE_WAN_UP_V6; 1649 evt_data.evt_data = (void *)wanup_data; 1650 IPACM_EvtDispatcher::PostEvt(&evt_data); 1651 } 1652 1653 /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */ 1654 IPACMDBG_H("dev %s add producer dependency\n", dev_name); 1655 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]); 1656 IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false); 1657 1658 if(rt_rule != NULL) 1659 { 1660 free(rt_rule); 1661 } 1662 return IPACM_SUCCESS; 1663 } 1664 1665 #ifdef FEATURE_IPA_ANDROID 1666 /* wan default route/filter rule configuration */ 1667 int IPACM_Wan::post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether) 1668 { 1669 ipacm_cmd_q_data evt_data; 1670 ipacm_event_iface_up_tehter *wanup_data; 1671 1672 wanup_data = (ipacm_event_iface_up_tehter *)malloc(sizeof(ipacm_event_iface_up_tehter)); 1673 if (wanup_data == NULL) 1674 { 1675 IPACMERR("Unable to allocate memory\n"); 1676 return IPACM_FAILURE; 1677 } 1678 memset(wanup_data, 0, sizeof(ipacm_event_iface_up_tehter)); 1679 1680 wanup_data->if_index_tether = ipa_if_num_tether; 1681 if (m_is_sta_mode!=Q6_WAN) 1682 { 1683 wanup_data->is_sta = true; 1684 } 1685 else 1686 { 1687 wanup_data->is_sta = false; 1688 } 1689 IPACMDBG_H("Posting IPA_HANDLE_WAN_UP_TETHER with below information:\n"); 1690 IPACMDBG_H("tether_if_name:%s, is sta mode:%d\n", 1691 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, wanup_data->is_sta); 1692 memset(&evt_data, 0, sizeof(evt_data)); 1693 1694 if (iptype == IPA_IP_v4) 1695 { 1696 evt_data.event = IPA_HANDLE_WAN_UP_TETHER; 1697 /* Add support tether ifaces to its array*/ 1698 IPACM_Wan::ipa_if_num_tether_v4[IPACM_Wan::ipa_if_num_tether_v4_total] = ipa_if_num_tether; 1699 IPACMDBG_H("adding tether iface(%s) ipa_if_num_tether_v4_total(%d) on wan_iface(%s)\n", 1700 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, 1701 IPACM_Wan::ipa_if_num_tether_v4_total, 1702 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); 1703 IPACM_Wan::ipa_if_num_tether_v4_total++; 1704 } 1705 else 1706 { 1707 evt_data.event = IPA_HANDLE_WAN_UP_V6_TETHER; 1708 memcpy(wanup_data->ipv6_prefix, ipv6_prefix, sizeof(wanup_data->ipv6_prefix)); 1709 /* Add support tether ifaces to its array*/ 1710 IPACM_Wan::ipa_if_num_tether_v6[IPACM_Wan::ipa_if_num_tether_v6_total] = ipa_if_num_tether; 1711 IPACMDBG_H("adding tether iface(%s) ipa_if_num_tether_v6_total(%d) on wan_iface(%s)\n", 1712 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, 1713 IPACM_Wan::ipa_if_num_tether_v6_total, 1714 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); 1715 IPACM_Wan::ipa_if_num_tether_v6_total++; 1716 } 1717 evt_data.evt_data = (void *)wanup_data; 1718 IPACM_EvtDispatcher::PostEvt(&evt_data); 1719 1720 return IPACM_SUCCESS; 1721 } 1722 1723 /* wan default route/filter rule configuration */ 1724 int IPACM_Wan::post_wan_down_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether) 1725 { 1726 ipacm_cmd_q_data evt_data; 1727 ipacm_event_iface_up_tehter *wandown_data; 1728 uint32_t i, j; 1729 1730 wandown_data = (ipacm_event_iface_up_tehter *)malloc(sizeof(ipacm_event_iface_up_tehter)); 1731 if (wandown_data == NULL) 1732 { 1733 IPACMERR("Unable to allocate memory\n"); 1734 return IPACM_FAILURE; 1735 } 1736 memset(wandown_data, 0, sizeof(ipacm_event_iface_up_tehter)); 1737 1738 wandown_data->if_index_tether = ipa_if_num_tether; 1739 if (m_is_sta_mode!=Q6_WAN) 1740 { 1741 wandown_data->is_sta = true; 1742 } 1743 else 1744 { 1745 wandown_data->is_sta = false; 1746 } 1747 IPACMDBG_H("Posting IPA_HANDLE_WAN_DOWN_TETHER with below information:\n"); 1748 IPACMDBG_H("tether_if_name:%s, is sta mode:%d\n", 1749 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name, wandown_data->is_sta); 1750 memset(&evt_data, 0, sizeof(evt_data)); 1751 1752 if (iptype == IPA_IP_v4) 1753 { 1754 evt_data.event = IPA_HANDLE_WAN_DOWN_TETHER; 1755 /* delete support tether ifaces to its array*/ 1756 for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++) 1757 { 1758 if(IPACM_Wan::ipa_if_num_tether_v4[i] == ipa_if_num_tether) 1759 { 1760 IPACMDBG_H("Found tether client at position %d name(%s)\n", i, 1761 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name); 1762 break; 1763 } 1764 } 1765 if(i == IPACM_Wan::ipa_if_num_tether_v4_total) 1766 { 1767 IPACMDBG_H("Not finding the tether client.\n"); 1768 free(wandown_data); 1769 return IPACM_SUCCESS; 1770 } 1771 for(j = i+1; j < IPACM_Wan::ipa_if_num_tether_v4_total; j++) 1772 { 1773 IPACM_Wan::ipa_if_num_tether_v4[j-1] = IPACM_Wan::ipa_if_num_tether_v4[j]; 1774 } 1775 IPACM_Wan::ipa_if_num_tether_v4_total--; 1776 IPACMDBG_H("Now the total num of ipa_if_num_tether_v4_total is %d on wan-iface(%s)\n", 1777 IPACM_Wan::ipa_if_num_tether_v4_total, 1778 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); 1779 } 1780 else 1781 { 1782 evt_data.event = IPA_HANDLE_WAN_DOWN_V6_TETHER; 1783 /* delete support tether ifaces to its array*/ 1784 for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++) 1785 { 1786 if(IPACM_Wan::ipa_if_num_tether_v6[i] == ipa_if_num_tether) 1787 { 1788 IPACMDBG_H("Found tether client at position %d name(%s)\n", i, 1789 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name); 1790 break; 1791 } 1792 } 1793 if(i == IPACM_Wan::ipa_if_num_tether_v6_total) 1794 { 1795 IPACMDBG_H("Not finding the tether client.\n"); 1796 free(wandown_data); 1797 return IPACM_SUCCESS; 1798 } 1799 for(j = i+1; j < IPACM_Wan::ipa_if_num_tether_v6_total; j++) 1800 { 1801 IPACM_Wan::ipa_if_num_tether_v6[j-1] = IPACM_Wan::ipa_if_num_tether_v6[j]; 1802 } 1803 IPACM_Wan::ipa_if_num_tether_v6_total--; 1804 IPACMDBG_H("Now the total num of ipa_if_num_tether_v6_total is %d on wan-iface(%s)\n", 1805 IPACM_Wan::ipa_if_num_tether_v6_total, 1806 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); 1807 } 1808 evt_data.evt_data = (void *)wandown_data; 1809 IPACM_EvtDispatcher::PostEvt(&evt_data); 1810 return IPACM_SUCCESS; 1811 } 1812 #endif 1813 1814 /* construct complete ethernet header */ 1815 int IPACM_Wan::handle_sta_header_add_evt() 1816 { 1817 int res = IPACM_SUCCESS, index = IPACM_INVALID_INDEX; 1818 if((header_set_v4 == true) || (header_set_v6 == true)) 1819 { 1820 IPACMDBG_H("Already add STA full header\n"); 1821 return IPACM_SUCCESS; 1822 } 1823 1824 /* checking if the ipv4 same as default route */ 1825 if(wan_v4_addr_gw_set) 1826 { 1827 index = get_wan_client_index_ipv4(wan_v4_addr_gw); 1828 if (index != IPACM_INVALID_INDEX) 1829 { 1830 IPACMDBG_H("Matched client index: %d\n", index); 1831 IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 1832 get_client_memptr(wan_client, index)->mac[0], 1833 get_client_memptr(wan_client, index)->mac[1], 1834 get_client_memptr(wan_client, index)->mac[2], 1835 get_client_memptr(wan_client, index)->mac[3], 1836 get_client_memptr(wan_client, index)->mac[4], 1837 get_client_memptr(wan_client, index)->mac[5]); 1838 1839 if(get_client_memptr(wan_client, index)->ipv4_header_set) 1840 { 1841 hdr_hdl_sta_v4 = get_client_memptr(wan_client, index)->hdr_hdl_v4; 1842 header_set_v4 = true; 1843 IPACMDBG_H("add full ipv4 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v4); 1844 /* store external_ap's MAC */ 1845 memcpy(ext_router_mac_addr, get_client_memptr(wan_client, index)->mac, sizeof(ext_router_mac_addr)); 1846 } 1847 else 1848 { 1849 IPACMERR(" wan-client got ipv4 however didn't construct complete ipv4 header \n"); 1850 return IPACM_FAILURE; 1851 } 1852 1853 if(get_client_memptr(wan_client, index)->ipv6_header_set) 1854 { 1855 hdr_hdl_sta_v6 = get_client_memptr(wan_client, index)->hdr_hdl_v6; 1856 header_set_v6 = true; 1857 IPACMDBG_H("add full ipv6 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v6); 1858 } 1859 else 1860 { 1861 IPACMERR(" wan-client got ipv6 however didn't construct complete ipv6 header \n"); 1862 return IPACM_FAILURE; 1863 } 1864 } 1865 else 1866 { 1867 IPACMDBG_H(" currently can't find matched wan-client's MAC-addr, waiting for header construction\n"); 1868 return IPACM_SUCCESS; 1869 } 1870 } 1871 1872 /* checking if the ipv4 same as default route */ 1873 if(wan_v6_addr_gw_set) 1874 { 1875 index = get_wan_client_index_ipv6(wan_v6_addr_gw); 1876 if (index != IPACM_INVALID_INDEX) 1877 { 1878 IPACMDBG_H("Matched client index: %d\n", index); 1879 IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 1880 get_client_memptr(wan_client, index)->mac[0], 1881 get_client_memptr(wan_client, index)->mac[1], 1882 get_client_memptr(wan_client, index)->mac[2], 1883 get_client_memptr(wan_client, index)->mac[3], 1884 get_client_memptr(wan_client, index)->mac[4], 1885 get_client_memptr(wan_client, index)->mac[5]); 1886 1887 if(get_client_memptr(wan_client, index)->ipv6_header_set) 1888 { 1889 hdr_hdl_sta_v6 = get_client_memptr(wan_client, index)->hdr_hdl_v6; 1890 header_set_v6 = true; 1891 IPACMDBG_H("add full ipv6 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v6); 1892 /* store external_ap's MAC */ 1893 memcpy(ext_router_mac_addr, get_client_memptr(wan_client, index)->mac, sizeof(ext_router_mac_addr)); 1894 } 1895 else 1896 { 1897 IPACMERR(" wan-client got ipv6 however didn't construct complete ipv4 header \n"); 1898 return IPACM_FAILURE; 1899 } 1900 1901 if(get_client_memptr(wan_client, index)->ipv4_header_set) 1902 { 1903 hdr_hdl_sta_v4 = get_client_memptr(wan_client, index)->hdr_hdl_v4; 1904 header_set_v4 = true; 1905 IPACMDBG_H("add full ipv4 header hdl: (%x)\n", get_client_memptr(wan_client, index)->hdr_hdl_v4); 1906 } 1907 else 1908 { 1909 IPACMERR(" wan-client got ipv4 however didn't construct complete ipv4 header \n"); 1910 return IPACM_FAILURE; 1911 } 1912 } 1913 else 1914 { 1915 IPACMDBG_H(" currently can't find matched wan-client's MAC-addr, waiting for header construction\n"); 1916 return IPACM_SUCCESS; 1917 } 1918 } 1919 1920 /* see if default routes are setup before constructing full header */ 1921 if(header_partial_default_wan_v4 == true) 1922 { 1923 handle_route_add_evt(IPA_IP_v4); 1924 } 1925 1926 if(header_partial_default_wan_v6 == true) 1927 { 1928 handle_route_add_evt(IPA_IP_v6); 1929 } 1930 return res; 1931 } 1932 1933 /* For checking attribute mask field in firewall rules for IPv6 only */ 1934 bool IPACM_Wan::check_dft_firewall_rules_attr_mask(IPACM_firewall_conf_t *firewall_config) 1935 { 1936 uint32_t attrib_mask = 0ul; 1937 attrib_mask = IPA_FLT_SRC_PORT_RANGE | 1938 IPA_FLT_DST_PORT_RANGE | 1939 IPA_FLT_TYPE | 1940 IPA_FLT_CODE | 1941 IPA_FLT_SPI | 1942 IPA_FLT_SRC_PORT | 1943 IPA_FLT_DST_PORT; 1944 1945 for (int i = 0; i < firewall_config->num_extd_firewall_entries; i++) 1946 { 1947 if (firewall_config->extd_firewall_entries[i].ip_vsn == 6) 1948 { 1949 if (firewall_config->extd_firewall_entries[i].attrib.attrib_mask & attrib_mask) 1950 { 1951 IPACMDBG_H("IHL based attribute mask is found: install IPv6 frag firewall rule \n"); 1952 return true; 1953 } 1954 } 1955 } 1956 IPACMDBG_H("IHL based attribute mask is not found: no IPv6 frag firewall rule \n"); 1957 return false; 1958 } 1959 1960 /* for STA mode: add firewall rules */ 1961 int IPACM_Wan::config_dft_firewall_rules(ipa_ip_type iptype) 1962 { 1963 struct ipa_flt_rule_add flt_rule_entry; 1964 int i, rule_v4 = 0, rule_v6 = 0, len; 1965 1966 IPACMDBG_H("ip-family: %d; \n", iptype); 1967 1968 if (rx_prop == NULL) 1969 { 1970 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); 1971 return IPACM_SUCCESS; 1972 } 1973 1974 /* default firewall is disable and the rule action is drop */ 1975 memset(&firewall_config, 0, sizeof(firewall_config)); 1976 strlcpy(firewall_config.firewall_config_file, "/etc/mobileap_firewall.xml", sizeof(firewall_config.firewall_config_file)); 1977 1978 IPACMDBG_H("Firewall XML file is %s \n", firewall_config.firewall_config_file); 1979 if (IPACM_SUCCESS == IPACM_read_firewall_xml(firewall_config.firewall_config_file, &firewall_config)) 1980 { 1981 IPACMDBG_H("QCMAP Firewall XML read OK \n"); 1982 /* find the number of v4/v6 firewall rules */ 1983 for (i = 0; i < firewall_config.num_extd_firewall_entries; i++) 1984 { 1985 if (firewall_config.extd_firewall_entries[i].ip_vsn == 4) 1986 { 1987 rule_v4++; 1988 } 1989 else 1990 { 1991 rule_v6++; 1992 } 1993 } 1994 IPACMDBG_H("firewall rule v4:%d v6:%d total:%d\n", rule_v4, rule_v6, firewall_config.num_extd_firewall_entries); 1995 } 1996 else 1997 { 1998 IPACMERR("QCMAP Firewall XML read failed, no that file, use default configuration \n"); 1999 } 2000 2001 /* construct ipa_ioc_add_flt_rule with N firewall rules */ 2002 ipa_ioc_add_flt_rule *m_pFilteringTable = NULL; 2003 len = sizeof(struct ipa_ioc_add_flt_rule) + 1 * sizeof(struct ipa_flt_rule_add); 2004 m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len); 2005 if (!m_pFilteringTable) 2006 { 2007 IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); 2008 return IPACM_FAILURE; 2009 } 2010 2011 if(iptype == IPA_IP_v6 && 2012 firewall_config.firewall_enable == true && 2013 check_dft_firewall_rules_attr_mask(&firewall_config)) 2014 { 2015 m_pFilteringTable->commit = 1; 2016 m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; 2017 m_pFilteringTable->global = false; 2018 m_pFilteringTable->ip = IPA_IP_v6; 2019 m_pFilteringTable->num_rules = (uint8_t)1; 2020 2021 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 2022 flt_rule_entry.at_rear = true; 2023 #ifdef FEATURE_IPA_V3 2024 flt_rule_entry.at_rear = false; 2025 flt_rule_entry.rule.hashable = false; 2026 #endif 2027 flt_rule_entry.flt_rule_hdl = -1; 2028 flt_rule_entry.status = -1; 2029 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 2030 memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(struct ipa_rule_attrib)); 2031 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT; 2032 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2033 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2034 { 2035 IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); 2036 free(m_pFilteringTable); 2037 return IPACM_FAILURE; 2038 } 2039 else 2040 { 2041 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 2042 ipv6_frag_firewall_flt_rule_hdl = m_pFilteringTable->rules[0].flt_rule_hdl; 2043 is_ipv6_frag_firewall_flt_rule_installed = true; 2044 IPACMDBG_H("Installed IPv6 frag firewall rule, handle %d.\n", ipv6_frag_firewall_flt_rule_hdl); 2045 } 2046 } 2047 2048 if (iptype == IPA_IP_v4) 2049 { 2050 if (rule_v4 == 0) 2051 { 2052 memset(m_pFilteringTable, 0, len); 2053 2054 m_pFilteringTable->commit = 1; 2055 m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; 2056 m_pFilteringTable->global = false; 2057 m_pFilteringTable->ip = IPA_IP_v4; 2058 m_pFilteringTable->num_rules = (uint8_t)1; 2059 2060 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 2061 2062 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan_v4)) 2063 { 2064 IPACMERR("m_routing.GetRoutingTable(rt_tbl_lan_v4) Failed.\n"); 2065 free(m_pFilteringTable); 2066 return IPACM_FAILURE; 2067 } 2068 2069 flt_rule_entry.flt_rule_hdl = -1; 2070 flt_rule_entry.status = -1; 2071 2072 /* firewall disable, all traffic are allowed */ 2073 if(firewall_config.firewall_enable == true) 2074 { 2075 flt_rule_entry.at_rear = true; 2076 2077 /* default action for v4 is go DST_NAT unless user set to exception*/ 2078 if(firewall_config.rule_action_accept == true) 2079 { 2080 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 2081 } 2082 else 2083 { 2084 if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER) 2085 { 2086 flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; 2087 } 2088 else 2089 { 2090 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2091 } 2092 } 2093 } 2094 else 2095 { 2096 flt_rule_entry.at_rear = true; 2097 if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER) 2098 { 2099 flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; 2100 } 2101 else 2102 { 2103 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2104 } 2105 } 2106 #ifdef FEATURE_IPA_V3 2107 flt_rule_entry.at_rear = true; 2108 flt_rule_entry.rule.hashable = true; 2109 #endif 2110 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl; 2111 memcpy(&flt_rule_entry.rule.attrib, 2112 &rx_prop->rx[0].attrib, 2113 sizeof(struct ipa_rule_attrib)); 2114 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 2115 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; 2116 flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000; 2117 2118 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2119 2120 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2121 { 2122 IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); 2123 free(m_pFilteringTable); 2124 return IPACM_FAILURE; 2125 } 2126 else 2127 { 2128 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1); 2129 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); 2130 } 2131 2132 /* copy filter hdls */ 2133 dft_wan_fl_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl; 2134 } 2135 else 2136 { 2137 memset(m_pFilteringTable, 0, len); 2138 2139 m_pFilteringTable->commit = 1; 2140 m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; 2141 m_pFilteringTable->global = false; 2142 m_pFilteringTable->ip = IPA_IP_v4; 2143 m_pFilteringTable->num_rules = (uint8_t)1; 2144 2145 IPACMDBG_H("Retreiving Routing handle for routing table name:%s\n", 2146 IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name); 2147 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_lan_v4)) 2148 { 2149 IPACMERR("m_routing.GetRoutingTable(&rt_tbl_lan_v4=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_lan_v4); 2150 free(m_pFilteringTable); 2151 return IPACM_FAILURE; 2152 } 2153 IPACMDBG_H("Routing handle for wan routing table:0x%x\n", IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl); 2154 2155 if(firewall_config.firewall_enable == true) 2156 { 2157 rule_v4 = 0; 2158 for (i = 0; i < firewall_config.num_extd_firewall_entries; i++) 2159 { 2160 if (firewall_config.extd_firewall_entries[i].ip_vsn == 4) 2161 { 2162 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 2163 2164 flt_rule_entry.at_rear = true; 2165 flt_rule_entry.flt_rule_hdl = -1; 2166 flt_rule_entry.status = -1; 2167 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl; 2168 2169 /* Accept v4 matched rules*/ 2170 if(firewall_config.rule_action_accept == true) 2171 { 2172 if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER) 2173 { 2174 flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; 2175 } 2176 else 2177 { 2178 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2179 } 2180 } 2181 else 2182 { 2183 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 2184 } 2185 #ifdef FEATURE_IPA_V3 2186 flt_rule_entry.rule.hashable = true; 2187 #endif 2188 memcpy(&flt_rule_entry.rule.attrib, 2189 &firewall_config.extd_firewall_entries[i].attrib, 2190 sizeof(struct ipa_rule_attrib)); 2191 2192 IPACMDBG_H("rx property attrib mask: 0x%x\n", rx_prop->rx[0].attrib.attrib_mask); 2193 flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask; 2194 flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask; 2195 flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data; 2196 2197 /* check if the rule is define as TCP_UDP, split into 2 rules, 1 for TCP and 1 UDP */ 2198 if (firewall_config.extd_firewall_entries[i].attrib.u.v4.protocol 2199 == IPACM_FIREWALL_IPPROTO_TCP_UDP) 2200 { 2201 /* insert TCP rule*/ 2202 flt_rule_entry.rule.attrib.u.v4.protocol = IPACM_FIREWALL_IPPROTO_TCP; 2203 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2204 2205 IPACMDBG_H("Filter rule attrib mask: 0x%x\n", 2206 m_pFilteringTable->rules[0].rule.attrib.attrib_mask); 2207 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2208 { 2209 IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); 2210 free(m_pFilteringTable); 2211 return IPACM_FAILURE; 2212 } 2213 else 2214 { 2215 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1); 2216 /* save v4 firewall filter rule handler */ 2217 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", 2218 m_pFilteringTable->rules[rule_v4].flt_rule_hdl, 2219 m_pFilteringTable->rules[rule_v4].status); 2220 firewall_hdl_v4[rule_v4] = m_pFilteringTable->rules[0].flt_rule_hdl; 2221 num_firewall_v4++; 2222 rule_v4++; 2223 } 2224 2225 /* insert UDP rule*/ 2226 flt_rule_entry.rule.attrib.u.v4.protocol = IPACM_FIREWALL_IPPROTO_UDP; 2227 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2228 2229 IPACMDBG_H("Filter rule attrib mask: 0x%x\n", 2230 m_pFilteringTable->rules[0].rule.attrib.attrib_mask); 2231 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2232 { 2233 IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); 2234 free(m_pFilteringTable); 2235 return IPACM_FAILURE; 2236 } 2237 else 2238 { 2239 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1); 2240 /* save v4 firewall filter rule handler */ 2241 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", 2242 m_pFilteringTable->rules[rule_v4].flt_rule_hdl, 2243 m_pFilteringTable->rules[rule_v4].status); 2244 firewall_hdl_v4[rule_v4] = m_pFilteringTable->rules[0].flt_rule_hdl; 2245 num_firewall_v4++; 2246 rule_v4++; 2247 } 2248 } 2249 else 2250 { 2251 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2252 2253 IPACMDBG_H("Filter rule attrib mask: 0x%x\n", 2254 m_pFilteringTable->rules[0].rule.attrib.attrib_mask); 2255 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2256 { 2257 IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); 2258 free(m_pFilteringTable); 2259 return IPACM_FAILURE; 2260 } 2261 else 2262 { 2263 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1); 2264 /* save v4 firewall filter rule handler */ 2265 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", 2266 m_pFilteringTable->rules[rule_v4].flt_rule_hdl, 2267 m_pFilteringTable->rules[rule_v4].status); 2268 firewall_hdl_v4[rule_v4] = m_pFilteringTable->rules[0].flt_rule_hdl; 2269 num_firewall_v4++; 2270 rule_v4++; 2271 } 2272 } 2273 } 2274 } /* end of firewall ipv4 filter rule add for loop*/ 2275 } 2276 /* configure default filter rule */ 2277 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 2278 2279 flt_rule_entry.flt_rule_hdl = -1; 2280 flt_rule_entry.status = -1; 2281 2282 /* firewall disable, all traffic are allowed */ 2283 if(firewall_config.firewall_enable == true) 2284 { 2285 flt_rule_entry.at_rear = true; 2286 2287 /* default action for v4 is go DST_NAT unless user set to exception*/ 2288 if(firewall_config.rule_action_accept == true) 2289 { 2290 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 2291 } 2292 else 2293 { 2294 if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER) 2295 { 2296 flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; 2297 } 2298 else 2299 { 2300 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2301 } 2302 } 2303 } 2304 else 2305 { 2306 flt_rule_entry.at_rear = true; 2307 if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_mode == ROUTER) 2308 { 2309 flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; 2310 } 2311 else 2312 { 2313 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2314 } 2315 } 2316 #ifdef FEATURE_IPA_V3 2317 flt_rule_entry.rule.hashable = true; 2318 #endif 2319 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.hdl; 2320 memcpy(&flt_rule_entry.rule.attrib, 2321 &rx_prop->rx[0].attrib, 2322 sizeof(struct ipa_rule_attrib)); 2323 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 2324 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; 2325 flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000; 2326 2327 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2328 2329 IPACMDBG_H("Filter rule attrib mask: 0x%x\n", 2330 m_pFilteringTable->rules[0].rule.attrib.attrib_mask); 2331 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2332 { 2333 IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); 2334 free(m_pFilteringTable); 2335 return IPACM_FAILURE; 2336 } 2337 else 2338 { 2339 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1); 2340 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); 2341 } 2342 2343 /* copy filter hdls */ 2344 dft_wan_fl_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl; 2345 } 2346 2347 } 2348 else 2349 { 2350 if (rule_v6 == 0) 2351 { 2352 memset(m_pFilteringTable, 0, len); 2353 2354 m_pFilteringTable->commit = 1; 2355 m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; 2356 m_pFilteringTable->global = false; 2357 m_pFilteringTable->ip = IPA_IP_v6; 2358 m_pFilteringTable->num_rules = (uint8_t)1; 2359 2360 /* Construct ICMP rule */ 2361 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 2362 flt_rule_entry.at_rear = true; 2363 flt_rule_entry.flt_rule_hdl = -1; 2364 flt_rule_entry.status = -1; 2365 flt_rule_entry.rule.retain_hdr = 1; 2366 flt_rule_entry.rule.eq_attrib_type = 0; 2367 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 2368 #ifdef FEATURE_IPA_V3 2369 flt_rule_entry.rule.hashable = true; 2370 #endif 2371 memcpy(&flt_rule_entry.rule.attrib, 2372 &rx_prop->rx[0].attrib, 2373 sizeof(struct ipa_rule_attrib)); 2374 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR; 2375 flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6; 2376 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2377 2378 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2379 { 2380 IPACMERR("Error Adding Filtering rules, aborting...\n"); 2381 free(m_pFilteringTable); 2382 return IPACM_FAILURE; 2383 } 2384 else 2385 { 2386 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 2387 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); 2388 } 2389 /* copy filter hdls */ 2390 dft_wan_fl_hdl[2] = m_pFilteringTable->rules[0].flt_rule_hdl; 2391 2392 /* End of construct ICMP rule */ 2393 2394 /* v6 default route */ 2395 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 2396 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v6)) //rt_tbl_wan_v6 rt_tbl_v6 2397 { 2398 IPACMERR("m_routing.GetRoutingTable(rt_tbl_wan_v6) Failed.\n"); 2399 free(m_pFilteringTable); 2400 return IPACM_FAILURE; 2401 } 2402 2403 flt_rule_entry.flt_rule_hdl = -1; 2404 flt_rule_entry.status = -1; 2405 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.hdl; 2406 2407 /* firewall disable, all traffic are allowed */ 2408 if(firewall_config.firewall_enable == true) 2409 { 2410 flt_rule_entry.at_rear = true; 2411 2412 /* default action for v6 is PASS_TO_ROUTE unless user set to exception*/ 2413 if(firewall_config.rule_action_accept == true) 2414 { 2415 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 2416 } 2417 else 2418 { 2419 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2420 } 2421 } 2422 else 2423 { 2424 flt_rule_entry.at_rear = true; 2425 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2426 } 2427 #ifdef FEATURE_IPA_V3 2428 flt_rule_entry.rule.hashable = true; 2429 #endif 2430 memcpy(&flt_rule_entry.rule.attrib, 2431 &rx_prop->rx[0].attrib, 2432 sizeof(struct ipa_rule_attrib)); 2433 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 2434 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000; 2435 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; 2436 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; 2437 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; 2438 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000; 2439 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; 2440 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; 2441 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; 2442 2443 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2444 2445 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2446 { 2447 IPACMERR("Error Adding Filtering rules, aborting...\n"); 2448 free(m_pFilteringTable); 2449 return IPACM_FAILURE; 2450 } 2451 else 2452 { 2453 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 2454 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); 2455 } 2456 2457 /* copy filter hdls */ 2458 dft_wan_fl_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl; 2459 } 2460 else 2461 { 2462 memset(m_pFilteringTable, 0, len); 2463 2464 m_pFilteringTable->commit = 1; 2465 m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; 2466 m_pFilteringTable->global = false; 2467 m_pFilteringTable->ip = IPA_IP_v6; 2468 m_pFilteringTable->num_rules = (uint8_t)1; 2469 2470 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v6)) 2471 { 2472 IPACMERR("m_routing.GetRoutingTable(rt_tbl_wan_v6) Failed.\n"); 2473 free(m_pFilteringTable); 2474 return IPACM_FAILURE; 2475 } 2476 2477 if(firewall_config.firewall_enable == true) 2478 { 2479 rule_v6 = 0; 2480 for (i = 0; i < firewall_config.num_extd_firewall_entries; i++) 2481 { 2482 if (firewall_config.extd_firewall_entries[i].ip_vsn == 6) 2483 { 2484 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 2485 2486 flt_rule_entry.at_rear = true; 2487 flt_rule_entry.flt_rule_hdl = -1; 2488 flt_rule_entry.status = -1; 2489 2490 /* matched rules for v6 go PASS_TO_ROUTE */ 2491 if(firewall_config.rule_action_accept == true) 2492 { 2493 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2494 } 2495 else 2496 { 2497 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 2498 } 2499 #ifdef FEATURE_IPA_V3 2500 flt_rule_entry.rule.hashable = true; 2501 #endif 2502 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.hdl; 2503 memcpy(&flt_rule_entry.rule.attrib, 2504 &firewall_config.extd_firewall_entries[i].attrib, 2505 sizeof(struct ipa_rule_attrib)); 2506 flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask; 2507 flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask; 2508 flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data; 2509 2510 /* check if the rule is define as TCP/UDP */ 2511 if (firewall_config.extd_firewall_entries[i].attrib.u.v6.next_hdr == IPACM_FIREWALL_IPPROTO_TCP_UDP) 2512 { 2513 /* insert TCP rule*/ 2514 flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_TCP; 2515 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2516 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2517 { 2518 IPACMERR("Error Adding Filtering rules, aborting...\n"); 2519 free(m_pFilteringTable); 2520 return IPACM_FAILURE; 2521 } 2522 else 2523 { 2524 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 2525 /* save v4 firewall filter rule handler */ 2526 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); 2527 firewall_hdl_v6[rule_v6] = m_pFilteringTable->rules[0].flt_rule_hdl; 2528 num_firewall_v6++; 2529 rule_v6++; 2530 } 2531 2532 /* insert UDP rule*/ 2533 flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_UDP; 2534 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2535 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2536 { 2537 IPACMERR("Error Adding Filtering rules, aborting...\n"); 2538 free(m_pFilteringTable); 2539 return IPACM_FAILURE; 2540 } 2541 else 2542 { 2543 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 2544 /* save v6 firewall filter rule handler */ 2545 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); 2546 firewall_hdl_v6[rule_v6] = m_pFilteringTable->rules[0].flt_rule_hdl; 2547 num_firewall_v6++; 2548 rule_v6++; 2549 } 2550 } 2551 else 2552 { 2553 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2554 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2555 { 2556 IPACMERR("Error Adding Filtering rules, aborting...\n"); 2557 free(m_pFilteringTable); 2558 return IPACM_FAILURE; 2559 } 2560 else 2561 { 2562 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 2563 /* save v6 firewall filter rule handler */ 2564 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); 2565 firewall_hdl_v6[rule_v6] = m_pFilteringTable->rules[0].flt_rule_hdl; 2566 num_firewall_v6++; 2567 rule_v6++; 2568 } 2569 } 2570 } 2571 } /* end of firewall ipv6 filter rule add for loop*/ 2572 } 2573 2574 /* Construct ICMP rule */ 2575 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 2576 flt_rule_entry.at_rear = true; 2577 flt_rule_entry.flt_rule_hdl = -1; 2578 flt_rule_entry.status = -1; 2579 flt_rule_entry.rule.retain_hdr = 1; 2580 flt_rule_entry.rule.eq_attrib_type = 0; 2581 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 2582 #ifdef FEATURE_IPA_V3 2583 flt_rule_entry.rule.hashable = true; 2584 #endif 2585 memcpy(&flt_rule_entry.rule.attrib, 2586 &rx_prop->rx[0].attrib, 2587 sizeof(struct ipa_rule_attrib)); 2588 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR; 2589 flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6; 2590 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2591 2592 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2593 { 2594 IPACMERR("Error Adding Filtering rules, aborting...\n"); 2595 free(m_pFilteringTable); 2596 return IPACM_FAILURE; 2597 } 2598 else 2599 { 2600 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 2601 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); 2602 } 2603 /* copy filter hdls */ 2604 dft_wan_fl_hdl[2] = m_pFilteringTable->rules[0].flt_rule_hdl; 2605 /* End of construct ICMP rule */ 2606 2607 /* setup default wan filter rule */ 2608 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 2609 2610 flt_rule_entry.flt_rule_hdl = -1; 2611 flt_rule_entry.status = -1; 2612 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.hdl; 2613 2614 /* firewall disable, all traffic are allowed */ 2615 if(firewall_config.firewall_enable == true) 2616 { 2617 flt_rule_entry.at_rear = true; 2618 2619 /* default action for v6 is PASS_TO_ROUTE unless user set to exception*/ 2620 if(firewall_config.rule_action_accept == true) 2621 { 2622 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 2623 } 2624 else 2625 { 2626 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2627 } 2628 } 2629 else 2630 { 2631 flt_rule_entry.at_rear = true; 2632 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2633 } 2634 #ifdef FEATURE_IPA_V3 2635 flt_rule_entry.rule.hashable = true; 2636 #endif 2637 memcpy(&flt_rule_entry.rule.attrib, 2638 &rx_prop->rx[0].attrib, 2639 sizeof(struct ipa_rule_attrib)); 2640 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 2641 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000; 2642 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; 2643 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; 2644 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; 2645 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000; 2646 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; 2647 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; 2648 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; 2649 2650 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2651 2652 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 2653 { 2654 IPACMERR("Error Adding Filtering rules, aborting...\n"); 2655 free(m_pFilteringTable); 2656 return IPACM_FAILURE; 2657 } 2658 else 2659 { 2660 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 2661 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); 2662 } 2663 /* copy filter hdls*/ 2664 dft_wan_fl_hdl[1] = m_pFilteringTable->rules[0].flt_rule_hdl; 2665 } 2666 } 2667 2668 if(m_pFilteringTable != NULL) 2669 { 2670 free(m_pFilteringTable); 2671 } 2672 return IPACM_SUCCESS; 2673 } 2674 2675 /* configure the initial firewall filter rules */ 2676 int IPACM_Wan::config_dft_firewall_rules_ex(struct ipa_flt_rule_add *rules, int rule_offset, ipa_ip_type iptype) 2677 { 2678 struct ipa_flt_rule_add flt_rule_entry; 2679 int i; 2680 int num_rules = 0, original_num_rules = 0; 2681 ipa_ioc_get_rt_tbl_indx rt_tbl_idx; 2682 ipa_ioc_generate_flt_eq flt_eq; 2683 int pos = rule_offset; 2684 2685 IPACMDBG_H("ip-family: %d; \n", iptype); 2686 2687 if (rx_prop == NULL) 2688 { 2689 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); 2690 return IPACM_SUCCESS; 2691 } 2692 2693 if(rules == NULL || rule_offset < 0) 2694 { 2695 IPACMERR("No filtering table is available.\n"); 2696 return IPACM_FAILURE; 2697 } 2698 2699 /* default firewall is disable and the rule action is drop */ 2700 memset(&firewall_config, 0, sizeof(firewall_config)); 2701 strlcpy(firewall_config.firewall_config_file, "/etc/mobileap_firewall.xml", sizeof(firewall_config.firewall_config_file)); 2702 2703 IPACMDBG_H("Firewall XML file is %s \n", firewall_config.firewall_config_file); 2704 if (IPACM_SUCCESS == IPACM_read_firewall_xml(firewall_config.firewall_config_file, &firewall_config)) 2705 { 2706 IPACMDBG_H("QCMAP Firewall XML read OK \n"); 2707 } 2708 else 2709 { 2710 IPACMERR("QCMAP Firewall XML read failed, no that file, use default configuration \n"); 2711 } 2712 2713 /* add IPv6 frag rule when firewall is enabled*/ 2714 if(iptype == IPA_IP_v6 && 2715 firewall_config.firewall_enable == true && 2716 check_dft_firewall_rules_attr_mask(&firewall_config)) 2717 { 2718 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 2719 flt_rule_entry.at_rear = true; 2720 #ifdef FEATURE_IPA_V3 2721 flt_rule_entry.at_rear = false; 2722 #endif 2723 flt_rule_entry.flt_rule_hdl = -1; 2724 flt_rule_entry.status = -1; 2725 2726 flt_rule_entry.rule.retain_hdr = 1; 2727 flt_rule_entry.rule.to_uc = 0; 2728 flt_rule_entry.rule.eq_attrib_type = 1; 2729 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2730 #ifdef FEATURE_IPA_V3 2731 flt_rule_entry.at_rear = false; 2732 flt_rule_entry.rule.hashable = false; 2733 #endif 2734 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 2735 rt_tbl_idx.ip = IPA_IP_v6; 2736 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); 2737 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 2738 if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) 2739 { 2740 IPACMERR("Failed to get routing table index from name\n"); 2741 return IPACM_FAILURE; 2742 } 2743 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 2744 IPACMDBG_H("IPv6 frag flt rule uses routing table index %d\n", rt_tbl_idx.idx); 2745 2746 flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask; 2747 flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask; 2748 flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data; 2749 2750 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_FRAGMENT; 2751 2752 change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib); 2753 2754 memset(&flt_eq, 0, sizeof(flt_eq)); 2755 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 2756 flt_eq.ip = IPA_IP_v6; 2757 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 2758 { 2759 IPACMERR("Failed to get eq_attrib\n"); 2760 return IPACM_FAILURE; 2761 } 2762 memcpy(&flt_rule_entry.rule.eq_attrib, 2763 &flt_eq.eq_attrib, 2764 sizeof(flt_rule_entry.rule.eq_attrib)); 2765 2766 memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2767 pos++; 2768 IPACM_Wan::num_v6_flt_rule++; 2769 } 2770 2771 if (iptype == IPA_IP_v4) 2772 { 2773 original_num_rules = IPACM_Wan::num_v4_flt_rule; 2774 if(firewall_config.firewall_enable == true) 2775 { 2776 for (i = 0; i < firewall_config.num_extd_firewall_entries; i++) 2777 { 2778 if (firewall_config.extd_firewall_entries[i].ip_vsn == 4) 2779 { 2780 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 2781 2782 flt_rule_entry.at_rear = true; 2783 flt_rule_entry.flt_rule_hdl = -1; 2784 flt_rule_entry.status = -1; 2785 2786 flt_rule_entry.rule.retain_hdr = 1; 2787 flt_rule_entry.rule.to_uc = 0; 2788 flt_rule_entry.rule.eq_attrib_type = 1; 2789 2790 /* Accept v4 matched rules*/ 2791 if(firewall_config.rule_action_accept == true) 2792 { 2793 flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; 2794 } 2795 else 2796 { 2797 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2798 } 2799 #ifdef FEATURE_IPA_V3 2800 flt_rule_entry.rule.hashable = true; 2801 #endif 2802 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 2803 rt_tbl_idx.ip = iptype; 2804 if(flt_rule_entry.rule.action == IPA_PASS_TO_ROUTING) 2805 { 2806 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); 2807 } 2808 else /*pass to dst nat*/ 2809 { 2810 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, IPA_RESOURCE_NAME_MAX); 2811 } 2812 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 2813 if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) 2814 { 2815 IPACMERR("Failed to get routing table index from name\n"); 2816 return IPACM_FAILURE; 2817 } 2818 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 2819 2820 IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); 2821 2822 memcpy(&flt_rule_entry.rule.attrib, 2823 &firewall_config.extd_firewall_entries[i].attrib, 2824 sizeof(struct ipa_rule_attrib)); 2825 2826 flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask; 2827 flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask; 2828 flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data; 2829 2830 change_to_network_order(IPA_IP_v4, &flt_rule_entry.rule.attrib); 2831 2832 /* check if the rule is define as TCP_UDP, split into 2 rules, 1 for TCP and 1 UDP */ 2833 if (firewall_config.extd_firewall_entries[i].attrib.u.v4.protocol == IPACM_FIREWALL_IPPROTO_TCP_UDP) 2834 { 2835 /* insert TCP rule*/ 2836 flt_rule_entry.rule.attrib.u.v4.protocol = IPACM_FIREWALL_IPPROTO_TCP; 2837 2838 memset(&flt_eq, 0, sizeof(flt_eq)); 2839 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 2840 flt_eq.ip = iptype; 2841 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 2842 { 2843 IPACMERR("Failed to get eq_attrib\n"); 2844 return IPACM_FAILURE; 2845 } 2846 memcpy(&flt_rule_entry.rule.eq_attrib, 2847 &flt_eq.eq_attrib, 2848 sizeof(flt_rule_entry.rule.eq_attrib)); 2849 2850 memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2851 IPACMDBG_H("Filter rule attrib mask: 0x%x\n", rules[pos].rule.attrib.attrib_mask); 2852 pos++; 2853 num_firewall_v4++; 2854 IPACM_Wan::num_v4_flt_rule++; 2855 2856 /* insert UDP rule*/ 2857 flt_rule_entry.rule.attrib.u.v4.protocol = IPACM_FIREWALL_IPPROTO_UDP; 2858 2859 memset(&flt_eq, 0, sizeof(flt_eq)); 2860 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 2861 flt_eq.ip = iptype; 2862 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 2863 { 2864 IPACMERR("Failed to get eq_attrib\n"); 2865 return IPACM_FAILURE; 2866 } 2867 memcpy(&flt_rule_entry.rule.eq_attrib, 2868 &flt_eq.eq_attrib, 2869 sizeof(flt_rule_entry.rule.eq_attrib)); 2870 2871 memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2872 IPACMDBG_H("Filter rule attrib mask: 0x%x\n", rules[pos].rule.attrib.attrib_mask); 2873 pos++; 2874 num_firewall_v4++; 2875 IPACM_Wan::num_v4_flt_rule++; 2876 } 2877 else 2878 { 2879 memset(&flt_eq, 0, sizeof(flt_eq)); 2880 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 2881 flt_eq.ip = iptype; 2882 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 2883 { 2884 IPACMERR("Failed to get eq_attrib\n"); 2885 return IPACM_FAILURE; 2886 } 2887 memcpy(&flt_rule_entry.rule.eq_attrib, 2888 &flt_eq.eq_attrib, 2889 sizeof(flt_rule_entry.rule.eq_attrib)); 2890 2891 memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2892 IPACMDBG_H("Filter rule attrib mask: 0x%x\n", rules[pos].rule.attrib.attrib_mask); 2893 pos++; 2894 num_firewall_v4++; 2895 IPACM_Wan::num_v4_flt_rule++; 2896 } 2897 } 2898 } /* end of firewall ipv4 filter rule add for loop*/ 2899 } 2900 /* configure default filter rule */ 2901 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 2902 2903 flt_rule_entry.at_rear = true; 2904 flt_rule_entry.flt_rule_hdl = -1; 2905 flt_rule_entry.status = -1; 2906 2907 flt_rule_entry.rule.retain_hdr = 1; 2908 flt_rule_entry.rule.to_uc = 0; 2909 flt_rule_entry.rule.eq_attrib_type = 1; 2910 2911 /* firewall disable, all traffic are allowed */ 2912 if(firewall_config.firewall_enable == true) 2913 { 2914 /* default action for v4 is go DST_NAT unless user set to exception*/ 2915 if(firewall_config.rule_action_accept == true) 2916 { 2917 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2918 } 2919 else 2920 { 2921 flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; 2922 } 2923 } 2924 else 2925 { 2926 if(isWan_Bridge_Mode()) 2927 { 2928 IPACMDBG_H("ODU is in bridge mode. \n"); 2929 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 2930 } 2931 else 2932 { 2933 flt_rule_entry.rule.action = IPA_PASS_TO_DST_NAT; 2934 } 2935 } 2936 #ifdef FEATURE_IPA_V3 2937 flt_rule_entry.rule.hashable = true; 2938 #endif 2939 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 2940 rt_tbl_idx.ip = iptype; 2941 2942 if(flt_rule_entry.rule.action == IPA_PASS_TO_ROUTING) 2943 { 2944 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); 2945 } 2946 else /*pass to dst nat*/ 2947 { 2948 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, IPA_RESOURCE_NAME_MAX); 2949 } 2950 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 2951 2952 if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) 2953 { 2954 IPACMERR("Failed to get routing table index from name\n"); 2955 return IPACM_FAILURE; 2956 } 2957 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 2958 2959 IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); 2960 2961 memcpy(&flt_rule_entry.rule.attrib, 2962 &rx_prop->rx[0].attrib, 2963 sizeof(struct ipa_rule_attrib)); 2964 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 2965 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; 2966 flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000; 2967 2968 change_to_network_order(IPA_IP_v4, &flt_rule_entry.rule.attrib); 2969 2970 memset(&flt_eq, 0, sizeof(flt_eq)); 2971 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 2972 flt_eq.ip = iptype; 2973 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 2974 { 2975 IPACMERR("Failed to get eq_attrib\n"); 2976 return IPACM_FAILURE; 2977 } 2978 2979 memcpy(&flt_rule_entry.rule.eq_attrib, 2980 &flt_eq.eq_attrib, 2981 sizeof(flt_rule_entry.rule.eq_attrib)); 2982 2983 memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 2984 IPACMDBG_H("Filter rule attrib mask: 0x%x\n", rules[pos].rule.attrib.attrib_mask); 2985 pos++; 2986 num_firewall_v4++; 2987 IPACM_Wan::num_v4_flt_rule++; 2988 2989 num_rules = IPACM_Wan::num_v4_flt_rule - original_num_rules - 1; 2990 } 2991 else 2992 { 2993 original_num_rules = IPACM_Wan::num_v6_flt_rule; 2994 2995 if(firewall_config.firewall_enable == true) 2996 { 2997 for (i = 0; i < firewall_config.num_extd_firewall_entries; i++) 2998 { 2999 if (firewall_config.extd_firewall_entries[i].ip_vsn == 6) 3000 { 3001 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 3002 3003 flt_rule_entry.at_rear = true; 3004 flt_rule_entry.flt_rule_hdl = -1; 3005 flt_rule_entry.status = -1; 3006 3007 flt_rule_entry.rule.retain_hdr = 1; 3008 flt_rule_entry.rule.to_uc = 0; 3009 flt_rule_entry.rule.eq_attrib_type = 1; 3010 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 3011 #ifdef FEATURE_IPA_V3 3012 flt_rule_entry.rule.hashable = true; 3013 #endif 3014 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 3015 rt_tbl_idx.ip = iptype; 3016 3017 /* matched rules for v6 go PASS_TO_ROUTE */ 3018 if(firewall_config.rule_action_accept == true) 3019 { 3020 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, IPA_RESOURCE_NAME_MAX); 3021 } 3022 else 3023 { 3024 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); 3025 } 3026 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 3027 3028 if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) 3029 { 3030 IPACMERR("Failed to get routing table index from name\n"); 3031 return IPACM_FAILURE; 3032 } 3033 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 3034 3035 IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); 3036 3037 memcpy(&flt_rule_entry.rule.attrib, 3038 &firewall_config.extd_firewall_entries[i].attrib, 3039 sizeof(struct ipa_rule_attrib)); 3040 3041 flt_rule_entry.rule.attrib.attrib_mask |= rx_prop->rx[0].attrib.attrib_mask; 3042 flt_rule_entry.rule.attrib.meta_data_mask = rx_prop->rx[0].attrib.meta_data_mask; 3043 flt_rule_entry.rule.attrib.meta_data = rx_prop->rx[0].attrib.meta_data; 3044 3045 change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib); 3046 3047 /* check if the rule is define as TCP/UDP */ 3048 if (firewall_config.extd_firewall_entries[i].attrib.u.v6.next_hdr == IPACM_FIREWALL_IPPROTO_TCP_UDP) 3049 { 3050 /* insert TCP rule*/ 3051 flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_TCP; 3052 3053 memset(&flt_eq, 0, sizeof(flt_eq)); 3054 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3055 flt_eq.ip = iptype; 3056 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3057 { 3058 IPACMERR("Failed to get eq_attrib\n"); 3059 return IPACM_FAILURE; 3060 } 3061 3062 memcpy(&flt_rule_entry.rule.eq_attrib, 3063 &flt_eq.eq_attrib, 3064 sizeof(flt_rule_entry.rule.eq_attrib)); 3065 memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3066 pos++; 3067 num_firewall_v6++; 3068 IPACM_Wan::num_v6_flt_rule++; 3069 3070 /* insert UDP rule*/ 3071 flt_rule_entry.rule.attrib.u.v6.next_hdr = IPACM_FIREWALL_IPPROTO_UDP; 3072 3073 memset(&flt_eq, 0, sizeof(flt_eq)); 3074 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3075 flt_eq.ip = iptype; 3076 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3077 { 3078 IPACMERR("Failed to get eq_attrib\n"); 3079 return IPACM_FAILURE; 3080 } 3081 3082 memcpy(&flt_rule_entry.rule.eq_attrib, 3083 &flt_eq.eq_attrib, 3084 sizeof(flt_rule_entry.rule.eq_attrib)); 3085 memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3086 pos++; 3087 num_firewall_v6++; 3088 IPACM_Wan::num_v6_flt_rule++; 3089 } 3090 else 3091 { 3092 memset(&flt_eq, 0, sizeof(flt_eq)); 3093 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3094 flt_eq.ip = iptype; 3095 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3096 { 3097 IPACMERR("Failed to get eq_attrib\n"); 3098 return IPACM_FAILURE; 3099 } 3100 3101 memcpy(&flt_rule_entry.rule.eq_attrib, 3102 &flt_eq.eq_attrib, 3103 sizeof(flt_rule_entry.rule.eq_attrib)); 3104 memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3105 pos++; 3106 num_firewall_v6++; 3107 IPACM_Wan::num_v6_flt_rule++; 3108 } 3109 } 3110 } /* end of firewall ipv6 filter rule add for loop*/ 3111 } 3112 3113 /* setup default wan filter rule */ 3114 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 3115 3116 flt_rule_entry.at_rear = true; 3117 flt_rule_entry.flt_rule_hdl = -1; 3118 flt_rule_entry.status = -1; 3119 3120 flt_rule_entry.rule.retain_hdr = 1; 3121 flt_rule_entry.rule.to_uc = 0; 3122 flt_rule_entry.rule.eq_attrib_type = 1; 3123 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 3124 #ifdef FEATURE_IPA_V3 3125 flt_rule_entry.rule.hashable = true; 3126 #endif 3127 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 3128 rt_tbl_idx.ip = iptype; 3129 /* firewall disable, all traffic are allowed */ 3130 if(firewall_config.firewall_enable == true) 3131 { 3132 /* default action for v6 is PASS_TO_ROUTE unless user set to exception*/ 3133 if(firewall_config.rule_action_accept == true) 3134 { 3135 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); 3136 } 3137 else 3138 { 3139 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, IPA_RESOURCE_NAME_MAX); 3140 } 3141 } 3142 else 3143 { 3144 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, IPA_RESOURCE_NAME_MAX); 3145 } 3146 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 3147 if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) 3148 { 3149 IPACMERR("Failed to get routing table index from name\n"); 3150 return IPACM_FAILURE; 3151 } 3152 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 3153 3154 IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); 3155 3156 memcpy(&flt_rule_entry.rule.attrib, 3157 &rx_prop->rx[1].attrib, 3158 sizeof(struct ipa_rule_attrib)); 3159 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 3160 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000; 3161 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; 3162 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; 3163 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; 3164 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000; 3165 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; 3166 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; 3167 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; 3168 3169 change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib); 3170 3171 memset(&flt_eq, 0, sizeof(flt_eq)); 3172 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3173 flt_eq.ip = iptype; 3174 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3175 { 3176 IPACMERR("Failed to get eq_attrib\n"); 3177 return IPACM_FAILURE; 3178 } 3179 memcpy(&flt_rule_entry.rule.eq_attrib, 3180 &flt_eq.eq_attrib, 3181 sizeof(flt_rule_entry.rule.eq_attrib)); 3182 memcpy(&(rules[pos]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3183 pos++; 3184 num_firewall_v6++; 3185 IPACM_Wan::num_v6_flt_rule++; 3186 3187 num_rules = IPACM_Wan::num_v6_flt_rule - original_num_rules - 1; 3188 } 3189 IPACMDBG_H("Constructed %d firewall rules for ip type %d\n", num_rules, iptype); 3190 return IPACM_SUCCESS; 3191 } 3192 3193 int IPACM_Wan::init_fl_rule_ex(ipa_ip_type iptype) 3194 { 3195 int res = IPACM_SUCCESS; 3196 3197 /* ADD corresponding ipa_rm_resource_name of RX-endpoint before adding all IPV4V6 FT-rules */ 3198 IPACMDBG_H(" dun add producer dependency from %s with registered rx-prop\n", dev_name); 3199 3200 if(iptype == IPA_IP_v4) 3201 { 3202 if(modem_ipv4_pdn_index == 0) /* install ipv4 default modem DL filtering rules only once */ 3203 { 3204 /* reset the num_v4_flt_rule*/ 3205 IPACM_Wan::num_v4_flt_rule = 0; 3206 add_dft_filtering_rule(flt_rule_v4, IPACM_Wan::num_v4_flt_rule, IPA_IP_v4); 3207 } 3208 } 3209 else if(iptype == IPA_IP_v6) 3210 { 3211 if(modem_ipv6_pdn_index == 0) /* install ipv6 default modem DL filtering rules only once */ 3212 { 3213 /* reset the num_v6_flt_rule*/ 3214 IPACM_Wan::num_v6_flt_rule = 0; 3215 add_dft_filtering_rule(flt_rule_v6, IPACM_Wan::num_v6_flt_rule, IPA_IP_v6); 3216 } 3217 } 3218 else 3219 { 3220 IPACMERR("IP type is not expected.\n"); 3221 res = IPACM_FAILURE; 3222 goto fail; 3223 } 3224 install_wan_filtering_rule(false); 3225 3226 fail: 3227 return res; 3228 } 3229 3230 int IPACM_Wan::add_icmp_alg_rules(struct ipa_flt_rule_add *rules, int rule_offset, ipa_ip_type iptype) 3231 { 3232 int res = IPACM_SUCCESS, i, original_num_rules = 0, num_rules = 0; 3233 struct ipa_flt_rule_add flt_rule_entry; 3234 IPACM_Config* ipacm_config = IPACM_Iface::ipacmcfg; 3235 ipa_ioc_generate_flt_eq flt_eq; 3236 ipa_ioc_get_rt_tbl_indx rt_tbl_idx; 3237 3238 if(rules == NULL || rule_offset < 0) 3239 { 3240 IPACMERR("No filtering table is available.\n"); 3241 return IPACM_FAILURE; 3242 } 3243 3244 if(iptype == IPA_IP_v4) 3245 { 3246 original_num_rules = IPACM_Wan::num_v4_flt_rule; 3247 3248 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 3249 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); 3250 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 3251 rt_tbl_idx.ip = iptype; 3252 if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) 3253 { 3254 IPACMERR("Failed to get routing table index from name\n"); 3255 res = IPACM_FAILURE; 3256 goto fail; 3257 } 3258 3259 IPACMDBG_H("WAN DL routing table %s has index %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, rt_tbl_idx.idx); 3260 3261 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 3262 3263 flt_rule_entry.at_rear = true; 3264 flt_rule_entry.flt_rule_hdl = -1; 3265 flt_rule_entry.status = -1; 3266 3267 flt_rule_entry.rule.retain_hdr = 1; 3268 flt_rule_entry.rule.to_uc = 0; 3269 flt_rule_entry.rule.eq_attrib_type = 1; 3270 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 3271 #ifdef FEATURE_IPA_V3 3272 flt_rule_entry.rule.hashable = true; 3273 #endif 3274 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 3275 3276 /* Configuring ICMP filtering rule */ 3277 memcpy(&flt_rule_entry.rule.attrib, 3278 &rx_prop->rx[0].attrib, 3279 sizeof(flt_rule_entry.rule.attrib)); 3280 /* Multiple PDNs may exist so keep meta-data */ 3281 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL; 3282 flt_rule_entry.rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP; 3283 3284 memset(&flt_eq, 0, sizeof(flt_eq)); 3285 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3286 flt_eq.ip = iptype; 3287 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3288 { 3289 IPACMERR("Failed to get eq_attrib\n"); 3290 res = IPACM_FAILURE; 3291 goto fail; 3292 } 3293 3294 memcpy(&flt_rule_entry.rule.eq_attrib, 3295 &flt_eq.eq_attrib, 3296 sizeof(flt_rule_entry.rule.eq_attrib)); 3297 3298 memcpy(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3299 3300 IPACM_Wan::num_v4_flt_rule++; 3301 3302 /* Configure ALG filtering rules */ 3303 memcpy(&flt_rule_entry.rule.attrib, 3304 &rx_prop->rx[0].attrib, 3305 sizeof(flt_rule_entry.rule.attrib)); 3306 /* remove meta data mask */ 3307 flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); 3308 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_PORT; 3309 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL; 3310 for(i = 0; i < ipacm_config->ipa_num_alg_ports; i++) 3311 { 3312 flt_rule_entry.rule.attrib.src_port = ipacm_config->alg_table[i].port; 3313 flt_rule_entry.rule.attrib.u.v4.protocol = ipacm_config->alg_table[i].protocol; 3314 3315 memset(&flt_eq, 0, sizeof(flt_eq)); 3316 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3317 flt_eq.ip = iptype; 3318 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3319 { 3320 IPACMERR("Failed to get eq_attrib\n"); 3321 res = IPACM_FAILURE; 3322 goto fail; 3323 } 3324 memcpy(&flt_rule_entry.rule.eq_attrib, 3325 &flt_eq.eq_attrib, 3326 sizeof(flt_rule_entry.rule.eq_attrib)); 3327 memcpy(&(rules[rule_offset + 1 + i]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3328 IPACM_Wan::num_v4_flt_rule++; 3329 } 3330 3331 memcpy(&flt_rule_entry.rule.attrib, 3332 &rx_prop->rx[0].attrib, 3333 sizeof(flt_rule_entry.rule.attrib)); 3334 /* remove meta data mask */ 3335 flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); 3336 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_PORT; 3337 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL; 3338 for(i = 0; i < ipacm_config->ipa_num_alg_ports; i++) 3339 { 3340 flt_rule_entry.rule.attrib.dst_port = ipacm_config->alg_table[i].port; 3341 flt_rule_entry.rule.attrib.u.v4.protocol = ipacm_config->alg_table[i].protocol; 3342 3343 memset(&flt_eq, 0, sizeof(flt_eq)); 3344 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3345 flt_eq.ip = iptype; 3346 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3347 { 3348 IPACMERR("Failed to get eq_attrib\n"); 3349 res = IPACM_FAILURE; 3350 goto fail; 3351 } 3352 3353 memcpy(&flt_rule_entry.rule.eq_attrib, 3354 &flt_eq.eq_attrib, 3355 sizeof(flt_rule_entry.rule.eq_attrib)); 3356 3357 memcpy(&(rules[rule_offset + ipacm_config->ipa_num_alg_ports + 1 + i]), 3358 &flt_rule_entry, 3359 sizeof(struct ipa_flt_rule_add)); 3360 IPACM_Wan::num_v4_flt_rule++; 3361 } 3362 num_rules = IPACM_Wan::num_v4_flt_rule - original_num_rules; 3363 } 3364 else /* IPv6 case */ 3365 { 3366 original_num_rules = IPACM_Wan::num_v6_flt_rule; 3367 3368 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 3369 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); 3370 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 3371 rt_tbl_idx.ip = iptype; 3372 if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) 3373 { 3374 IPACMERR("Failed to get routing table index from name\n"); 3375 res = IPACM_FAILURE; 3376 goto fail; 3377 } 3378 3379 IPACMDBG_H("WAN DL routing table %s has index %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, rt_tbl_idx.idx); 3380 3381 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 3382 3383 flt_rule_entry.at_rear = true; 3384 flt_rule_entry.flt_rule_hdl = -1; 3385 flt_rule_entry.status = -1; 3386 3387 flt_rule_entry.rule.retain_hdr = 1; 3388 flt_rule_entry.rule.to_uc = 0; 3389 flt_rule_entry.rule.eq_attrib_type = 1; 3390 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 3391 #ifdef FEATURE_IPA_V3 3392 flt_rule_entry.rule.hashable = true; 3393 #endif 3394 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 3395 3396 /* Configuring ICMP filtering rule */ 3397 memcpy(&flt_rule_entry.rule.attrib, 3398 &rx_prop->rx[1].attrib, 3399 sizeof(flt_rule_entry.rule.attrib)); 3400 /* Multiple PDNs may exist so keep meta-data */ 3401 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR; 3402 flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6; 3403 3404 memset(&flt_eq, 0, sizeof(flt_eq)); 3405 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3406 flt_eq.ip = iptype; 3407 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3408 { 3409 IPACMERR("Failed to get eq_attrib\n"); 3410 res = IPACM_FAILURE; 3411 goto fail; 3412 } 3413 3414 memcpy(&flt_rule_entry.rule.eq_attrib, 3415 &flt_eq.eq_attrib, 3416 sizeof(flt_rule_entry.rule.eq_attrib)); 3417 3418 memcpy(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3419 IPACM_Wan::num_v6_flt_rule++; 3420 3421 num_rules = IPACM_Wan::num_v6_flt_rule - original_num_rules; 3422 } 3423 3424 fail: 3425 IPACMDBG_H("Constructed %d ICMP/ALG rules for ip type %d\n", num_rules, iptype); 3426 return res; 3427 } 3428 3429 int IPACM_Wan::query_ext_prop() 3430 { 3431 int fd, ret = IPACM_SUCCESS; 3432 uint32_t cnt; 3433 3434 if (iface_query->num_ext_props > 0) 3435 { 3436 fd = open(IPA_DEVICE_NAME, O_RDWR); 3437 IPACMDBG_H("iface query-property \n"); 3438 if (0 == fd) 3439 { 3440 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); 3441 return IPACM_FAILURE; 3442 } 3443 3444 ext_prop = (struct ipa_ioc_query_intf_ext_props *) 3445 calloc(1, sizeof(struct ipa_ioc_query_intf_ext_props) + 3446 iface_query->num_ext_props * sizeof(struct ipa_ioc_ext_intf_prop)); 3447 if(ext_prop == NULL) 3448 { 3449 IPACMERR("Unable to allocate memory.\n"); 3450 return IPACM_FAILURE; 3451 } 3452 memcpy(ext_prop->name, dev_name, 3453 sizeof(dev_name)); 3454 ext_prop->num_ext_props = iface_query->num_ext_props; 3455 3456 IPACMDBG_H("Query extended property for iface %s\n", ext_prop->name); 3457 3458 ret = ioctl(fd, IPA_IOC_QUERY_INTF_EXT_PROPS, ext_prop); 3459 if (ret < 0) 3460 { 3461 IPACMERR("ioctl IPA_IOC_QUERY_INTF_EXT_PROPS failed\n"); 3462 /* ext_prop memory will free when iface-down*/ 3463 free(ext_prop); 3464 close(fd); 3465 return ret; 3466 } 3467 3468 IPACMDBG_H("Wan interface has %d tx props, %d rx props and %d ext props\n", 3469 iface_query->num_tx_props, iface_query->num_rx_props, iface_query->num_ext_props); 3470 3471 for (cnt = 0; cnt < ext_prop->num_ext_props; cnt++) 3472 { 3473 #ifndef FEATURE_IPA_V3 3474 IPACMDBG_H("Ex(%d): ip-type: %d, mux_id: %d, flt_action: %d\n, rt_tbl_idx: %d, is_xlat_rule: %d flt_hdl: %d\n", 3475 cnt, ext_prop->ext[cnt].ip, ext_prop->ext[cnt].mux_id, ext_prop->ext[cnt].action, 3476 ext_prop->ext[cnt].rt_tbl_idx, ext_prop->ext[cnt].is_xlat_rule, ext_prop->ext[cnt].filter_hdl); 3477 #else /* defined (FEATURE_IPA_V3) */ 3478 IPACMDBG_H("Ex(%d): ip-type: %d, mux_id: %d, flt_action: %d\n, rt_tbl_idx: %d, is_xlat_rule: %d rule_id: %d\n", 3479 cnt, ext_prop->ext[cnt].ip, ext_prop->ext[cnt].mux_id, ext_prop->ext[cnt].action, 3480 ext_prop->ext[cnt].rt_tbl_idx, ext_prop->ext[cnt].is_xlat_rule, ext_prop->ext[cnt].rule_id); 3481 #endif 3482 } 3483 3484 if(IPACM_Wan::is_ext_prop_set == false) 3485 { 3486 IPACM_Iface::ipacmcfg->SetExtProp(ext_prop); 3487 IPACM_Wan::is_ext_prop_set = true; 3488 } 3489 close(fd); 3490 } 3491 return IPACM_SUCCESS; 3492 } 3493 3494 int IPACM_Wan::config_wan_firewall_rule(ipa_ip_type iptype) 3495 { 3496 int res = IPACM_SUCCESS; 3497 3498 IPACMDBG_H("Configure WAN DL firewall rules.\n"); 3499 3500 if(iptype == IPA_IP_v4) 3501 { 3502 IPACM_Wan::num_v4_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4; 3503 if(IPACM_FAILURE == add_icmp_alg_rules(flt_rule_v4, IPACM_Wan::num_v4_flt_rule, IPA_IP_v4)) 3504 { 3505 IPACMERR("Failed to add ICMP and ALG port filtering rules.\n"); 3506 res = IPACM_FAILURE; 3507 goto fail; 3508 } 3509 IPACMDBG_H("Succeded in constructing ICMP/ALG rules for ip type %d\n", iptype); 3510 3511 if(IPACM_FAILURE == config_dft_firewall_rules_ex(flt_rule_v4, IPACM_Wan::num_v4_flt_rule, IPA_IP_v4)) 3512 { 3513 IPACMERR("Failed to add firewall filtering rules.\n"); 3514 res = IPACM_FAILURE; 3515 goto fail; 3516 } 3517 IPACMDBG_H("Succeded in constructing firewall rules for ip type %d\n", iptype); 3518 } 3519 else if(iptype == IPA_IP_v6) 3520 { 3521 IPACM_Wan::num_v6_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6; 3522 if(IPACM_FAILURE == add_icmp_alg_rules(flt_rule_v6, IPACM_Wan::num_v6_flt_rule, IPA_IP_v6)) 3523 { 3524 IPACMERR("Failed to add ICMP and ALG port filtering rules.\n"); 3525 res = IPACM_FAILURE; 3526 goto fail; 3527 } 3528 IPACMDBG_H("Succeded in constructing ICMP/ALG rules for ip type %d\n", iptype); 3529 3530 if(IPACM_FAILURE == config_dft_firewall_rules_ex(flt_rule_v6, IPACM_Wan::num_v6_flt_rule, IPA_IP_v6)) 3531 { 3532 IPACMERR("Failed to add firewall filtering rules.\n"); 3533 res = IPACM_FAILURE; 3534 goto fail; 3535 } 3536 IPACMDBG_H("Succeded in constructing firewall rules for ip type %d\n", iptype); 3537 } 3538 else 3539 { 3540 IPACMERR("IP type is not expected.\n"); 3541 return IPACM_FAILURE; 3542 } 3543 3544 fail: 3545 return res; 3546 } 3547 3548 int IPACM_Wan::add_dft_filtering_rule(struct ipa_flt_rule_add *rules, int rule_offset, ipa_ip_type iptype) 3549 { 3550 struct ipa_ioc_get_rt_tbl_indx rt_tbl_idx; 3551 struct ipa_flt_rule_add flt_rule_entry; 3552 struct ipa_ioc_generate_flt_eq flt_eq; 3553 int res = IPACM_SUCCESS; 3554 3555 if(rules == NULL) 3556 { 3557 IPACMERR("No filtering table available.\n"); 3558 return IPACM_FAILURE; 3559 } 3560 if(rx_prop == NULL) 3561 { 3562 IPACMERR("No tx property.\n"); 3563 return IPACM_FAILURE; 3564 } 3565 3566 if (iptype == IPA_IP_v4) 3567 { 3568 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 3569 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); 3570 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 3571 rt_tbl_idx.ip = iptype; 3572 if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) 3573 { 3574 IPACMERR("Failed to get routing table index from name\n"); 3575 res = IPACM_FAILURE; 3576 goto fail; 3577 } 3578 3579 IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); 3580 3581 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 3582 3583 flt_rule_entry.at_rear = true; 3584 flt_rule_entry.flt_rule_hdl = -1; 3585 flt_rule_entry.status = -1; 3586 3587 flt_rule_entry.rule.retain_hdr = 1; 3588 flt_rule_entry.rule.to_uc = 0; 3589 flt_rule_entry.rule.eq_attrib_type = 1; 3590 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 3591 #ifdef FEATURE_IPA_V3 3592 flt_rule_entry.rule.hashable = true; 3593 #endif 3594 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 3595 3596 IPACMDBG_H("rx property attrib mask:0x%x\n", rx_prop->rx[0].attrib.attrib_mask); 3597 3598 /* Configuring Multicast Filtering Rule */ 3599 memcpy(&flt_rule_entry.rule.attrib, 3600 &rx_prop->rx[0].attrib, 3601 sizeof(flt_rule_entry.rule.attrib)); 3602 /* remove meta data mask since we only install default flt rules once for all modem PDN*/ 3603 flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); 3604 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 3605 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xF0000000; 3606 flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xE0000000; 3607 3608 change_to_network_order(IPA_IP_v4, &flt_rule_entry.rule.attrib); 3609 3610 memset(&flt_eq, 0, sizeof(flt_eq)); 3611 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3612 flt_eq.ip = iptype; 3613 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3614 { 3615 IPACMERR("Failed to get eq_attrib\n"); 3616 res = IPACM_FAILURE; 3617 goto fail; 3618 } 3619 3620 memcpy(&flt_rule_entry.rule.eq_attrib, 3621 &flt_eq.eq_attrib, 3622 sizeof(flt_rule_entry.rule.eq_attrib)); 3623 memcpy(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3624 3625 /* Configuring Broadcast Filtering Rule */ 3626 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; 3627 flt_rule_entry.rule.attrib.u.v4.dst_addr = 0xFFFFFFFF; 3628 3629 change_to_network_order(IPA_IP_v4, &flt_rule_entry.rule.attrib); 3630 3631 memset(&flt_eq, 0, sizeof(flt_eq)); 3632 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3633 flt_eq.ip = iptype; 3634 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3635 { 3636 IPACMERR("Failed to get eq_attrib\n"); 3637 res = IPACM_FAILURE; 3638 goto fail; 3639 } 3640 3641 memcpy(&flt_rule_entry.rule.eq_attrib, 3642 &flt_eq.eq_attrib, 3643 sizeof(flt_rule_entry.rule.eq_attrib)); 3644 memcpy(&(rules[rule_offset + 1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3645 3646 IPACM_Wan::num_v4_flt_rule += IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4; 3647 IPACMDBG_H("Constructed %d default filtering rules for ip type %d\n", IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4, iptype); 3648 } 3649 else /*insert rules for ipv6*/ 3650 { 3651 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 3652 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); 3653 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 3654 rt_tbl_idx.ip = iptype; 3655 if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) 3656 { 3657 IPACMERR("Failed to get routing table index from name\n"); 3658 res = IPACM_FAILURE; 3659 goto fail; 3660 } 3661 3662 IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); 3663 3664 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 3665 3666 flt_rule_entry.at_rear = true; 3667 flt_rule_entry.flt_rule_hdl = -1; 3668 flt_rule_entry.status = -1; 3669 3670 flt_rule_entry.rule.retain_hdr = 1; 3671 flt_rule_entry.rule.to_uc = 0; 3672 flt_rule_entry.rule.eq_attrib_type = 1; 3673 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 3674 #ifdef FEATURE_IPA_V3 3675 flt_rule_entry.rule.hashable = true; 3676 #endif 3677 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 3678 3679 /* Configuring Multicast Filtering Rule */ 3680 memcpy(&flt_rule_entry.rule.attrib, 3681 &rx_prop->rx[0].attrib, 3682 sizeof(flt_rule_entry.rule.attrib)); 3683 /* remove meta data mask since we only install default flt rules once for all modem PDN*/ 3684 flt_rule_entry.rule.attrib.attrib_mask &= ~((uint32_t)IPA_FLT_META_DATA); 3685 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 3686 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFF000000; 3687 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; 3688 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; 3689 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; 3690 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFF000000; 3691 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; 3692 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; 3693 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x00000000; 3694 3695 change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib); 3696 3697 memset(&flt_eq, 0, sizeof(flt_eq)); 3698 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3699 flt_eq.ip = iptype; 3700 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3701 { 3702 IPACMERR("Failed to get eq_attrib\n"); 3703 res = IPACM_FAILURE; 3704 goto fail; 3705 } 3706 3707 memcpy(&flt_rule_entry.rule.eq_attrib, 3708 &flt_eq.eq_attrib, 3709 sizeof(flt_rule_entry.rule.eq_attrib)); 3710 memcpy(&(rules[rule_offset]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3711 3712 /* Configuring fe80::/10 Link-Scoped Unicast Filtering Rule */ 3713 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFC00000; 3714 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; 3715 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; 3716 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; 3717 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFE800000; 3718 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; 3719 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; 3720 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x00000000; 3721 3722 change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib); 3723 3724 memset(&flt_eq, 0, sizeof(flt_eq)); 3725 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3726 flt_eq.ip = iptype; 3727 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3728 { 3729 IPACMERR("Failed to get eq_attrib\n"); 3730 res = IPACM_FAILURE; 3731 goto fail; 3732 } 3733 3734 memcpy(&flt_rule_entry.rule.eq_attrib, 3735 &flt_eq.eq_attrib, 3736 sizeof(flt_rule_entry.rule.eq_attrib)); 3737 3738 memcpy(&(rules[rule_offset + 1]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3739 3740 /* Configuring fec0::/10 Reserved by IETF Filtering Rule */ 3741 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFC00000; 3742 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; 3743 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; 3744 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; 3745 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0xFEC00000; 3746 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; 3747 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; 3748 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x00000000; 3749 3750 change_to_network_order(IPA_IP_v6, &flt_rule_entry.rule.attrib); 3751 3752 memset(&flt_eq, 0, sizeof(flt_eq)); 3753 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 3754 flt_eq.ip = iptype; 3755 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 3756 { 3757 IPACMERR("Failed to get eq_attrib\n"); 3758 res = IPACM_FAILURE; 3759 goto fail; 3760 } 3761 3762 memcpy(&flt_rule_entry.rule.eq_attrib, 3763 &flt_eq.eq_attrib, 3764 sizeof(flt_rule_entry.rule.eq_attrib)); 3765 3766 memcpy(&(rules[rule_offset + 2]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3767 3768 #ifdef FEATURE_IPA_ANDROID 3769 IPACMDBG_H("Add TCP ctrl rules: total num %d\n", IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6); 3770 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 3771 3772 flt_rule_entry.at_rear = true; 3773 flt_rule_entry.flt_rule_hdl = -1; 3774 flt_rule_entry.status = -1; 3775 3776 flt_rule_entry.rule.retain_hdr = 1; 3777 flt_rule_entry.rule.to_uc = 0; 3778 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 3779 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 3780 flt_rule_entry.rule.eq_attrib_type = 1; 3781 3782 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap = 0; 3783 3784 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<1); 3785 flt_rule_entry.rule.eq_attrib.protocol_eq_present = 1; 3786 flt_rule_entry.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP; 3787 3788 #ifdef FEATURE_IPA_V3 3789 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<7); 3790 #else 3791 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<8); 3792 #endif 3793 flt_rule_entry.rule.eq_attrib.num_ihl_offset_meq_32 = 1; 3794 flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12; 3795 3796 /* add TCP FIN rule*/ 3797 flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_FIN_SHIFT); 3798 flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_FIN_SHIFT); 3799 memcpy(&(rules[rule_offset + 3]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3800 3801 /* add TCP SYN rule*/ 3802 flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_SYN_SHIFT); 3803 flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_SYN_SHIFT); 3804 memcpy(&(rules[rule_offset + 4]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3805 3806 /* add TCP RST rule*/ 3807 flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_RST_SHIFT); 3808 flt_rule_entry.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_RST_SHIFT); 3809 memcpy(&(rules[rule_offset + 5]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3810 #endif 3811 3812 IPACM_Wan::num_v6_flt_rule += IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6; 3813 IPACMDBG_H("Constructed %d default filtering rules for ip type %d\n", IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6, iptype); 3814 } 3815 3816 fail: 3817 return res; 3818 } 3819 3820 int IPACM_Wan::del_wan_firewall_rule(ipa_ip_type iptype) 3821 { 3822 if(iptype == IPA_IP_v4) 3823 { 3824 IPACM_Wan::num_v4_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4; 3825 memset(&IPACM_Wan::flt_rule_v4[IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4], 0, 3826 (IPA_MAX_FLT_RULE - IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4) * sizeof(struct ipa_flt_rule_add)); 3827 } 3828 else if(iptype == IPA_IP_v6) 3829 { 3830 IPACM_Wan::num_v6_flt_rule = IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6; 3831 memset(&IPACM_Wan::flt_rule_v6[IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6], 0, 3832 (IPA_MAX_FLT_RULE - IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6) * sizeof(struct ipa_flt_rule_add)); 3833 } 3834 else 3835 { 3836 IPACMERR("IP type is not expected.\n"); 3837 return IPACM_FAILURE; 3838 } 3839 3840 return IPACM_SUCCESS; 3841 } 3842 3843 /*for STA mode: clean firewall filter rules */ 3844 int IPACM_Wan::del_dft_firewall_rules(ipa_ip_type iptype) 3845 { 3846 /* free v4 firewall filter rule */ 3847 if (rx_prop == NULL) 3848 { 3849 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); 3850 return IPACM_SUCCESS; 3851 } 3852 3853 if ((iptype == IPA_IP_v4) && (active_v4 == true)) 3854 { 3855 if (num_firewall_v4 > IPACM_MAX_FIREWALL_ENTRIES) 3856 { 3857 IPACMERR("the number of v4 firewall entries overflow, aborting...\n"); 3858 return IPACM_FAILURE; 3859 } 3860 if (num_firewall_v4 != 0) 3861 { 3862 if (m_filtering.DeleteFilteringHdls(firewall_hdl_v4, 3863 IPA_IP_v4, num_firewall_v4) == false) 3864 { 3865 IPACMERR("Error Deleting Filtering rules, aborting...\n"); 3866 return IPACM_FAILURE; 3867 } 3868 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_firewall_v4); 3869 } 3870 else 3871 { 3872 IPACMDBG_H("No ipv4 firewall rules, no need deleted\n"); 3873 } 3874 3875 if (m_filtering.DeleteFilteringHdls(dft_wan_fl_hdl, 3876 IPA_IP_v4, 1) == false) 3877 { 3878 IPACMERR("Error Deleting Filtering rules, aborting...\n"); 3879 return IPACM_FAILURE; 3880 } 3881 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1); 3882 3883 num_firewall_v4 = 0; 3884 } 3885 3886 /* free v6 firewall filter rule */ 3887 if ((iptype == IPA_IP_v6) && (active_v6 == true)) 3888 { 3889 if (num_firewall_v6 > IPACM_MAX_FIREWALL_ENTRIES) 3890 { 3891 IPACMERR("the number of v6 firewall entries overflow, aborting...\n"); 3892 return IPACM_FAILURE; 3893 } 3894 if (num_firewall_v6 != 0) 3895 { 3896 if (m_filtering.DeleteFilteringHdls(firewall_hdl_v6, 3897 IPA_IP_v6, num_firewall_v6) == false) 3898 { 3899 IPACMERR("Error Deleting Filtering rules, aborting...\n"); 3900 return IPACM_FAILURE; 3901 } 3902 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_firewall_v6); 3903 } 3904 else 3905 { 3906 IPACMDBG_H("No ipv6 firewall rules, no need deleted\n"); 3907 } 3908 3909 if (m_filtering.DeleteFilteringHdls(&dft_wan_fl_hdl[1], 3910 IPA_IP_v6, 1) == false) 3911 { 3912 IPACMERR("Error Deleting Filtering rules, aborting...\n"); 3913 return IPACM_FAILURE; 3914 } 3915 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 3916 if (m_filtering.DeleteFilteringHdls(&dft_wan_fl_hdl[2], 3917 IPA_IP_v6, 1) == false) 3918 { 3919 IPACMERR("Error Deleting Filtering rules, aborting...\n"); 3920 return IPACM_FAILURE; 3921 } 3922 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 3923 3924 if (is_ipv6_frag_firewall_flt_rule_installed && 3925 check_dft_firewall_rules_attr_mask(&firewall_config)) 3926 { 3927 if (m_filtering.DeleteFilteringHdls(&ipv6_frag_firewall_flt_rule_hdl, IPA_IP_v6, 1) == false) 3928 { 3929 IPACMERR("Error deleting IPv6 frag filtering rules.\n"); 3930 return IPACM_FAILURE; 3931 } 3932 is_ipv6_frag_firewall_flt_rule_installed = false; 3933 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 3934 } 3935 num_firewall_v6 = 0; 3936 } 3937 3938 return IPACM_SUCCESS; 3939 } 3940 3941 /* for STA mode: wan default route/filter rule delete */ 3942 int IPACM_Wan::handle_route_del_evt(ipa_ip_type iptype) 3943 { 3944 uint32_t tx_index; 3945 ipacm_cmd_q_data evt_data; 3946 3947 IPACMDBG_H("got handle_route_del_evt for STA-mode with ip-family:%d \n", iptype); 3948 3949 if(tx_prop == NULL) 3950 { 3951 IPACMDBG_H("No tx properties, ignore delete default route setting\n"); 3952 return IPACM_SUCCESS; 3953 } 3954 3955 is_default_gateway = false; 3956 IPACMDBG_H("Default route is deleted to iface %s.\n", dev_name); 3957 3958 if (((iptype == IPA_IP_v4) && (active_v4 == true)) || 3959 ((iptype == IPA_IP_v6) && (active_v6 == true))) 3960 { 3961 3962 /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */ 3963 IPACMDBG_H("dev %s add producer dependency\n", dev_name); 3964 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]); 3965 IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); 3966 3967 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) 3968 { 3969 if(iptype != tx_prop->tx[tx_index].ip) 3970 { 3971 IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d, no RT-rule deleted\n", 3972 tx_index, tx_prop->tx[tx_index].ip,iptype); 3973 continue; 3974 } 3975 3976 if (iptype == IPA_IP_v4) 3977 { 3978 IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n", tx_index, tx_prop->tx[tx_index].ip,iptype); 3979 3980 if (m_routing.DeleteRoutingHdl(wan_route_rule_v4_hdl[tx_index], IPA_IP_v4) == false) 3981 { 3982 IPACMDBG_H("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v4, wan_route_rule_v4_hdl[tx_index], tx_index); 3983 return IPACM_FAILURE; 3984 } 3985 } 3986 else 3987 { 3988 IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n", tx_index, tx_prop->tx[tx_index].ip,iptype); 3989 3990 if (m_routing.DeleteRoutingHdl(wan_route_rule_v6_hdl[tx_index], IPA_IP_v6) == false) 3991 { 3992 IPACMDBG_H("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v6, wan_route_rule_v6_hdl[tx_index], tx_index); 3993 return IPACM_FAILURE; 3994 } 3995 } 3996 } 3997 3998 /* Delete the default wan route*/ 3999 if (iptype == IPA_IP_v6) 4000 { 4001 IPACMDBG_H("ip-type %d: default v6 wan RT-rule deleted\n",iptype); 4002 if (m_routing.DeleteRoutingHdl(wan_route_rule_v6_hdl_a5[0], IPA_IP_v6) == false) 4003 { 4004 IPACMDBG_H("IP-family:%d, Routing rule(hdl:0x%x) deletion failed!\n",IPA_IP_v6,wan_route_rule_v6_hdl_a5[0]); 4005 return IPACM_FAILURE; 4006 } 4007 } 4008 ipacm_event_iface_up *wandown_data; 4009 wandown_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up)); 4010 if (wandown_data == NULL) 4011 { 4012 IPACMERR("Unable to allocate memory\n"); 4013 return IPACM_FAILURE; 4014 } 4015 memset(wandown_data, 0, sizeof(ipacm_event_iface_up)); 4016 4017 if (iptype == IPA_IP_v4) 4018 { 4019 wandown_data->ipv4_addr = wan_v4_addr; 4020 if (m_is_sta_mode!=Q6_WAN) 4021 { 4022 wandown_data->is_sta = true; 4023 } 4024 else 4025 { 4026 wandown_data->is_sta = false; 4027 } 4028 evt_data.event = IPA_HANDLE_WAN_DOWN; 4029 evt_data.evt_data = (void *)wandown_data; 4030 /* Insert IPA_HANDLE_WAN_DOWN to command queue */ 4031 IPACMDBG_H("posting IPA_HANDLE_WAN_DOWN for IPv4 (%d.%d.%d.%d) \n", 4032 (unsigned char)(wandown_data->ipv4_addr), 4033 (unsigned char)(wandown_data->ipv4_addr >> 8), 4034 (unsigned char)(wandown_data->ipv4_addr >> 16), 4035 (unsigned char)(wandown_data->ipv4_addr >> 24)); 4036 4037 IPACM_EvtDispatcher::PostEvt(&evt_data); 4038 IPACMDBG_H("setup wan_up/active_v4= false \n"); 4039 IPACM_Wan::wan_up = false; 4040 active_v4 = false; 4041 if(IPACM_Wan::wan_up_v6) 4042 { 4043 IPACMDBG_H("modem v6-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name); 4044 } 4045 else 4046 { 4047 memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); 4048 } 4049 } 4050 else 4051 { 4052 if (m_is_sta_mode!=Q6_WAN) 4053 { 4054 wandown_data->is_sta = true; 4055 } 4056 else 4057 { 4058 wandown_data->is_sta = false; 4059 } 4060 memcpy(wandown_data->ipv6_prefix, ipv6_prefix, sizeof(wandown_data->ipv6_prefix)); 4061 evt_data.event = IPA_HANDLE_WAN_DOWN_V6; 4062 evt_data.evt_data = (void *)wandown_data; 4063 /* Insert IPA_HANDLE_WAN_DOWN to command queue */ 4064 IPACMDBG_H("posting IPA_HANDLE_WAN_DOWN for IPv6 with prefix 0x%08x%08x\n", ipv6_prefix[0], ipv6_prefix[1]); 4065 IPACM_EvtDispatcher::PostEvt(&evt_data); 4066 IPACMDBG_H("setup wan_up_v6/active_v6= false \n"); 4067 IPACM_Wan::wan_up_v6 = false; 4068 active_v6 = false; 4069 if(IPACM_Wan::wan_up) 4070 { 4071 IPACMDBG_H("modem v4-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name); 4072 } 4073 else 4074 { 4075 memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); 4076 } 4077 } 4078 } 4079 else 4080 { 4081 IPACMDBG_H(" The default WAN routing rules are deleted already \n"); 4082 } 4083 4084 return IPACM_SUCCESS; 4085 } 4086 4087 int IPACM_Wan::handle_route_del_evt_ex(ipa_ip_type iptype) 4088 { 4089 ipacm_cmd_q_data evt_data; 4090 4091 IPACMDBG_H("got handle_route_del_evt_ex with ip-family:%d \n", iptype); 4092 4093 if(tx_prop == NULL) 4094 { 4095 IPACMDBG_H("No tx properties, ignore delete default route setting\n"); 4096 return IPACM_SUCCESS; 4097 } 4098 4099 is_default_gateway = false; 4100 IPACMDBG_H("Default route is deleted to iface %s.\n", dev_name); 4101 4102 if (((iptype == IPA_IP_v4) && (active_v4 == true)) || 4103 ((iptype == IPA_IP_v6) && (active_v6 == true))) 4104 { 4105 4106 /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */ 4107 IPACMDBG_H("dev %s add producer dependency\n", dev_name); 4108 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]); 4109 IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); 4110 4111 /* Delete the default route*/ 4112 if (iptype == IPA_IP_v6) 4113 { 4114 IPACMDBG_H("ip-type %d: default v6 wan RT-rule deleted\n",iptype); 4115 if (m_routing.DeleteRoutingHdl(wan_route_rule_v6_hdl_a5[0], IPA_IP_v6) == false) 4116 { 4117 IPACMDBG_H("IP-family:%d, Routing rule(hdl:0x%x) deletion failed!\n",IPA_IP_v6,wan_route_rule_v6_hdl_a5[0]); 4118 return IPACM_FAILURE; 4119 } 4120 } 4121 4122 ipacm_event_iface_up *wandown_data; 4123 wandown_data = (ipacm_event_iface_up *)malloc(sizeof(ipacm_event_iface_up)); 4124 if (wandown_data == NULL) 4125 { 4126 IPACMERR("Unable to allocate memory\n"); 4127 return IPACM_FAILURE; 4128 } 4129 memset(wandown_data, 0, sizeof(ipacm_event_iface_up)); 4130 4131 if (iptype == IPA_IP_v4) 4132 { 4133 wandown_data->ipv4_addr = wan_v4_addr; 4134 if (m_is_sta_mode!=Q6_WAN) 4135 { 4136 wandown_data->is_sta = true; 4137 } 4138 else 4139 { 4140 wandown_data->is_sta = false; 4141 } 4142 evt_data.event = IPA_HANDLE_WAN_DOWN; 4143 evt_data.evt_data = (void *)wandown_data; 4144 /* Insert IPA_HANDLE_WAN_DOWN to command queue */ 4145 IPACMDBG_H("posting IPA_HANDLE_WAN_DOWN for IPv4 with address: 0x%x\n", wan_v4_addr); 4146 IPACM_EvtDispatcher::PostEvt(&evt_data); 4147 4148 IPACMDBG_H("setup wan_up/active_v4= false \n"); 4149 IPACM_Wan::wan_up = false; 4150 active_v4 = false; 4151 if(IPACM_Wan::wan_up_v6) 4152 { 4153 IPACMDBG_H("modem v6-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name); 4154 } 4155 else 4156 { 4157 memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); 4158 } 4159 } 4160 else 4161 { 4162 if (m_is_sta_mode!=Q6_WAN) 4163 { 4164 wandown_data->is_sta = true; 4165 } 4166 else 4167 { 4168 wandown_data->is_sta = false; 4169 } 4170 memcpy(wandown_data->ipv6_prefix, ipv6_prefix, sizeof(wandown_data->ipv6_prefix)); 4171 evt_data.event = IPA_HANDLE_WAN_DOWN_V6; 4172 evt_data.evt_data = (void *)wandown_data; 4173 IPACMDBG_H("posting IPA_HANDLE_WAN_DOWN_V6 for IPv6 with prefix 0x%08x%08x\n", ipv6_prefix[0], ipv6_prefix[1]); 4174 IPACM_EvtDispatcher::PostEvt(&evt_data); 4175 4176 IPACMDBG_H("setup wan_up_v6/active_v6= false \n"); 4177 IPACM_Wan::wan_up_v6 = false; 4178 active_v6 = false; 4179 if(IPACM_Wan::wan_up) 4180 { 4181 IPACMDBG_H("modem v4-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name); 4182 } 4183 else 4184 { 4185 memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); 4186 } 4187 } 4188 } 4189 else 4190 { 4191 IPACMDBG_H(" The default WAN routing rules are deleted already \n"); 4192 } 4193 4194 return IPACM_SUCCESS; 4195 } 4196 4197 /* configure the initial embms filter rules */ 4198 int IPACM_Wan::config_dft_embms_rules(ipa_ioc_add_flt_rule *pFilteringTable_v4, ipa_ioc_add_flt_rule *pFilteringTable_v6) 4199 { 4200 struct ipa_flt_rule_add flt_rule_entry; 4201 struct ipa_ioc_get_rt_tbl_indx rt_tbl_idx; 4202 struct ipa_ioc_generate_flt_eq flt_eq; 4203 4204 if (rx_prop == NULL) 4205 { 4206 IPACMDBG("No rx properties registered for iface %s\n", dev_name); 4207 return IPACM_SUCCESS; 4208 } 4209 4210 if(pFilteringTable_v4 == NULL || pFilteringTable_v6 == NULL) 4211 { 4212 IPACMERR("Either v4 or v6 filtering table is empty.\n"); 4213 return IPACM_FAILURE; 4214 } 4215 4216 /* set up ipv4 odu rule*/ 4217 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 4218 4219 /* get eMBMS ODU tbl index*/ 4220 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 4221 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name, IPA_RESOURCE_NAME_MAX); 4222 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 4223 rt_tbl_idx.ip = IPA_IP_v4; 4224 if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) 4225 { 4226 IPACMERR("Failed to get routing table index from name\n"); 4227 return IPACM_FAILURE; 4228 } 4229 IPACMDBG_H("Odu routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); 4230 4231 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 4232 flt_rule_entry.flt_rule_hdl = -1; 4233 flt_rule_entry.status = -1; 4234 flt_rule_entry.at_rear = false; 4235 4236 flt_rule_entry.rule.retain_hdr = 0; 4237 flt_rule_entry.rule.to_uc = 0; 4238 flt_rule_entry.rule.eq_attrib_type = 1; 4239 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 4240 #ifdef FEATURE_IPA_V3 4241 flt_rule_entry.rule.hashable = true; 4242 #endif 4243 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 4244 4245 memcpy(&flt_rule_entry.rule.attrib, 4246 &rx_prop->rx[0].attrib, 4247 sizeof(struct ipa_rule_attrib)); 4248 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 4249 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x00000000; 4250 flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x00000000; 4251 4252 memset(&flt_eq, 0, sizeof(flt_eq)); 4253 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 4254 flt_eq.ip = IPA_IP_v4; 4255 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 4256 { 4257 IPACMERR("Failed to get eq_attrib\n"); 4258 return IPACM_FAILURE; 4259 } 4260 memcpy(&flt_rule_entry.rule.eq_attrib, 4261 &flt_eq.eq_attrib, 4262 sizeof(flt_rule_entry.rule.eq_attrib)); 4263 4264 memcpy(&(pFilteringTable_v4->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 4265 4266 /* construc v6 rule */ 4267 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 4268 /* get eMBMS ODU tbl*/ 4269 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 4270 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name, IPA_RESOURCE_NAME_MAX); 4271 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 4272 rt_tbl_idx.ip = IPA_IP_v6; 4273 if(0 != ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx)) 4274 { 4275 IPACMERR("Failed to get routing table index from name\n"); 4276 return IPACM_FAILURE; 4277 } 4278 IPACMDBG_H("Odu routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); 4279 4280 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 4281 flt_rule_entry.flt_rule_hdl = -1; 4282 flt_rule_entry.status = -1; 4283 flt_rule_entry.at_rear = false; 4284 4285 flt_rule_entry.rule.retain_hdr = 0; 4286 flt_rule_entry.rule.to_uc = 0; 4287 flt_rule_entry.rule.eq_attrib_type = 1; 4288 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 4289 #ifdef FEATURE_IPA_V3 4290 flt_rule_entry.rule.hashable = true; 4291 #endif 4292 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 4293 4294 memcpy(&flt_rule_entry.rule.attrib, 4295 &rx_prop->rx[0].attrib, 4296 sizeof(struct ipa_rule_attrib)); 4297 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 4298 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000; 4299 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; 4300 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; 4301 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; 4302 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000; 4303 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; 4304 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; 4305 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; 4306 4307 memset(&flt_eq, 0, sizeof(flt_eq)); 4308 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 4309 flt_eq.ip = IPA_IP_v6; 4310 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 4311 { 4312 IPACMERR("Failed to get eq_attrib\n"); 4313 return IPACM_FAILURE; 4314 } 4315 memcpy(&flt_rule_entry.rule.eq_attrib, 4316 &flt_eq.eq_attrib, 4317 sizeof(flt_rule_entry.rule.eq_attrib)); 4318 4319 memcpy(&(pFilteringTable_v6->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 4320 4321 return IPACM_SUCCESS; 4322 } 4323 4324 4325 /*for STA mode: handle wan-iface down event */ 4326 int IPACM_Wan::handle_down_evt() 4327 { 4328 int res = IPACM_SUCCESS; 4329 uint32_t i; 4330 4331 IPACMDBG_H(" wan handle_down_evt \n"); 4332 4333 /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */ 4334 IPACMDBG_H("dev %s add producer dependency\n", dev_name); 4335 if (tx_prop != NULL) 4336 { 4337 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]); 4338 IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); 4339 } 4340 4341 /* no iface address up, directly close iface*/ 4342 if (ip_type == IPACM_IP_NULL) 4343 { 4344 goto fail; 4345 } 4346 4347 /* make sure default routing rules and firewall rules are deleted*/ 4348 if (active_v4) 4349 { 4350 if (rx_prop != NULL) 4351 { 4352 del_dft_firewall_rules(IPA_IP_v4); 4353 } 4354 handle_route_del_evt(IPA_IP_v4); 4355 IPACMDBG_H("Delete default v4 routing rules\n"); 4356 } 4357 4358 if (active_v6) 4359 { 4360 if (rx_prop != NULL) 4361 { 4362 del_dft_firewall_rules(IPA_IP_v6); 4363 } 4364 handle_route_del_evt(IPA_IP_v6); 4365 IPACMDBG_H("Delete default v6 routing rules\n"); 4366 } 4367 4368 /* Delete default v4 RT rule */ 4369 if (ip_type != IPA_IP_v6) 4370 { 4371 IPACMDBG_H("Delete default v4 routing rules\n"); 4372 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false) 4373 { 4374 IPACMERR("Routing rule deletion failed!\n"); 4375 res = IPACM_FAILURE; 4376 goto fail; 4377 } 4378 } 4379 4380 /* delete default v6 RT rule */ 4381 if (ip_type != IPA_IP_v4) 4382 { 4383 IPACMDBG_H("Delete default v6 routing rules\n"); 4384 /* May have multiple ipv6 iface-routing rules*/ 4385 for (i = 0; i < 2*num_dft_rt_v6; i++) 4386 { 4387 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false) 4388 { 4389 IPACMERR("Routing rule deletion failed!\n"); 4390 res = IPACM_FAILURE; 4391 goto fail; 4392 } 4393 } 4394 4395 IPACMDBG_H("finished delete default v6 RT rules\n "); 4396 } 4397 4398 4399 /* clean wan-client header, routing rules */ 4400 IPACMDBG_H("left %d wan clients need to be deleted \n ", num_wan_client); 4401 for (i = 0; i < num_wan_client; i++) 4402 { 4403 /* Del NAT rules before ipv4 RT rules are delete */ 4404 if(get_client_memptr(wan_client, i)->ipv4_set == true) 4405 { 4406 IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(wan_client, i)->v4_addr); 4407 CtList->HandleSTAClientDelEvt(get_client_memptr(wan_client, i)->v4_addr); 4408 } 4409 4410 if (delete_wan_rtrules(i, IPA_IP_v4)) 4411 { 4412 IPACMERR("unbale to delete wan-client v4 route rules for index %d\n", i); 4413 res = IPACM_FAILURE; 4414 goto fail; 4415 } 4416 4417 if (delete_wan_rtrules(i, IPA_IP_v6)) 4418 { 4419 IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i); 4420 res = IPACM_FAILURE; 4421 goto fail; 4422 } 4423 4424 IPACMDBG_H("Delete %d client header\n", num_wan_client); 4425 4426 4427 if(get_client_memptr(wan_client, i)->ipv4_header_set == true) 4428 { 4429 if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, i)->hdr_hdl_v4) 4430 == false) 4431 { 4432 res = IPACM_FAILURE; 4433 goto fail; 4434 } 4435 } 4436 4437 if(get_client_memptr(wan_client, i)->ipv6_header_set == true) 4438 { 4439 if (m_header.DeleteHeaderHdl(get_client_memptr(wan_client, i)->hdr_hdl_v6) 4440 == false) 4441 { 4442 res = IPACM_FAILURE; 4443 goto fail; 4444 } 4445 } 4446 } /* end of for loop */ 4447 4448 /* free the edm clients cache */ 4449 IPACMDBG_H("Free wan clients cache\n"); 4450 4451 /* check software routing fl rule hdl */ 4452 if (softwarerouting_act == true) 4453 { 4454 handle_software_routing_disable(); 4455 } 4456 4457 /* free filter rule handlers */ 4458 if (ip_type != IPA_IP_v6 && rx_prop != NULL) 4459 { 4460 if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, 4461 IPA_IP_v4, 4462 IPV4_DEFAULT_FILTERTING_RULES) == false) 4463 { 4464 IPACMERR("Error Delete Filtering rules, aborting...\n"); 4465 res = IPACM_FAILURE; 4466 goto fail; 4467 } 4468 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES); 4469 4470 IPACMDBG_H("finished delete default v4 filtering rules\n "); 4471 } 4472 4473 4474 if (ip_type != IPA_IP_v4 && rx_prop != NULL) 4475 { 4476 if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, 4477 IPA_IP_v6, 4478 IPV6_DEFAULT_FILTERTING_RULES) == false) 4479 { 4480 IPACMERR("ErrorDeleting Filtering rule, aborting...\n"); 4481 res = IPACM_FAILURE; 4482 goto fail; 4483 } 4484 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES); 4485 4486 if(num_ipv6_dest_flt_rule > 0 && num_ipv6_dest_flt_rule <= MAX_DEFAULT_v6_ROUTE_RULES) 4487 { 4488 if(m_filtering.DeleteFilteringHdls(ipv6_dest_flt_rule_hdl, IPA_IP_v6, num_ipv6_dest_flt_rule) == false) 4489 { 4490 IPACMERR("Failed to delete ipv6 dest flt rules.\n"); 4491 res = IPACM_FAILURE; 4492 goto fail; 4493 } 4494 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_ipv6_dest_flt_rule); 4495 } 4496 IPACMDBG_H("finished delete default v6 filtering rules\n "); 4497 } 4498 if(hdr_proc_hdl_dummy_v6) 4499 { 4500 if(m_header.DeleteHeaderProcCtx(hdr_proc_hdl_dummy_v6) == false) 4501 { 4502 IPACMERR("Failed to delete hdr_proc_hdl_dummy_v6\n"); 4503 res = IPACM_FAILURE; 4504 goto fail; 4505 } 4506 } 4507 if(hdr_hdl_dummy_v6) 4508 { 4509 if (m_header.DeleteHeaderHdl(hdr_hdl_dummy_v6) == false) 4510 { 4511 IPACMERR("Failed to delete hdr_hdl_dummy_v6\n"); 4512 res = IPACM_FAILURE; 4513 goto fail; 4514 } 4515 } 4516 fail: 4517 if (tx_prop != NULL) 4518 { 4519 free(tx_prop); 4520 } 4521 if (rx_prop != NULL) 4522 { 4523 free(rx_prop); 4524 } 4525 if (iface_query != NULL) 4526 { 4527 free(iface_query); 4528 } 4529 if (wan_route_rule_v4_hdl != NULL) 4530 { 4531 free(wan_route_rule_v4_hdl); 4532 } 4533 if (wan_route_rule_v6_hdl != NULL) 4534 { 4535 free(wan_route_rule_v6_hdl); 4536 } 4537 if (wan_route_rule_v6_hdl_a5 != NULL) 4538 { 4539 free(wan_route_rule_v6_hdl_a5); 4540 } 4541 if (wan_client != NULL) 4542 { 4543 free(wan_client); 4544 } 4545 close(m_fd_ipa); 4546 return res; 4547 } 4548 4549 int IPACM_Wan::handle_down_evt_ex() 4550 { 4551 int res = IPACM_SUCCESS; 4552 uint32_t i, tether_total; 4553 int ipa_if_num_tether_tmp[IPA_MAX_IFACE_ENTRIES]; 4554 4555 IPACMDBG_H(" wan handle_down_evt \n"); 4556 4557 /* free ODU filter rule handlers */ 4558 if(IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat == EMBMS_IF) 4559 { 4560 embms_is_on = false; 4561 /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete IPV4/V6 RT-rule */ 4562 IPACMDBG_H("dev %s add producer dependency\n", dev_name); 4563 if (tx_prop != NULL) 4564 { 4565 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]); 4566 IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); 4567 } 4568 4569 if (rx_prop != NULL) 4570 { 4571 install_wan_filtering_rule(false); 4572 IPACMDBG("finished delete embms filtering rule\n "); 4573 } 4574 goto fail; 4575 } 4576 4577 /* no iface address up, directly close iface*/ 4578 if (ip_type == IPACM_IP_NULL) 4579 { 4580 goto fail; 4581 } 4582 4583 if(ip_type == IPA_IP_v4) 4584 { 4585 num_ipv4_modem_pdn--; 4586 IPACMDBG_H("Now the number of ipv4 modem pdn is %d.\n", num_ipv4_modem_pdn); 4587 /* only when default gw goes down we post WAN_DOWN event*/ 4588 if(is_default_gateway == true) 4589 { 4590 IPACM_Wan::wan_up = false; 4591 del_wan_firewall_rule(IPA_IP_v4); 4592 install_wan_filtering_rule(false); 4593 handle_route_del_evt_ex(IPA_IP_v4); 4594 #ifdef FEATURE_IPA_ANDROID 4595 /* posting wan_down_tether for all lan clients */ 4596 for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++) 4597 { 4598 ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v4[i]; 4599 } 4600 tether_total = IPACM_Wan::ipa_if_num_tether_v4_total; 4601 for (i=0; i < tether_total; i++) 4602 { 4603 post_wan_down_tether_evt(IPA_IP_v4, ipa_if_num_tether_tmp[i]); 4604 IPACMDBG_H("post_wan_down_tether_v4 iface(%d: %s)\n", 4605 i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name); 4606 } 4607 #endif 4608 if(IPACM_Wan::wan_up_v6) 4609 { 4610 IPACMDBG_H("modem v6-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name); 4611 } 4612 else 4613 { 4614 memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); 4615 } 4616 } 4617 4618 /* only when the last ipv4 modem interface goes down, delete ipv4 default flt rules*/ 4619 if(num_ipv4_modem_pdn == 0) 4620 { 4621 IPACMDBG_H("Now the number of modem ipv4 interface is 0, delete default flt rules.\n"); 4622 IPACM_Wan::num_v4_flt_rule = 0; 4623 memset(IPACM_Wan::flt_rule_v4, 0, IPA_MAX_FLT_RULE * sizeof(struct ipa_flt_rule_add)); 4624 install_wan_filtering_rule(false); 4625 } 4626 4627 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false) 4628 { 4629 IPACMERR("Routing rule deletion failed!\n"); 4630 res = IPACM_FAILURE; 4631 goto fail; 4632 } 4633 } 4634 else if(ip_type == IPA_IP_v6) 4635 { 4636 if (num_dft_rt_v6 > 1) 4637 num_ipv6_modem_pdn--; 4638 IPACMDBG_H("Now the number of ipv6 modem pdn is %d.\n", num_ipv6_modem_pdn); 4639 /* only when default gw goes down we post WAN_DOWN event*/ 4640 if(is_default_gateway == true) 4641 { 4642 IPACM_Wan::wan_up_v6 = false; 4643 del_wan_firewall_rule(IPA_IP_v6); 4644 install_wan_filtering_rule(false); 4645 handle_route_del_evt_ex(IPA_IP_v6); 4646 #ifdef FEATURE_IPA_ANDROID 4647 /* posting wan_down_tether for all lan clients */ 4648 for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++) 4649 { 4650 ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v6[i]; 4651 } 4652 tether_total = IPACM_Wan::ipa_if_num_tether_v6_total; 4653 for (i=0; i < tether_total; i++) 4654 { 4655 post_wan_down_tether_evt(IPA_IP_v6, ipa_if_num_tether_tmp[i]); 4656 IPACMDBG_H("post_wan_down_tether_v6 iface(%d: %s)\n", 4657 i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name); 4658 } 4659 #endif 4660 if(IPACM_Wan::wan_up) 4661 { 4662 IPACMDBG_H("modem v4-call still up(%s), not reset\n", IPACM_Wan::wan_up_dev_name); 4663 } 4664 else 4665 { 4666 memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); 4667 } 4668 } 4669 4670 /* only when the last ipv6 modem interface goes down, delete ipv6 default flt rules*/ 4671 if(num_ipv6_modem_pdn == 0) 4672 { 4673 IPACMDBG_H("Now the number of modem ipv6 interface is 0, delete default flt rules.\n"); 4674 IPACM_Wan::num_v6_flt_rule = 0; 4675 memset(IPACM_Wan::flt_rule_v6, 0, IPA_MAX_FLT_RULE * sizeof(struct ipa_flt_rule_add)); 4676 install_wan_filtering_rule(false); 4677 } 4678 4679 for (i = 0; i < 2*num_dft_rt_v6; i++) 4680 { 4681 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false) 4682 { 4683 IPACMERR("Routing rule deletion failed!\n"); 4684 res = IPACM_FAILURE; 4685 goto fail; 4686 } 4687 } 4688 } 4689 else 4690 { 4691 num_ipv4_modem_pdn--; 4692 IPACMDBG_H("Now the number of ipv4 modem pdn is %d.\n", num_ipv4_modem_pdn); 4693 if (num_dft_rt_v6 > 1) 4694 num_ipv6_modem_pdn--; 4695 IPACMDBG_H("Now the number of ipv6 modem pdn is %d.\n", num_ipv6_modem_pdn); 4696 /* only when default gw goes down we post WAN_DOWN event*/ 4697 if(is_default_gateway == true) 4698 { 4699 IPACM_Wan::wan_up = false; 4700 del_wan_firewall_rule(IPA_IP_v4); 4701 handle_route_del_evt_ex(IPA_IP_v4); 4702 #ifdef FEATURE_IPA_ANDROID 4703 /* posting wan_down_tether for all lan clients */ 4704 for (i=0; i < IPACM_Wan::ipa_if_num_tether_v4_total; i++) 4705 { 4706 ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v4[i]; 4707 } 4708 tether_total = IPACM_Wan::ipa_if_num_tether_v4_total; 4709 for (i=0; i < tether_total; i++) 4710 { 4711 post_wan_down_tether_evt(IPA_IP_v4, ipa_if_num_tether_tmp[i]); 4712 IPACMDBG_H("post_wan_down_tether_v4 iface(%d: %s)\n", 4713 i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name); 4714 } 4715 #endif 4716 IPACM_Wan::wan_up_v6 = false; 4717 del_wan_firewall_rule(IPA_IP_v6); 4718 handle_route_del_evt_ex(IPA_IP_v6); 4719 #ifdef FEATURE_IPA_ANDROID 4720 /* posting wan_down_tether for all lan clients */ 4721 for (i=0; i < IPACM_Wan::ipa_if_num_tether_v6_total; i++) 4722 { 4723 ipa_if_num_tether_tmp[i] = IPACM_Wan::ipa_if_num_tether_v6[i]; 4724 } 4725 tether_total = IPACM_Wan::ipa_if_num_tether_v6_total; 4726 for (i=0; i < tether_total; i++) 4727 { 4728 post_wan_down_tether_evt(IPA_IP_v6, ipa_if_num_tether_tmp[i]); 4729 IPACMDBG_H("post_wan_down_tether_v6 iface(%d: %s)\n", 4730 i, IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether_tmp[i]].iface_name); 4731 } 4732 #endif 4733 memset(IPACM_Wan::wan_up_dev_name, 0, sizeof(IPACM_Wan::wan_up_dev_name)); 4734 4735 install_wan_filtering_rule(false); 4736 } 4737 4738 /* only when the last ipv4 modem interface goes down, delete ipv4 default flt rules*/ 4739 if(num_ipv4_modem_pdn == 0) 4740 { 4741 IPACMDBG_H("Now the number of modem ipv4 interface is 0, delete default flt rules.\n"); 4742 IPACM_Wan::num_v4_flt_rule = 0; 4743 memset(IPACM_Wan::flt_rule_v4, 0, IPA_MAX_FLT_RULE * sizeof(struct ipa_flt_rule_add)); 4744 install_wan_filtering_rule(false); 4745 } 4746 /* only when the last ipv6 modem interface goes down, delete ipv6 default flt rules*/ 4747 if(num_ipv6_modem_pdn == 0) 4748 { 4749 IPACMDBG_H("Now the number of modem ipv6 interface is 0, delete default flt rules.\n"); 4750 IPACM_Wan::num_v6_flt_rule = 0; 4751 memset(IPACM_Wan::flt_rule_v6, 0, IPA_MAX_FLT_RULE * sizeof(struct ipa_flt_rule_add)); 4752 install_wan_filtering_rule(false); 4753 } 4754 4755 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) == false) 4756 { 4757 IPACMERR("Routing rule deletion failed!\n"); 4758 res = IPACM_FAILURE; 4759 goto fail; 4760 } 4761 4762 for (i = 0; i < 2*num_dft_rt_v6; i++) 4763 { 4764 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES+i], IPA_IP_v6) == false) 4765 { 4766 IPACMERR("Routing rule deletion failed!\n"); 4767 res = IPACM_FAILURE; 4768 goto fail; 4769 } 4770 } 4771 } 4772 4773 /* check software routing fl rule hdl */ 4774 if (softwarerouting_act == true) 4775 { 4776 handle_software_routing_disable(); 4777 } 4778 4779 fail: 4780 if (tx_prop != NULL) 4781 { 4782 free(tx_prop); 4783 } 4784 if (rx_prop != NULL) 4785 { 4786 free(rx_prop); 4787 } 4788 if (ext_prop != NULL) 4789 { 4790 free(ext_prop); 4791 } 4792 if (iface_query != NULL) 4793 { 4794 free(iface_query); 4795 } 4796 if (wan_route_rule_v4_hdl != NULL) 4797 { 4798 free(wan_route_rule_v4_hdl); 4799 } 4800 if (wan_route_rule_v6_hdl != NULL) 4801 { 4802 free(wan_route_rule_v6_hdl); 4803 } 4804 if (wan_route_rule_v6_hdl_a5 != NULL) 4805 { 4806 free(wan_route_rule_v6_hdl_a5); 4807 } 4808 if (wan_client != NULL) 4809 { 4810 free(wan_client); 4811 } 4812 close(m_fd_ipa); 4813 return res; 4814 } 4815 4816 int IPACM_Wan::install_wan_filtering_rule(bool is_sw_routing) 4817 { 4818 int len, res = IPACM_SUCCESS; 4819 uint8_t mux_id; 4820 ipa_ioc_add_flt_rule *pFilteringTable_v4 = NULL; 4821 ipa_ioc_add_flt_rule *pFilteringTable_v6 = NULL; 4822 4823 mux_id = IPACM_Iface::ipacmcfg->GetQmapId(); 4824 if(rx_prop == NULL) 4825 { 4826 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); 4827 return IPACM_SUCCESS; 4828 } 4829 if (is_sw_routing == true || 4830 IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true) 4831 { 4832 /* contruct SW-RT rules to Q6*/ 4833 struct ipa_flt_rule_add flt_rule_entry; 4834 struct ipa_ioc_get_rt_tbl_indx rt_tbl_idx; 4835 ipa_ioc_generate_flt_eq flt_eq; 4836 4837 IPACMDBG("\n"); 4838 if (softwarerouting_act == true) 4839 { 4840 IPACMDBG("already setup software_routing rule for (%s)iface ip-family %d\n", 4841 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ip_type); 4842 return IPACM_SUCCESS; 4843 } 4844 4845 len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); 4846 pFilteringTable_v4 = (struct ipa_ioc_add_flt_rule*)malloc(len); 4847 if (pFilteringTable_v4 == NULL) 4848 { 4849 IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); 4850 return IPACM_FAILURE; 4851 } 4852 memset(pFilteringTable_v4, 0, len); 4853 IPACMDBG_H("Total number of WAN DL filtering rule for IPv4 is 1\n"); 4854 4855 pFilteringTable_v4->commit = 1; 4856 pFilteringTable_v4->ep = rx_prop->rx[0].src_pipe; 4857 pFilteringTable_v4->global = false; 4858 pFilteringTable_v4->ip = IPA_IP_v4; 4859 pFilteringTable_v4->num_rules = (uint8_t)1; 4860 4861 /* Configuring Software-Routing Filtering Rule */ 4862 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 4863 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 4864 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); 4865 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 4866 rt_tbl_idx.ip = IPA_IP_v4; 4867 if(ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx) < 0) 4868 { 4869 IPACMERR("Failed to get routing table index from name\n"); 4870 res = IPACM_FAILURE; 4871 goto fail; 4872 } 4873 IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); 4874 4875 flt_rule_entry.at_rear = false; 4876 flt_rule_entry.flt_rule_hdl = -1; 4877 flt_rule_entry.status = -1; 4878 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 4879 #ifdef FEATURE_IPA_V3 4880 flt_rule_entry.rule.hashable = true; 4881 #endif 4882 4883 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 4884 4885 memcpy(&flt_rule_entry.rule.attrib, 4886 &rx_prop->rx[0].attrib, 4887 sizeof(flt_rule_entry.rule.attrib)); 4888 flt_rule_entry.rule.retain_hdr = 0; 4889 flt_rule_entry.rule.to_uc = 0; 4890 flt_rule_entry.rule.eq_attrib_type = 1; 4891 4892 memset(&flt_eq, 0, sizeof(flt_eq)); 4893 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 4894 flt_eq.ip = IPA_IP_v4; 4895 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 4896 { 4897 IPACMERR("Failed to get eq_attrib\n"); 4898 res = IPACM_FAILURE; 4899 goto fail; 4900 } 4901 memcpy(&flt_rule_entry.rule.eq_attrib, 4902 &flt_eq.eq_attrib, 4903 sizeof(flt_rule_entry.rule.eq_attrib)); 4904 memcpy(&(pFilteringTable_v4->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 4905 4906 len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); 4907 pFilteringTable_v6 = (struct ipa_ioc_add_flt_rule*)malloc(len); 4908 if (pFilteringTable_v6 == NULL) 4909 { 4910 IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); 4911 free(pFilteringTable_v4); 4912 return IPACM_FAILURE; 4913 } 4914 memset(pFilteringTable_v6, 0, len); 4915 IPACMDBG_H("Total number of WAN DL filtering rule for IPv6 is 1\n"); 4916 4917 pFilteringTable_v6->commit = 1; 4918 pFilteringTable_v6->ep = rx_prop->rx[0].src_pipe; 4919 pFilteringTable_v6->global = false; 4920 pFilteringTable_v6->ip = IPA_IP_v6; 4921 pFilteringTable_v6->num_rules = (uint8_t)1; 4922 4923 /* Configuring Software-Routing Filtering Rule */ 4924 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 4925 memset(&rt_tbl_idx, 0, sizeof(rt_tbl_idx)); 4926 strlcpy(rt_tbl_idx.name, IPACM_Iface::ipacmcfg->rt_tbl_wan_dl.name, IPA_RESOURCE_NAME_MAX); 4927 rt_tbl_idx.name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 4928 rt_tbl_idx.ip = IPA_IP_v6; 4929 if(ioctl(m_fd_ipa, IPA_IOC_QUERY_RT_TBL_INDEX, &rt_tbl_idx) < 0) 4930 { 4931 IPACMERR("Failed to get routing table index from name\n"); 4932 res = IPACM_FAILURE; 4933 goto fail; 4934 } 4935 IPACMDBG_H("Routing table %s has index %d\n", rt_tbl_idx.name, rt_tbl_idx.idx); 4936 4937 flt_rule_entry.at_rear = false; 4938 flt_rule_entry.flt_rule_hdl = -1; 4939 flt_rule_entry.status = -1; 4940 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 4941 #ifdef FEATURE_IPA_V3 4942 flt_rule_entry.rule.hashable = true; 4943 #endif 4944 flt_rule_entry.rule.rt_tbl_idx = rt_tbl_idx.idx; 4945 memcpy(&flt_rule_entry.rule.attrib, 4946 &rx_prop->rx[0].attrib, 4947 sizeof(flt_rule_entry.rule.attrib)); 4948 flt_rule_entry.rule.retain_hdr = 0; 4949 flt_rule_entry.rule.to_uc = 0; 4950 flt_rule_entry.rule.eq_attrib_type = 1; 4951 4952 memset(&flt_eq, 0, sizeof(flt_eq)); 4953 memcpy(&flt_eq.attrib, &flt_rule_entry.rule.attrib, sizeof(flt_eq.attrib)); 4954 flt_eq.ip = IPA_IP_v6; 4955 if(0 != ioctl(m_fd_ipa, IPA_IOC_GENERATE_FLT_EQ, &flt_eq)) 4956 { 4957 IPACMERR("Failed to get eq_attrib\n"); 4958 res = IPACM_FAILURE; 4959 goto fail; 4960 } 4961 memcpy(&flt_rule_entry.rule.eq_attrib, 4962 &flt_eq.eq_attrib, 4963 sizeof(flt_rule_entry.rule.eq_attrib)); 4964 memcpy(&(pFilteringTable_v6->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 4965 softwarerouting_act = true; 4966 /* end of contruct SW-RT rules to Q6*/ 4967 } 4968 else 4969 { 4970 if(embms_is_on == false) 4971 { 4972 if(IPACM_Wan::num_v4_flt_rule > 0) 4973 { 4974 len = sizeof(struct ipa_ioc_add_flt_rule) + IPACM_Wan::num_v4_flt_rule * sizeof(struct ipa_flt_rule_add); 4975 pFilteringTable_v4 = (struct ipa_ioc_add_flt_rule*)malloc(len); 4976 4977 IPACMDBG_H("Total number of WAN DL filtering rule for IPv4 is %d\n", IPACM_Wan::num_v4_flt_rule); 4978 4979 if (pFilteringTable_v4 == NULL) 4980 { 4981 IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); 4982 return IPACM_FAILURE; 4983 } 4984 memset(pFilteringTable_v4, 0, len); 4985 pFilteringTable_v4->commit = 1; 4986 pFilteringTable_v4->ep = rx_prop->rx[0].src_pipe; 4987 pFilteringTable_v4->global = false; 4988 pFilteringTable_v4->ip = IPA_IP_v4; 4989 pFilteringTable_v4->num_rules = (uint8_t)IPACM_Wan::num_v4_flt_rule; 4990 4991 memcpy(pFilteringTable_v4->rules, IPACM_Wan::flt_rule_v4, IPACM_Wan::num_v4_flt_rule * sizeof(ipa_flt_rule_add)); 4992 } 4993 4994 if(IPACM_Wan::num_v6_flt_rule > 0) 4995 { 4996 len = sizeof(struct ipa_ioc_add_flt_rule) + IPACM_Wan::num_v6_flt_rule * sizeof(struct ipa_flt_rule_add); 4997 pFilteringTable_v6 = (struct ipa_ioc_add_flt_rule*)malloc(len); 4998 4999 IPACMDBG_H("Total number of WAN DL filtering rule for IPv6 is %d\n", IPACM_Wan::num_v6_flt_rule); 5000 5001 if (pFilteringTable_v6 == NULL) 5002 { 5003 IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); 5004 free(pFilteringTable_v4); 5005 return IPACM_FAILURE; 5006 } 5007 memset(pFilteringTable_v6, 0, len); 5008 pFilteringTable_v6->commit = 1; 5009 pFilteringTable_v6->ep = rx_prop->rx[0].src_pipe; 5010 pFilteringTable_v6->global = false; 5011 pFilteringTable_v6->ip = IPA_IP_v6; 5012 pFilteringTable_v6->num_rules = (uint8_t)IPACM_Wan::num_v6_flt_rule; 5013 5014 memcpy(pFilteringTable_v6->rules, IPACM_Wan::flt_rule_v6, IPACM_Wan::num_v6_flt_rule * sizeof(ipa_flt_rule_add)); 5015 } 5016 } 5017 else //embms is on, always add 1 embms rule on top of WAN DL flt table 5018 { 5019 /* allocate ipv4 filtering table */ 5020 len = sizeof(struct ipa_ioc_add_flt_rule) + (1 + IPACM_Wan::num_v4_flt_rule) * sizeof(struct ipa_flt_rule_add); 5021 pFilteringTable_v4 = (struct ipa_ioc_add_flt_rule*)malloc(len); 5022 IPACMDBG_H("Total number of WAN DL filtering rule for IPv4 is %d\n", IPACM_Wan::num_v4_flt_rule + 1); 5023 if (pFilteringTable_v4 == NULL) 5024 { 5025 IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); 5026 return IPACM_FAILURE; 5027 } 5028 memset(pFilteringTable_v4, 0, len); 5029 pFilteringTable_v4->commit = 1; 5030 pFilteringTable_v4->ep = rx_prop->rx[0].src_pipe; 5031 pFilteringTable_v4->global = false; 5032 pFilteringTable_v4->ip = IPA_IP_v4; 5033 pFilteringTable_v4->num_rules = (uint8_t)IPACM_Wan::num_v4_flt_rule + 1; 5034 5035 /* allocate ipv6 filtering table */ 5036 len = sizeof(struct ipa_ioc_add_flt_rule) + (1 + IPACM_Wan::num_v6_flt_rule) * sizeof(struct ipa_flt_rule_add); 5037 pFilteringTable_v6 = (struct ipa_ioc_add_flt_rule*)malloc(len); 5038 IPACMDBG_H("Total number of WAN DL filtering rule for IPv6 is %d\n", IPACM_Wan::num_v6_flt_rule + 1); 5039 if (pFilteringTable_v6 == NULL) 5040 { 5041 IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); 5042 free(pFilteringTable_v4); 5043 return IPACM_FAILURE; 5044 } 5045 memset(pFilteringTable_v6, 0, len); 5046 pFilteringTable_v6->commit = 1; 5047 pFilteringTable_v6->ep = rx_prop->rx[0].src_pipe; 5048 pFilteringTable_v6->global = false; 5049 pFilteringTable_v6->ip = IPA_IP_v6; 5050 pFilteringTable_v6->num_rules = (uint8_t)IPACM_Wan::num_v6_flt_rule + 1; 5051 5052 config_dft_embms_rules(pFilteringTable_v4, pFilteringTable_v6); 5053 if(IPACM_Wan::num_v4_flt_rule > 0) 5054 { 5055 memcpy(&(pFilteringTable_v4->rules[1]), IPACM_Wan::flt_rule_v4, IPACM_Wan::num_v4_flt_rule * sizeof(ipa_flt_rule_add)); 5056 } 5057 5058 if(IPACM_Wan::num_v6_flt_rule > 0) 5059 { 5060 memcpy(&(pFilteringTable_v6->rules[1]), IPACM_Wan::flt_rule_v6, IPACM_Wan::num_v6_flt_rule * sizeof(ipa_flt_rule_add)); 5061 } 5062 } 5063 } 5064 5065 if(false == m_filtering.AddWanDLFilteringRule(pFilteringTable_v4, pFilteringTable_v6, mux_id)) 5066 { 5067 IPACMERR("Failed to install WAN DL filtering table.\n"); 5068 res = IPACM_FAILURE; 5069 goto fail; 5070 } 5071 5072 fail: 5073 if(pFilteringTable_v4 != NULL) 5074 { 5075 free(pFilteringTable_v4); 5076 } 5077 if(pFilteringTable_v6 != NULL) 5078 { 5079 free(pFilteringTable_v6); 5080 } 5081 return res; 5082 } 5083 5084 void IPACM_Wan::change_to_network_order(ipa_ip_type iptype, ipa_rule_attrib* attrib) 5085 { 5086 if(attrib == NULL) 5087 { 5088 IPACMERR("Attribute pointer is NULL.\n"); 5089 return; 5090 } 5091 5092 if(iptype == IPA_IP_v6) 5093 { 5094 int i; 5095 for(i=0; i<4; i++) 5096 { 5097 attrib->u.v6.src_addr[i] = htonl(attrib->u.v6.src_addr[i]); 5098 attrib->u.v6.src_addr_mask[i] = htonl(attrib->u.v6.src_addr_mask[i]); 5099 attrib->u.v6.dst_addr[i] = htonl(attrib->u.v6.dst_addr[i]); 5100 attrib->u.v6.dst_addr_mask[i] = htonl(attrib->u.v6.dst_addr_mask[i]); 5101 } 5102 } 5103 else 5104 { 5105 IPACMDBG_H("IP type is not IPv6, do nothing: %d\n", iptype); 5106 } 5107 5108 return; 5109 } 5110 5111 bool IPACM_Wan::is_global_ipv6_addr(uint32_t* ipv6_addr) 5112 { 5113 if(ipv6_addr == NULL) 5114 { 5115 IPACMERR("IPv6 address is empty.\n"); 5116 return false; 5117 } 5118 IPACMDBG_H("Get ipv6 address with first word 0x%08x.\n", ipv6_addr[0]); 5119 5120 uint32_t ipv6_link_local_prefix, ipv6_link_local_prefix_mask; 5121 ipv6_link_local_prefix = 0xFE800000; 5122 ipv6_link_local_prefix_mask = 0xFFC00000; 5123 if((ipv6_addr[0] & ipv6_link_local_prefix_mask) == (ipv6_link_local_prefix & ipv6_link_local_prefix_mask)) 5124 { 5125 IPACMDBG_H("This IPv6 address is link local.\n"); 5126 return false; 5127 } 5128 else 5129 { 5130 IPACMDBG_H("This IPv6 address is not link local.\n"); 5131 return true; 5132 } 5133 } 5134 5135 /* handle STA WAN-client */ 5136 /* handle WAN client initial, construct full headers (tx property) */ 5137 int IPACM_Wan::handle_wan_hdr_init(uint8_t *mac_addr) 5138 { 5139 5140 #define WAN_IFACE_INDEX_LEN 2 5141 5142 int res = IPACM_SUCCESS, len = 0; 5143 char index[WAN_IFACE_INDEX_LEN]; 5144 struct ipa_ioc_copy_hdr sCopyHeader; 5145 struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL; 5146 uint32_t cnt; 5147 int clnt_indx; 5148 5149 clnt_indx = get_wan_client_index(mac_addr); 5150 5151 if (clnt_indx != IPACM_INVALID_INDEX) 5152 { 5153 IPACMERR("eth client is found/attached already with index %d \n", clnt_indx); 5154 return IPACM_FAILURE; 5155 } 5156 5157 /* add header to IPA */ 5158 if (num_wan_client >= IPA_MAX_NUM_WAN_CLIENTS) 5159 { 5160 IPACMERR("Reached maximum number(%d) of eth clients\n", IPA_MAX_NUM_WAN_CLIENTS); 5161 return IPACM_FAILURE; 5162 } 5163 5164 IPACMDBG_H("WAN client number: %d\n", num_wan_client); 5165 5166 memcpy(get_client_memptr(wan_client, num_wan_client)->mac, 5167 mac_addr, 5168 sizeof(get_client_memptr(wan_client, num_wan_client)->mac)); 5169 5170 IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 5171 mac_addr[0], mac_addr[1], mac_addr[2], 5172 mac_addr[3], mac_addr[4], mac_addr[5]); 5173 5174 IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 5175 get_client_memptr(wan_client, num_wan_client)->mac[0], 5176 get_client_memptr(wan_client, num_wan_client)->mac[1], 5177 get_client_memptr(wan_client, num_wan_client)->mac[2], 5178 get_client_memptr(wan_client, num_wan_client)->mac[3], 5179 get_client_memptr(wan_client, num_wan_client)->mac[4], 5180 get_client_memptr(wan_client, num_wan_client)->mac[5]); 5181 5182 /* add header to IPA */ 5183 if(tx_prop != NULL) 5184 { 5185 len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add)); 5186 pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len); 5187 if (pHeaderDescriptor == NULL) 5188 { 5189 IPACMERR("calloc failed to allocate pHeaderDescriptor\n"); 5190 return IPACM_FAILURE; 5191 } 5192 5193 /* copy partial header for v4*/ 5194 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++) 5195 { 5196 if(tx_prop->tx[cnt].ip==IPA_IP_v4) 5197 { 5198 IPACMDBG_H("Got partial v4-header name from %d tx props\n", cnt); 5199 memset(&sCopyHeader, 0, sizeof(sCopyHeader)); 5200 memcpy(sCopyHeader.name, 5201 tx_prop->tx[cnt].hdr_name, 5202 sizeof(sCopyHeader.name)); 5203 5204 IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt); 5205 if (m_header.CopyHeader(&sCopyHeader) == false) 5206 { 5207 PERROR("ioctl copy header failed"); 5208 res = IPACM_FAILURE; 5209 goto fail; 5210 } 5211 5212 IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); 5213 IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); 5214 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) 5215 { 5216 IPACMERR("header oversize\n"); 5217 res = IPACM_FAILURE; 5218 goto fail; 5219 } 5220 else 5221 { 5222 memcpy(pHeaderDescriptor->hdr[0].hdr, 5223 sCopyHeader.hdr, 5224 sCopyHeader.hdr_len); 5225 } 5226 5227 /* copy client mac_addr to partial header */ 5228 IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", 5229 sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); 5230 5231 /* only copy 6 bytes mac-address */ 5232 if(sCopyHeader.is_eth2_ofst_valid == false) 5233 { 5234 memcpy(&pHeaderDescriptor->hdr[0].hdr[0], 5235 mac_addr, IPA_MAC_ADDR_SIZE); 5236 } 5237 else 5238 { 5239 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst], 5240 mac_addr, IPA_MAC_ADDR_SIZE); 5241 } 5242 5243 5244 pHeaderDescriptor->commit = true; 5245 pHeaderDescriptor->num_hdrs = 1; 5246 5247 memset(pHeaderDescriptor->hdr[0].name, 0, 5248 sizeof(pHeaderDescriptor->hdr[0].name)); 5249 5250 snprintf(index,sizeof(index), "%d", ipa_if_num); 5251 strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)); 5252 pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 5253 if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WAN_PARTIAL_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) 5254 { 5255 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name)); 5256 res = IPACM_FAILURE; 5257 goto fail; 5258 } 5259 5260 snprintf(index,sizeof(index), "%d", header_name_count); 5261 if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) 5262 { 5263 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name)); 5264 res = IPACM_FAILURE; 5265 goto fail; 5266 } 5267 5268 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; 5269 pHeaderDescriptor->hdr[0].hdr_hdl = -1; 5270 pHeaderDescriptor->hdr[0].is_partial = 0; 5271 pHeaderDescriptor->hdr[0].status = -1; 5272 5273 if (m_header.AddHeader(pHeaderDescriptor) == false || 5274 pHeaderDescriptor->hdr[0].status != 0) 5275 { 5276 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); 5277 res = IPACM_FAILURE; 5278 goto fail; 5279 } 5280 5281 get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl; 5282 IPACMDBG_H("eth-client(%d) v4 full header name:%s header handle:(0x%x)\n", 5283 num_wan_client, 5284 pHeaderDescriptor->hdr[0].name, 5285 get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v4); 5286 get_client_memptr(wan_client, num_wan_client)->ipv4_header_set=true; 5287 5288 break; 5289 } 5290 } 5291 5292 5293 /* copy partial header for v6*/ 5294 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++) 5295 { 5296 if(tx_prop->tx[cnt].ip==IPA_IP_v6) 5297 { 5298 5299 IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt); 5300 memset(&sCopyHeader, 0, sizeof(sCopyHeader)); 5301 memcpy(sCopyHeader.name, 5302 tx_prop->tx[cnt].hdr_name, 5303 sizeof(sCopyHeader.name)); 5304 5305 IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt); 5306 if (m_header.CopyHeader(&sCopyHeader) == false) 5307 { 5308 PERROR("ioctl copy header failed"); 5309 res = IPACM_FAILURE; 5310 goto fail; 5311 } 5312 5313 IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); 5314 IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); 5315 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) 5316 { 5317 IPACMERR("header oversize\n"); 5318 res = IPACM_FAILURE; 5319 goto fail; 5320 } 5321 else 5322 { 5323 memcpy(pHeaderDescriptor->hdr[0].hdr, 5324 sCopyHeader.hdr, 5325 sCopyHeader.hdr_len); 5326 } 5327 5328 /* copy client mac_addr to partial header */ 5329 if(sCopyHeader.is_eth2_ofst_valid == false) 5330 { 5331 memcpy(&pHeaderDescriptor->hdr[0].hdr[0], 5332 mac_addr, IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */ 5333 } 5334 else 5335 { 5336 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst], 5337 mac_addr, IPA_MAC_ADDR_SIZE); /* only copy 6 bytes mac-address */ 5338 } 5339 5340 5341 pHeaderDescriptor->commit = true; 5342 pHeaderDescriptor->num_hdrs = 1; 5343 5344 memset(pHeaderDescriptor->hdr[0].name, 0, 5345 sizeof(pHeaderDescriptor->hdr[0].name)); 5346 5347 snprintf(index,sizeof(index), "%d", ipa_if_num); 5348 strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)); 5349 pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 5350 if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_WAN_PARTIAL_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) 5351 { 5352 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name)); 5353 res = IPACM_FAILURE; 5354 goto fail; 5355 } 5356 snprintf(index,sizeof(index), "%d", header_name_count); 5357 if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) 5358 { 5359 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name)); 5360 res = IPACM_FAILURE; 5361 goto fail; 5362 } 5363 5364 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; 5365 pHeaderDescriptor->hdr[0].hdr_hdl = -1; 5366 pHeaderDescriptor->hdr[0].is_partial = 0; 5367 pHeaderDescriptor->hdr[0].status = -1; 5368 5369 if (m_header.AddHeader(pHeaderDescriptor) == false || 5370 pHeaderDescriptor->hdr[0].status != 0) 5371 { 5372 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); 5373 res = IPACM_FAILURE; 5374 goto fail; 5375 } 5376 5377 get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl; 5378 IPACMDBG_H("eth-client(%d) v6 full header name:%s header handle:(0x%x)\n", 5379 num_wan_client, 5380 pHeaderDescriptor->hdr[0].name, 5381 get_client_memptr(wan_client, num_wan_client)->hdr_hdl_v6); 5382 5383 get_client_memptr(wan_client, num_wan_client)->ipv6_header_set=true; 5384 5385 break; 5386 5387 } 5388 } 5389 /* initialize wifi client*/ 5390 get_client_memptr(wan_client, num_wan_client)->route_rule_set_v4 = false; 5391 get_client_memptr(wan_client, num_wan_client)->route_rule_set_v6 = 0; 5392 get_client_memptr(wan_client, num_wan_client)->ipv4_set = false; 5393 get_client_memptr(wan_client, num_wan_client)->ipv6_set = 0; 5394 num_wan_client++; 5395 header_name_count++; //keep increasing header_name_count 5396 res = IPACM_SUCCESS; 5397 IPACMDBG_H("eth client number: %d\n", num_wan_client); 5398 } 5399 else 5400 { 5401 return res; 5402 } 5403 fail: 5404 free(pHeaderDescriptor); 5405 5406 return res; 5407 } 5408 5409 /*handle eth client */ 5410 int IPACM_Wan::handle_wan_client_ipaddr(ipacm_event_data_all *data) 5411 { 5412 int clnt_indx; 5413 int v6_num; 5414 5415 IPACMDBG_H("number of wan clients: %d\n", num_wan_client); 5416 IPACMDBG_H(" event MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 5417 data->mac_addr[0], 5418 data->mac_addr[1], 5419 data->mac_addr[2], 5420 data->mac_addr[3], 5421 data->mac_addr[4], 5422 data->mac_addr[5]); 5423 5424 clnt_indx = get_wan_client_index(data->mac_addr); 5425 5426 if (clnt_indx == IPACM_INVALID_INDEX) 5427 { 5428 IPACMERR("wan client not found/attached \n"); 5429 return IPACM_FAILURE; 5430 } 5431 5432 IPACMDBG_H("Ip-type received %d\n", data->iptype); 5433 if (data->iptype == IPA_IP_v4) 5434 { 5435 IPACMDBG_H("ipv4 address: 0x%x\n", data->ipv4_addr); 5436 if (data->ipv4_addr != 0) /* not 0.0.0.0 */ 5437 { 5438 if (get_client_memptr(wan_client, clnt_indx)->ipv4_set == false) 5439 { 5440 get_client_memptr(wan_client, clnt_indx)->v4_addr = data->ipv4_addr; 5441 get_client_memptr(wan_client, clnt_indx)->ipv4_set = true; 5442 /* Add NAT rules after ipv4 RT rules are set */ 5443 CtList->HandleSTAClientAddEvt(data->ipv4_addr); 5444 } 5445 else 5446 { 5447 /* check if client got new IPv4 address*/ 5448 if(data->ipv4_addr == get_client_memptr(wan_client, clnt_indx)->v4_addr) 5449 { 5450 IPACMDBG_H("Already setup ipv4 addr for client:%d, ipv4 address didn't change\n", clnt_indx); 5451 return IPACM_FAILURE; 5452 } 5453 else 5454 { 5455 IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx); 5456 /* Del NAT rules before ipv4 RT rules are delete */ 5457 CtList->HandleSTAClientDelEvt(get_client_memptr(wan_client, clnt_indx)->v4_addr); 5458 delete_wan_rtrules(clnt_indx,IPA_IP_v4); 5459 get_client_memptr(wan_client, clnt_indx)->route_rule_set_v4 = false; 5460 get_client_memptr(wan_client, clnt_indx)->v4_addr = data->ipv4_addr; 5461 /* Add NAT rules after ipv4 RT rules are set */ 5462 CtList->HandleSTAClientAddEvt(data->ipv4_addr); 5463 } 5464 } 5465 } 5466 else 5467 { 5468 IPACMDBG_H("Invalid client IPv4 address \n"); 5469 return IPACM_FAILURE; 5470 } 5471 } 5472 else 5473 { 5474 if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) || 5475 (data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0)) /* check if all 0 not valid ipv6 address */ 5476 { 5477 IPACMDBG_H("ipv6 address: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); 5478 if(get_client_memptr(wan_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR) 5479 { 5480 5481 for(v6_num=0;v6_num < get_client_memptr(wan_client, clnt_indx)->ipv6_set;v6_num++) 5482 { 5483 if( data->ipv6_addr[0] == get_client_memptr(wan_client, clnt_indx)->v6_addr[v6_num][0] && 5484 data->ipv6_addr[1] == get_client_memptr(wan_client, clnt_indx)->v6_addr[v6_num][1] && 5485 data->ipv6_addr[2]== get_client_memptr(wan_client, clnt_indx)->v6_addr[v6_num][2] && 5486 data->ipv6_addr[3] == get_client_memptr(wan_client, clnt_indx)->v6_addr[v6_num][3]) 5487 { 5488 IPACMDBG_H("Already see this ipv6 addr for client:%d\n", clnt_indx); 5489 return IPACM_FAILURE; /* not setup the RT rules*/ 5490 } 5491 } 5492 5493 /* not see this ipv6 before for wifi client*/ 5494 get_client_memptr(wan_client, clnt_indx)->v6_addr[get_client_memptr(wan_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0]; 5495 get_client_memptr(wan_client, clnt_indx)->v6_addr[get_client_memptr(wan_client, clnt_indx)->ipv6_set][1] = data->ipv6_addr[1]; 5496 get_client_memptr(wan_client, clnt_indx)->v6_addr[get_client_memptr(wan_client, clnt_indx)->ipv6_set][2] = data->ipv6_addr[2]; 5497 get_client_memptr(wan_client, clnt_indx)->v6_addr[get_client_memptr(wan_client, clnt_indx)->ipv6_set][3] = data->ipv6_addr[3]; 5498 get_client_memptr(wan_client, clnt_indx)->ipv6_set++; 5499 } 5500 else 5501 { 5502 IPACMDBG_H("Already got 3 ipv6 addr for client:%d\n", clnt_indx); 5503 return IPACM_FAILURE; /* not setup the RT rules*/ 5504 } 5505 } 5506 else 5507 { 5508 IPACMDBG_H("Invalid IPV6 address\n"); 5509 return IPACM_FAILURE; 5510 } 5511 } 5512 5513 return IPACM_SUCCESS; 5514 } 5515 5516 /*handle wan client routing rule*/ 5517 int IPACM_Wan::handle_wan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype) 5518 { 5519 struct ipa_ioc_add_rt_rule *rt_rule; 5520 struct ipa_rt_rule_add *rt_rule_entry; 5521 uint32_t tx_index; 5522 int wan_index,v6_num; 5523 const int NUM = 1; 5524 5525 if(tx_prop == NULL) 5526 { 5527 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); 5528 return IPACM_SUCCESS; 5529 } 5530 5531 IPACMDBG_H("Received mac_addr MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 5532 mac_addr[0], mac_addr[1], mac_addr[2], 5533 mac_addr[3], mac_addr[4], mac_addr[5]); 5534 5535 wan_index = get_wan_client_index(mac_addr); 5536 if (wan_index == IPACM_INVALID_INDEX) 5537 { 5538 IPACMDBG_H("wan client not found/attached \n"); 5539 return IPACM_SUCCESS; 5540 } 5541 5542 if (iptype==IPA_IP_v4) { 5543 IPACMDBG_H("wan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", wan_index, iptype, 5544 get_client_memptr(wan_client, wan_index)->ipv4_set, 5545 get_client_memptr(wan_client, wan_index)->route_rule_set_v4); 5546 } else { 5547 IPACMDBG_H("wan client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", wan_index, iptype, 5548 get_client_memptr(wan_client, wan_index)->ipv6_set, 5549 get_client_memptr(wan_client, wan_index)->route_rule_set_v6); 5550 } 5551 5552 /* Add default routing rules if not set yet */ 5553 if ((iptype == IPA_IP_v4 5554 && get_client_memptr(wan_client, wan_index)->route_rule_set_v4 == false 5555 && get_client_memptr(wan_client, wan_index)->ipv4_set == true) 5556 || (iptype == IPA_IP_v6 5557 && get_client_memptr(wan_client, wan_index)->route_rule_set_v6 < get_client_memptr(wan_client, wan_index)->ipv6_set 5558 )) 5559 { 5560 5561 /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */ 5562 IPACMDBG_H("dev %s add producer dependency\n", dev_name); 5563 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]); 5564 IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false); 5565 5566 rt_rule = (struct ipa_ioc_add_rt_rule *) 5567 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + 5568 NUM * sizeof(struct ipa_rt_rule_add)); 5569 5570 if (rt_rule == NULL) 5571 { 5572 PERROR("Error Locate ipa_ioc_add_rt_rule memory...\n"); 5573 return IPACM_FAILURE; 5574 } 5575 5576 rt_rule->commit = 1; 5577 rt_rule->num_rules = (uint8_t)NUM; 5578 rt_rule->ip = iptype; 5579 5580 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) 5581 { 5582 if(iptype != tx_prop->tx[tx_index].ip) 5583 { 5584 IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n", 5585 tx_index, tx_prop->tx[tx_index].ip,iptype); 5586 continue; 5587 } 5588 5589 rt_rule_entry = &rt_rule->rules[0]; 5590 rt_rule_entry->at_rear = 0; 5591 5592 if (iptype == IPA_IP_v4) 5593 { 5594 IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", wan_index, 5595 get_client_memptr(wan_client, wan_index)->v4_addr); 5596 5597 IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n", 5598 wan_index, 5599 get_client_memptr(wan_client, wan_index)->hdr_hdl_v4); 5600 strlcpy(rt_rule->rt_tbl_name, 5601 IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name, 5602 sizeof(rt_rule->rt_tbl_name)); 5603 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 5604 if (IPACM_Iface::ipacmcfg->isMCC_Mode == true) 5605 { 5606 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n", 5607 tx_prop->tx[tx_index].alt_dst_pipe); 5608 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe; 5609 } 5610 else 5611 { 5612 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; 5613 } 5614 memcpy(&rt_rule_entry->rule.attrib, 5615 &tx_prop->tx[tx_index].attrib, 5616 sizeof(rt_rule_entry->rule.attrib)); 5617 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 5618 rt_rule_entry->rule.hdr_hdl = get_client_memptr(wan_client, wan_index)->hdr_hdl_v4; 5619 rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wan_client, wan_index)->v4_addr; 5620 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; 5621 #ifdef FEATURE_IPA_V3 5622 rt_rule_entry->rule.hashable = true; 5623 #endif 5624 if (false == m_routing.AddRoutingRule(rt_rule)) 5625 { 5626 IPACMERR("Routing rule addition failed!\n"); 5627 free(rt_rule); 5628 return IPACM_FAILURE; 5629 } 5630 5631 /* copy ipv4 RT hdl */ 5632 get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v4 = 5633 rt_rule->rules[0].rt_rule_hdl; 5634 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, 5635 get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v4, iptype); 5636 } else { 5637 5638 for(v6_num = get_client_memptr(wan_client, wan_index)->route_rule_set_v6;v6_num < get_client_memptr(wan_client, wan_index)->ipv6_set;v6_num++) 5639 { 5640 IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n", 5641 wan_index, 5642 get_client_memptr(wan_client, wan_index)->hdr_hdl_v6); 5643 5644 /* v6 LAN_RT_TBL */ 5645 strlcpy(rt_rule->rt_tbl_name, 5646 IPACM_Iface::ipacmcfg->rt_tbl_v6.name, 5647 sizeof(rt_rule->rt_tbl_name)); 5648 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 5649 /* Uplink going to wan clients should go to IPA */ 5650 if (IPACM_Iface::ipacmcfg->isMCC_Mode == true) 5651 { 5652 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n", 5653 tx_prop->tx[tx_index].alt_dst_pipe); 5654 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe; 5655 } 5656 else 5657 { 5658 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; 5659 } 5660 memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib)); 5661 rt_rule_entry->rule.hdr_hdl = get_client_memptr(wan_client, wan_index)->hdr_hdl_v6;; 5662 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 5663 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][0]; 5664 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][1]; 5665 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][2]; 5666 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][3]; 5667 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; 5668 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; 5669 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; 5670 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; 5671 #ifdef FEATURE_IPA_V3 5672 rt_rule_entry->rule.hashable = true; 5673 #endif 5674 if (false == m_routing.AddRoutingRule(rt_rule)) 5675 { 5676 IPACMERR("Routing rule addition failed!\n"); 5677 free(rt_rule); 5678 return IPACM_FAILURE; 5679 } 5680 5681 get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6[v6_num] = rt_rule->rules[0].rt_rule_hdl; 5682 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, 5683 get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6[v6_num], iptype); 5684 5685 /*Copy same rule to v6 WAN RT TBL*/ 5686 strlcpy(rt_rule->rt_tbl_name, 5687 IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, 5688 sizeof(rt_rule->rt_tbl_name)); 5689 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 5690 /* Downlink traffic from Wan clients, should go exception */ 5691 rt_rule_entry->rule.dst = iface_query->excp_pipe; 5692 memcpy(&rt_rule_entry->rule.attrib, 5693 &tx_prop->tx[tx_index].attrib, 5694 sizeof(rt_rule_entry->rule.attrib)); 5695 rt_rule_entry->rule.hdr_hdl = 0; 5696 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 5697 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][0]; 5698 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][1]; 5699 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][2]; 5700 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wan_client, wan_index)->v6_addr[v6_num][3]; 5701 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; 5702 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; 5703 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; 5704 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; 5705 if (false == m_routing.AddRoutingRule(rt_rule)) 5706 { 5707 IPACMERR("Routing rule addition failed!\n"); 5708 free(rt_rule); 5709 return IPACM_FAILURE; 5710 } 5711 5712 get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6_wan[v6_num] = rt_rule->rules[0].rt_rule_hdl; 5713 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, 5714 get_client_memptr(wan_client, wan_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6_wan[v6_num], iptype); 5715 } 5716 } 5717 5718 } /* end of for loop */ 5719 5720 free(rt_rule); 5721 5722 if (iptype == IPA_IP_v4) 5723 { 5724 get_client_memptr(wan_client, wan_index)->route_rule_set_v4 = true; 5725 } 5726 else 5727 { 5728 get_client_memptr(wan_client, wan_index)->route_rule_set_v6 = get_client_memptr(wan_client, wan_index)->ipv6_set; 5729 } 5730 } 5731 5732 return IPACM_SUCCESS; 5733 } 5734 5735 /* TODO Handle wan client routing rules also */ 5736 void IPACM_Wan::handle_wlan_SCC_MCC_switch(bool isSCCMode, ipa_ip_type iptype) 5737 { 5738 struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL; 5739 struct ipa_rt_rule_mdfy *rt_rule_entry; 5740 uint32_t tx_index = 0; 5741 5742 IPACMDBG("\n"); 5743 if (tx_prop == NULL || is_default_gateway == false) 5744 { 5745 IPACMDBG_H("No tx properties or no default route set yet\n"); 5746 return; 5747 } 5748 5749 const int NUM = tx_prop->num_tx_props; 5750 5751 for (tx_index = 0; tx_index < tx_prop->num_tx_props; tx_index++) 5752 { 5753 if (tx_prop->tx[tx_index].ip != iptype) 5754 { 5755 IPACMDBG_H("Tx:%d, ip-type: %d ip-type not matching: %d Ignore\n", 5756 tx_index, tx_prop->tx[tx_index].ip, iptype); 5757 continue; 5758 } 5759 5760 if (rt_rule == NULL) 5761 { 5762 rt_rule = (struct ipa_ioc_mdfy_rt_rule *) 5763 calloc(1, sizeof(struct ipa_ioc_mdfy_rt_rule) + 5764 NUM * sizeof(struct ipa_rt_rule_mdfy)); 5765 5766 if (rt_rule == NULL) 5767 { 5768 IPACMERR("Unable to allocate memory for modify rt rule\n"); 5769 return; 5770 } 5771 IPACMDBG("Allocated memory for %d rules successfully\n", NUM); 5772 5773 rt_rule->commit = 1; 5774 rt_rule->num_rules = 0; 5775 rt_rule->ip = iptype; 5776 } 5777 5778 rt_rule_entry = &rt_rule->rules[rt_rule->num_rules]; 5779 5780 memcpy(&rt_rule_entry->rule.attrib, 5781 &tx_prop->tx[tx_index].attrib, 5782 sizeof(rt_rule_entry->rule.attrib)); 5783 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 5784 5785 if (iptype == IPA_IP_v4) 5786 { 5787 rt_rule_entry->rule.attrib.u.v4.dst_addr = 0; 5788 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0; 5789 rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v4; 5790 rt_rule_entry->rt_rule_hdl = wan_route_rule_v4_hdl[tx_index]; 5791 } 5792 else 5793 { 5794 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0; 5795 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0; 5796 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0; 5797 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0; 5798 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0; 5799 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0; 5800 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0; 5801 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0; 5802 5803 rt_rule_entry->rule.hdr_hdl = hdr_hdl_sta_v6; 5804 rt_rule_entry->rt_rule_hdl = wan_route_rule_v6_hdl[tx_index]; 5805 } 5806 IPACMDBG_H("Header handle: 0x%x\n", rt_rule_entry->rule.hdr_hdl); 5807 5808 if (isSCCMode) 5809 { 5810 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; 5811 } 5812 else 5813 { 5814 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n", 5815 tx_prop->tx[tx_index].alt_dst_pipe); 5816 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe; 5817 } 5818 5819 rt_rule->num_rules++; 5820 } 5821 5822 if (rt_rule != NULL) 5823 { 5824 5825 if (rt_rule->num_rules > 0) 5826 { 5827 if (false == m_routing.ModifyRoutingRule(rt_rule)) 5828 { 5829 IPACMERR("Routing rule modify failed!\n"); 5830 free(rt_rule); 5831 return; 5832 } 5833 5834 IPACMDBG("Routing rule modified successfully \n"); 5835 } 5836 5837 free(rt_rule); 5838 } 5839 5840 return; 5841 } 5842 5843 void IPACM_Wan::handle_wan_client_SCC_MCC_switch(bool isSCCMode, ipa_ip_type iptype) 5844 { 5845 struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL; 5846 struct ipa_rt_rule_mdfy *rt_rule_entry; 5847 5848 uint32_t tx_index = 0, clnt_index =0; 5849 int v6_num = 0; 5850 const int NUM_RULES = 1; 5851 5852 int size = sizeof(struct ipa_ioc_mdfy_rt_rule) + 5853 NUM_RULES * sizeof(struct ipa_rt_rule_mdfy); 5854 5855 IPACMDBG("isSCCMode: %d\n",isSCCMode); 5856 5857 if (tx_prop == NULL || is_default_gateway == false) 5858 { 5859 IPACMDBG_H("No tx properties or no default route set yet\n"); 5860 return; 5861 } 5862 5863 rt_rule = (struct ipa_ioc_mdfy_rt_rule *)calloc(1, size); 5864 if (rt_rule == NULL) 5865 { 5866 IPACMERR("Unable to allocate memory for modify rt rule\n"); 5867 return; 5868 } 5869 5870 5871 for (clnt_index = 0; clnt_index < num_wan_client; clnt_index++) 5872 { 5873 if (iptype == IPA_IP_v4) 5874 { 5875 IPACMDBG_H("wan client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", 5876 clnt_index, iptype, 5877 get_client_memptr(wan_client, clnt_index)->ipv4_set, 5878 get_client_memptr(wan_client, clnt_index)->route_rule_set_v4); 5879 5880 if( get_client_memptr(wan_client, clnt_index)->route_rule_set_v4 == false || 5881 get_client_memptr(wan_client, clnt_index)->ipv4_set == false) 5882 { 5883 continue; 5884 } 5885 5886 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) 5887 { 5888 if (iptype != tx_prop->tx[tx_index].ip) 5889 { 5890 IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d skip\n", 5891 tx_index, tx_prop->tx[tx_index].ip, iptype); 5892 continue; 5893 } 5894 5895 memset(rt_rule, 0, size); 5896 rt_rule->commit = 1; 5897 rt_rule->num_rules = NUM_RULES; 5898 rt_rule->ip = iptype; 5899 rt_rule_entry = &rt_rule->rules[0]; 5900 5901 IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", clnt_index, 5902 get_client_memptr(wan_client, clnt_index)->v4_addr); 5903 5904 IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n", 5905 clnt_index, 5906 get_client_memptr(wan_client, clnt_index)->hdr_hdl_v4); 5907 5908 if (IPACM_Iface::ipacmcfg->isMCC_Mode == true) 5909 { 5910 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n", 5911 tx_prop->tx[tx_index].alt_dst_pipe); 5912 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe; 5913 } 5914 else 5915 { 5916 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; 5917 } 5918 5919 memcpy(&rt_rule_entry->rule.attrib, 5920 &tx_prop->tx[tx_index].attrib, 5921 sizeof(rt_rule_entry->rule.attrib)); 5922 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 5923 5924 rt_rule_entry->rule.hdr_hdl = get_client_memptr(wan_client, clnt_index)->hdr_hdl_v4; 5925 rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(wan_client, clnt_index)->v4_addr; 5926 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; 5927 5928 /* copy ipv4 RT rule hdl */ 5929 IPACMDBG_H("rt rule hdl=%x\n", 5930 get_client_memptr(wan_client, clnt_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v4); 5931 5932 rt_rule_entry->rt_rule_hdl = 5933 get_client_memptr(wan_client, clnt_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v4; 5934 5935 if (false == m_routing.ModifyRoutingRule(rt_rule)) 5936 { 5937 IPACMERR("Routing rule modify failed!\n"); 5938 free(rt_rule); 5939 return; 5940 } 5941 } 5942 } 5943 else 5944 { 5945 IPACMDBG_H("wan client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", clnt_index, iptype, 5946 get_client_memptr(wan_client, clnt_index)->ipv6_set, 5947 get_client_memptr(wan_client, clnt_index)->route_rule_set_v6); 5948 5949 if( get_client_memptr(wan_client, clnt_index)->route_rule_set_v6 == 0) 5950 { 5951 continue; 5952 } 5953 5954 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) 5955 { 5956 if (iptype != tx_prop->tx[tx_index].ip) 5957 { 5958 IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d skip\n", 5959 tx_index, tx_prop->tx[tx_index].ip, iptype); 5960 continue; 5961 } 5962 5963 memset(rt_rule, 0, size); 5964 rt_rule->commit = 1; 5965 rt_rule->num_rules = NUM_RULES; 5966 rt_rule->ip = iptype; 5967 rt_rule_entry = &rt_rule->rules[0]; 5968 5969 /* Modify only rules in v6 WAN RT TBL*/ 5970 for (v6_num = 0; 5971 v6_num < get_client_memptr(wan_client, clnt_index)->route_rule_set_v6; 5972 v6_num++) 5973 { 5974 IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n", 5975 clnt_index, 5976 get_client_memptr(wan_client, clnt_index)->hdr_hdl_v6); 5977 5978 /* Downlink traffic from Wan iface, directly through IPA */ 5979 if (IPACM_Iface::ipacmcfg->isMCC_Mode == true) 5980 { 5981 IPACMDBG_H("In MCC mode, use alt dst pipe: %d\n", 5982 tx_prop->tx[tx_index].alt_dst_pipe); 5983 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].alt_dst_pipe; 5984 } 5985 else 5986 { 5987 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; 5988 } 5989 5990 memcpy(&rt_rule_entry->rule.attrib, 5991 &tx_prop->tx[tx_index].attrib, 5992 sizeof(rt_rule_entry->rule.attrib)); 5993 5994 rt_rule_entry->rule.hdr_hdl = get_client_memptr(wan_client, clnt_index)->hdr_hdl_v6; 5995 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 5996 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(wan_client, clnt_index)->v6_addr[v6_num][0]; 5997 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(wan_client, clnt_index)->v6_addr[v6_num][1]; 5998 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(wan_client, clnt_index)->v6_addr[v6_num][2]; 5999 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(wan_client, clnt_index)->v6_addr[v6_num][3]; 6000 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; 6001 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; 6002 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; 6003 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; 6004 6005 IPACMDBG_H("rt rule hdl=%x\n", 6006 get_client_memptr(wan_client, clnt_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6_wan[v6_num]); 6007 6008 rt_rule_entry->rt_rule_hdl = 6009 get_client_memptr(wan_client, clnt_index)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6_wan[v6_num]; 6010 6011 if (false == m_routing.ModifyRoutingRule(rt_rule)) 6012 { 6013 IPACMERR("Routing rule Modify failed!\n"); 6014 free(rt_rule); 6015 return; 6016 } 6017 } 6018 } /* end of for loop */ 6019 } 6020 6021 } 6022 6023 free(rt_rule); 6024 return; 6025 } 6026 6027 /*handle eth client */ 6028 int IPACM_Wan::handle_network_stats_update(ipa_get_apn_data_stats_resp_msg_v01 *data) 6029 { 6030 FILE *fp = NULL; 6031 6032 for (uint32_t apn_index =0; apn_index < data->apn_data_stats_list_len; apn_index++) 6033 { 6034 if(data->apn_data_stats_list[apn_index].mux_id == ext_prop->ext[0].mux_id) 6035 { 6036 IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_NETWORK_STATS, MUX ID %d TX (P%lu/B%lu) RX (P%lu/B%lu)\n", 6037 data->apn_data_stats_list[apn_index].mux_id, 6038 data->apn_data_stats_list[apn_index].num_ul_packets, 6039 data->apn_data_stats_list[apn_index].num_ul_bytes, 6040 data->apn_data_stats_list[apn_index].num_dl_packets, 6041 data->apn_data_stats_list[apn_index].num_dl_bytes); 6042 fp = fopen(IPA_NETWORK_STATS_FILE_NAME, "w"); 6043 if ( fp == NULL ) 6044 { 6045 IPACMERR("Failed to write pipe stats to %s, error is %d - %s\n", 6046 IPA_NETWORK_STATS_FILE_NAME, errno, strerror(errno)); 6047 return IPACM_FAILURE; 6048 } 6049 6050 fprintf(fp, NETWORK_STATS, 6051 dev_name, 6052 data->apn_data_stats_list[apn_index].num_ul_packets, 6053 data->apn_data_stats_list[apn_index].num_ul_bytes, 6054 data->apn_data_stats_list[apn_index].num_dl_packets, 6055 data->apn_data_stats_list[apn_index].num_dl_bytes); 6056 fclose(fp); 6057 break; 6058 }; 6059 } 6060 return IPACM_SUCCESS; 6061 } 6062 6063 int IPACM_Wan::add_dummy_rx_hdr() 6064 { 6065 6066 #define IFACE_INDEX_LEN 2 6067 char index[IFACE_INDEX_LEN]; 6068 struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL; 6069 int len = 0; 6070 struct ipa_ioc_copy_hdr sCopyHeader; 6071 struct ipa_hdr_add *ipv6_hdr; 6072 struct ethhdr *eth_ipv6; 6073 struct ipa_ioc_add_hdr_proc_ctx* pHeaderProcTable = NULL; 6074 uint32_t cnt; 6075 6076 /* get netdev-mac */ 6077 if(tx_prop != NULL) 6078 { 6079 /* copy partial header for v6 */ 6080 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++) 6081 { 6082 if(tx_prop->tx[cnt].ip==IPA_IP_v6) 6083 { 6084 IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt); 6085 memset(&sCopyHeader, 0, sizeof(sCopyHeader)); 6086 memcpy(sCopyHeader.name, 6087 tx_prop->tx[cnt].hdr_name, 6088 sizeof(sCopyHeader.name)); 6089 6090 IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt); 6091 if (m_header.CopyHeader(&sCopyHeader) == false) 6092 { 6093 PERROR("ioctl copy header failed"); 6094 return IPACM_FAILURE; 6095 } 6096 6097 IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); 6098 IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); 6099 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) 6100 { 6101 IPACMERR("header oversize\n"); 6102 return IPACM_FAILURE; 6103 } 6104 else 6105 { 6106 /* copy client mac_addr to partial header */ 6107 IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", 6108 sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); 6109 /* only copy 6 bytes mac-address */ 6110 if(sCopyHeader.is_eth2_ofst_valid == false) 6111 { 6112 memcpy(netdev_mac, &sCopyHeader.hdr[0+IPA_MAC_ADDR_SIZE], 6113 sizeof(netdev_mac)); 6114 } 6115 else 6116 { 6117 memcpy(netdev_mac, &sCopyHeader.hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE], 6118 sizeof(netdev_mac)); 6119 } 6120 } 6121 break; 6122 } 6123 } 6124 } 6125 6126 len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add)); 6127 pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len); 6128 if (pHeaderDescriptor == NULL) 6129 { 6130 IPACMERR("calloc failed to allocate pHeaderDescriptor\n"); 6131 return IPACM_FAILURE; 6132 } 6133 ipv6_hdr = &pHeaderDescriptor->hdr[0]; 6134 /* copy ethernet type to header */ 6135 eth_ipv6 = (struct ethhdr *) (ipv6_hdr->hdr +2); 6136 memcpy(eth_ipv6->h_dest, netdev_mac, ETH_ALEN); 6137 memcpy(eth_ipv6->h_source, ext_router_mac_addr, ETH_ALEN); 6138 eth_ipv6->h_proto = htons(ETH_P_IPV6); 6139 pHeaderDescriptor->commit = true; 6140 pHeaderDescriptor->num_hdrs = 1; 6141 6142 memset(ipv6_hdr->name, 0, 6143 sizeof(pHeaderDescriptor->hdr[0].name)); 6144 6145 snprintf(index,sizeof(index), "%d", ipa_if_num); 6146 strlcpy(ipv6_hdr->name, index, sizeof(ipv6_hdr->name)); 6147 ipv6_hdr->name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 6148 6149 if (strlcat(ipv6_hdr->name, IPA_DUMMY_ETH_HDR_NAME_v6, sizeof(ipv6_hdr->name)) > IPA_RESOURCE_NAME_MAX) 6150 { 6151 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(ipv6_hdr->name)); 6152 return IPACM_FAILURE; 6153 } 6154 6155 ipv6_hdr->hdr_len = ETH_HLEN + 2; 6156 ipv6_hdr->hdr_hdl = -1; 6157 ipv6_hdr->is_partial = 0; 6158 ipv6_hdr->status = -1; 6159 ipv6_hdr->type = IPA_HDR_L2_ETHERNET_II; 6160 6161 if (m_header.AddHeader(pHeaderDescriptor) == false || 6162 ipv6_hdr->status != 0) 6163 { 6164 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", ipv6_hdr->status); 6165 return IPACM_FAILURE; 6166 } 6167 6168 hdr_hdl_dummy_v6 = ipv6_hdr->hdr_hdl; 6169 IPACMDBG_H("dummy v6 full header name:%s header handle:(0x%x)\n", 6170 ipv6_hdr->name, 6171 hdr_hdl_dummy_v6); 6172 /* add dummy hdr_proc_hdl */ 6173 len = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_add); 6174 pHeaderProcTable = (ipa_ioc_add_hdr_proc_ctx*)malloc(len); 6175 if(pHeaderProcTable == NULL) 6176 { 6177 IPACMERR("Cannot allocate header processing table.\n"); 6178 return IPACM_FAILURE; 6179 } 6180 6181 memset(pHeaderProcTable, 0, len); 6182 pHeaderProcTable->commit = 1; 6183 pHeaderProcTable->num_proc_ctxs = 1; 6184 pHeaderProcTable->proc_ctx[0].hdr_hdl = hdr_hdl_dummy_v6; 6185 if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) 6186 { 6187 IPACMERR("Adding dummy hhdr_proc_hdl failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); 6188 return IPACM_FAILURE; 6189 } 6190 else 6191 { 6192 hdr_proc_hdl_dummy_v6 = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; 6193 IPACMDBG_H("dummy hhdr_proc_hdl is added successfully. (0x%x)\n", hdr_proc_hdl_dummy_v6); 6194 } 6195 return IPACM_SUCCESS; 6196 } 6197