1/* 2Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. 3 4Redistribution and use in source and binary forms, with or without 5modification, are permitted provided that the following conditions are 6met: 7* Redistributions of source code must retain the above copyright 8notice, this list of conditions and the following disclaimer. 9 10* Redistributions in binary form must reproduce the above 11copyright notice, this list of conditions and the following 12disclaimer in the documentation and/or other materials provided 13with the distribution. 14 15* Neither the name of The Linux Foundation nor the names of its 16contributors may be used to endorse or promote products derived 17from this software without specific prior written permission. 18 19THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 20WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 22ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 23BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 26BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 28OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 29IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*/ 31/*! 32 @file 33 IPACM_Lan.cpp 34 35 @brief 36 This file implements the LAN iface functionality. 37 38 @Author 39 Skylar Chang 40 41*/ 42#include <string.h> 43#include <fcntl.h> 44#include <sys/ioctl.h> 45#include "IPACM_Netlink.h" 46#include "IPACM_Lan.h" 47#include "IPACM_Wan.h" 48#include "IPACM_IfaceManager.h" 49#include "linux/rmnet_ipa_fd_ioctl.h" 50#include "linux/ipa_qmi_service_v01.h" 51#include "linux/msm_ipa.h" 52#include "IPACM_ConntrackListener.h" 53#include <sys/ioctl.h> 54#include <fcntl.h> 55#ifdef FEATURE_IPACM_HAL 56#include "IPACM_OffloadManager.h" 57#endif 58bool IPACM_Lan::odu_up = false; 59 60IPACM_Lan::IPACM_Lan(int iface_index) : IPACM_Iface(iface_index) 61{ 62 num_eth_client = 0; 63 header_name_count = 0; 64 ipv6_set = 0; 65 ipv4_header_set = false; 66 ipv6_header_set = false; 67 odu_route_rule_v4_hdl = NULL; 68 odu_route_rule_v6_hdl = NULL; 69 eth_client = NULL; 70 int m_fd_odu, ret = IPACM_SUCCESS; 71 uint32_t i; 72 73 Nat_App = NatApp::GetInstance(); 74 if (Nat_App == NULL) 75 { 76 IPACMERR("unable to get Nat App instance \n"); 77 return; 78 } 79 80 num_wan_ul_fl_rule_v4 = 0; 81 num_wan_ul_fl_rule_v6 = 0; 82 is_active = true; 83 modem_ul_v4_set = false; 84 modem_ul_v6_set = false; 85 is_mode_switch = false; 86 if_ipv4_subnet =0; 87 each_client_rt_rule_count[IPA_IP_v4] = 0; 88 each_client_rt_rule_count[IPA_IP_v6] = 0; 89 eth_client_len = 0; 90 91 /* support eth multiple clients */ 92 if(iface_query != NULL) 93 { 94 if(ipa_if_cate != WLAN_IF) 95 { 96 eth_client_len = (sizeof(ipa_eth_client)) + (iface_query->num_tx_props * sizeof(eth_client_rt_hdl)); 97 eth_client = (ipa_eth_client *)calloc(IPA_MAX_NUM_ETH_CLIENTS, eth_client_len); 98 if (eth_client == NULL) 99 { 100 IPACMERR("unable to allocate memory\n"); 101 return; 102 } 103 } 104 105 IPACMDBG_H(" IPACM->IPACM_Lan(%d) constructor: Tx:%d Rx:%d \n", ipa_if_num, 106 iface_query->num_tx_props, iface_query->num_rx_props); 107 108 /* ODU routing table initilization */ 109 if(ipa_if_cate == ODU_IF) 110 { 111 odu_route_rule_v4_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t)); 112 odu_route_rule_v6_hdl = (uint32_t *)calloc(iface_query->num_tx_props, sizeof(uint32_t)); 113 if ((odu_route_rule_v4_hdl == NULL) || (odu_route_rule_v6_hdl == NULL)) 114 { 115 IPACMERR("unable to allocate memory\n"); 116 return; 117 } 118 } 119 } 120 121 memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t)); 122 memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t)); 123 124 memset(ipv4_icmp_flt_rule_hdl, 0, NUM_IPV4_ICMP_FLT_RULE * sizeof(uint32_t)); 125 126 memset(private_fl_rule_hdl, 0, IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(uint32_t)); 127 memset(ipv6_prefix_flt_rule_hdl, 0, NUM_IPV6_PREFIX_FLT_RULE * sizeof(uint32_t)); 128 memset(ipv6_icmp_flt_rule_hdl, 0, NUM_IPV6_ICMP_FLT_RULE * sizeof(uint32_t)); 129 memset(ipv6_prefix, 0, sizeof(ipv6_prefix)); 130 131 /* ODU routing table initilization */ 132 if(ipa_if_cate == ODU_IF) 133 { 134 /* only do one time ioctl to odu-driver to infrom in router or bridge mode*/ 135 if (IPACM_Lan::odu_up != true) 136 { 137 m_fd_odu = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR); 138 if (0 == m_fd_odu) 139 { 140 IPACMERR("Failed opening %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU); 141 return ; 142 } 143 144 if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == true) 145 { 146 ret = ioctl(m_fd_odu, ODU_BRIDGE_IOC_SET_MODE, ODU_BRIDGE_MODE_ROUTER); 147 IPACM_Iface::ipacmcfg->ipacm_odu_enable = true; 148 } 149 else 150 { 151 ret = ioctl(m_fd_odu, ODU_BRIDGE_IOC_SET_MODE, ODU_BRIDGE_MODE_BRIDGE); 152 IPACM_Iface::ipacmcfg->ipacm_odu_enable = true; 153 } 154 155 if (ret) 156 { 157 IPACMERR("Failed tell odu-driver the mode\n"); 158 } 159 IPACMDBG("Tell odu-driver in router-mode(%d)\n", IPACM_Iface::ipacmcfg->ipacm_odu_router_mode); 160 IPACMDBG_H("odu is up: odu-driver in router-mode(%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_router_mode); 161 close(m_fd_odu); 162 IPACM_Lan::odu_up = true; 163 } 164 } 165 166 if(iface_query != NULL && tx_prop != NULL) 167 { 168 for(i=0; i<iface_query->num_tx_props; i++) 169 each_client_rt_rule_count[tx_prop->tx[i].ip]++; 170 } 171 IPACMDBG_H("Need to add %d IPv4 and %d IPv6 routing rules for eth bridge for each client.\n", each_client_rt_rule_count[IPA_IP_v4], each_client_rt_rule_count[IPA_IP_v6]); 172 173#ifdef FEATURE_IPA_ANDROID 174 /* set the IPA-client pipe enum */ 175 if(ipa_if_cate == LAN_IF) 176 { 177#ifdef FEATURE_IPACM_HAL 178 handle_tethering_client(false, IPACM_CLIENT_MAX); 179#else 180 handle_tethering_client(false, IPACM_CLIENT_USB); 181#endif 182 } 183#endif 184 185 memset(is_downstream_set, 0, sizeof(is_downstream_set)); 186 memset(is_upstream_set, 0, sizeof(is_upstream_set)); 187 memset(&prefix, 0, sizeof(prefix)); 188 189#ifdef FEATURE_IPACM_HAL 190 /* check if Upstream was set before */ 191 if (IPACM_Wan::isWanUP(ipa_if_num)) 192 { 193 IPACMDBG_H("Upstream was set previously for ipv4, change is_upstream_set flag\n"); 194 is_upstream_set[IPA_IP_v4] = true; 195 } 196 197 if (IPACM_Wan::isWanUP_V6(ipa_if_num)) 198 { 199 IPACMDBG_H("Upstream was set previously for ipv6, change is_upstream_set flag\n"); 200 is_upstream_set[IPA_IP_v6] = true; 201 } 202#endif 203 return; 204} 205 206IPACM_Lan::~IPACM_Lan() 207{ 208 IPACM_EvtDispatcher::deregistr(this); 209 IPACM_IfaceManager::deregistr(this); 210 return; 211} 212 213 214/* LAN-iface's callback function */ 215void IPACM_Lan::event_callback(ipa_cm_event_id event, void *param) 216{ 217 if(is_active == false && event != IPA_LAN_DELETE_SELF) 218 { 219 IPACMDBG_H("The interface is no longer active, return.\n"); 220 return; 221 } 222 223 int ipa_interface_index; 224 ipacm_ext_prop* ext_prop; 225 ipacm_event_iface_up_tehter* data_wan_tether; 226 227 switch (event) 228 { 229 case IPA_LINK_DOWN_EVENT: 230 { 231 ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; 232 ipa_interface_index = iface_ipa_index_query(data->if_index); 233 if (ipa_interface_index == ipa_if_num) 234 { 235 IPACMDBG_H("Received IPA_LINK_DOWN_EVENT\n"); 236 handle_down_evt(); 237 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface 238 return; 239 } 240 } 241 break; 242 243 case IPA_CFG_CHANGE_EVENT: 244 { 245 if ( IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].if_cat != ipa_if_cate) 246 { 247 IPACMDBG_H("Received IPA_CFG_CHANGE_EVENT and category changed\n"); 248 /* delete previous instance */ 249 handle_down_evt(); 250 IPACM_Iface::ipacmcfg->DelNatIfaces(dev_name); // delete NAT-iface 251 is_mode_switch = true; // need post internal usb-link up event 252 return; 253 } 254 /* Add Natting iface to IPACM_Config if there is Rx/Tx property */ 255 if (rx_prop != NULL || tx_prop != NULL) 256 { 257 IPACMDBG_H(" Has rx/tx properties registered for iface %s, add for NATTING \n", dev_name); 258 IPACM_Iface::ipacmcfg->AddNatIfaces(dev_name); 259 } 260 } 261 break; 262 263 case IPA_PRIVATE_SUBNET_CHANGE_EVENT: 264 { 265 ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; 266 /* internel event: data->if_index is ipa_if_index */ 267 if (data->if_index == ipa_if_num) 268 { 269 IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from itself posting, ignore\n"); 270 return; 271 } 272 else 273 { 274 IPACMDBG_H("Received IPA_PRIVATE_SUBNET_CHANGE_EVENT from other LAN iface \n"); 275#ifdef FEATURE_IPA_ANDROID 276 handle_private_subnet_android(IPA_IP_v4); 277#endif 278 IPACMDBG_H(" delete old private subnet rules, use new sets \n"); 279 return; 280 } 281 } 282 break; 283 284 case IPA_LAN_DELETE_SELF: 285 { 286 ipacm_event_data_fid *data = (ipacm_event_data_fid *)param; 287 if(data->if_index == ipa_if_num) 288 { 289 IPACMDBG_H("Received IPA_LAN_DELETE_SELF event.\n"); 290 IPACMDBG_H("ipa_LAN (%s):ipa_index (%d) instance close \n", IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name, ipa_if_num); 291 /* posting link-up event for cradle use-case */ 292 if(is_mode_switch) 293 { 294 IPACMDBG_H("Posting IPA_USB_LINK_UP_EVENT event for (%s)\n", dev_name); 295 ipacm_cmd_q_data evt_data; 296 memset(&evt_data, 0, sizeof(evt_data)); 297 298 ipacm_event_data_fid *data_fid = NULL; 299 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid)); 300 if(data_fid == NULL) 301 { 302 IPACMERR("unable to allocate memory for IPA_USB_LINK_UP_EVENT data_fid\n"); 303 return; 304 } 305 if(IPACM_Iface::ipa_get_if_index(dev_name, &(data_fid->if_index))) 306 { 307 IPACMERR("Error while getting interface index for %s device", dev_name); 308 } 309 evt_data.event = IPA_USB_LINK_UP_EVENT; 310 evt_data.evt_data = data_fid; 311 //IPACMDBG_H("Posting event:%d\n", evt_data.event); 312 IPACM_EvtDispatcher::PostEvt(&evt_data); 313 } 314#ifndef FEATURE_IPA_ANDROID 315 if(rx_prop != NULL) 316 { 317 if(IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4) != 0) 318 { 319 IPACMDBG_DMESG("### WARNING ### num ipv4 flt rules on client %d is not expected: %d expected value: 0", 320 rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4)); 321 } 322 if(IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6) != 0) 323 { 324 IPACMDBG_DMESG("### WARNING ### num ipv6 flt rules on client %d is not expected: %d expected value: 0", 325 rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6)); 326 } 327 } 328#endif 329 delete this; 330 } 331 break; 332 } 333 334 case IPA_ADDR_ADD_EVENT: 335 { 336 ipacm_event_data_addr *data = (ipacm_event_data_addr *)param; 337 ipa_interface_index = iface_ipa_index_query(data->if_index); 338 339 if ( (data->iptype == IPA_IP_v4 && data->ipv4_addr == 0) || 340 (data->iptype == IPA_IP_v6 && 341 data->ipv6_addr[0] == 0 && data->ipv6_addr[1] == 0 && 342 data->ipv6_addr[2] == 0 && data->ipv6_addr[3] == 0) ) 343 { 344 IPACMDBG_H("Invalid address, ignore IPA_ADDR_ADD_EVENT event\n"); 345 return; 346 } 347 348 349 if (ipa_interface_index == ipa_if_num) 350 { 351 IPACMDBG_H("Received IPA_ADDR_ADD_EVENT\n"); 352 353 /* only call ioctl for ODU iface with bridge mode */ 354 if(IPACM_Iface::ipacmcfg->ipacm_odu_enable == true && IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false 355 && ipa_if_cate == ODU_IF) 356 { 357 if((data->iptype == IPA_IP_v6) && (num_dft_rt_v6 == 0)) 358 { 359 handle_addr_evt_odu_bridge(data); 360 } 361#ifdef FEATURE_IPA_ANDROID 362 add_dummy_private_subnet_flt_rule(data->iptype); 363 handle_private_subnet_android(data->iptype); 364#else 365 handle_private_subnet(data->iptype); 366#endif 367 } 368 else 369 { 370 371 /* check v4 not setup before, v6 can have 2 iface ip */ 372 if( ((data->iptype != ip_type) && (ip_type != IPA_IP_MAX)) 373 || ((data->iptype==IPA_IP_v6) && (num_dft_rt_v6!=MAX_DEFAULT_v6_ROUTE_RULES))) 374 { 375 IPACMDBG_H("Got IPA_ADDR_ADD_EVENT ip-family:%d, v6 num %d: \n",data->iptype,num_dft_rt_v6); 376 if(handle_addr_evt(data) == IPACM_FAILURE) 377 { 378 return; 379 } 380 381#ifdef FEATURE_IPA_ANDROID 382 add_dummy_private_subnet_flt_rule(data->iptype); 383 handle_private_subnet_android(data->iptype); 384#else 385 handle_private_subnet(data->iptype); 386#endif 387 388#ifndef FEATURE_IPACM_HAL 389 if (IPACM_Wan::isWanUP(ipa_if_num)) 390 { 391 if(data->iptype == IPA_IP_v4 || data->iptype == IPA_IP_MAX) 392 { 393 if(IPACM_Wan::backhaul_is_sta_mode == false) 394 { 395 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4); 396 handle_wan_up_ex(ext_prop, IPA_IP_v4, 397 IPACM_Wan::getXlat_Mux_Id()); 398 } 399 else 400 { 401 handle_wan_up(IPA_IP_v4); 402 } 403 } 404 IPACMDBG_H("Finished checking wan_up\n"); 405 } else { 406 IPACMDBG_H("Wan_V4 haven't up yet\n"); 407 } 408 409 if(IPACM_Wan::isWanUP_V6(ipa_if_num)) 410 { 411 if((data->iptype == IPA_IP_v6 || data->iptype == IPA_IP_MAX) && num_dft_rt_v6 == 1) 412 { 413 memcpy(ipv6_prefix, IPACM_Wan::backhaul_ipv6_prefix, sizeof(ipv6_prefix)); 414 install_ipv6_prefix_flt_rule(IPACM_Wan::backhaul_ipv6_prefix); 415 if(IPACM_Wan::backhaul_is_sta_mode == false) 416 { 417 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6); 418 handle_wan_up_ex(ext_prop, IPA_IP_v6, 0); 419 } 420 else 421 { 422 handle_wan_up(IPA_IP_v6); 423 } 424 } 425 IPACMDBG_H("Finished checking wan_up_v6\n"); 426 } else { 427 IPACMDBG_H("Wan_V6 haven't up yet\n"); 428 } 429#endif 430 /* Post event to NAT */ 431 if (data->iptype == IPA_IP_v4) 432 { 433 ipacm_cmd_q_data evt_data; 434 ipacm_event_iface_up *info; 435 436 info = (ipacm_event_iface_up *) 437 malloc(sizeof(ipacm_event_iface_up)); 438 if (info == NULL) 439 { 440 IPACMERR("Unable to allocate memory\n"); 441 return; 442 } 443 444 memcpy(info->ifname, dev_name, IF_NAME_LEN); 445 info->ipv4_addr = data->ipv4_addr; 446 info->addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[0].subnet_mask; 447 448 evt_data.event = IPA_HANDLE_LAN_UP; 449 evt_data.evt_data = (void *)info; 450 451 /* Insert IPA_HANDLE_LAN_UP to command queue */ 452 IPACMDBG_H("posting IPA_HANDLE_LAN_UP for IPv4 with below information\n"); 453 IPACMDBG_H("IPv4 address:0x%x, IPv4 address mask:0x%x\n", 454 info->ipv4_addr, info->addr_mask); 455 IPACM_EvtDispatcher::PostEvt(&evt_data); 456 } 457 IPACMDBG_H("Finish handling IPA_ADDR_ADD_EVENT for ip-family(%d)\n", data->iptype); 458 } 459 460 IPACMDBG_H("Finish handling IPA_ADDR_ADD_EVENT for ip-family(%d)\n", data->iptype); 461 /* checking if SW-RT_enable */ 462 if (IPACM_Iface::ipacmcfg->ipa_sw_rt_enable == true) 463 { 464 /* handle software routing enable event*/ 465 IPACMDBG_H("IPA_SW_ROUTING_ENABLE for iface: %s \n",IPACM_Iface::ipacmcfg->iface_table[ipa_if_num].iface_name); 466 handle_software_routing_enable(); 467 } 468 469 } 470 } 471 } 472 break; 473#ifdef FEATURE_IPA_ANDROID 474 case IPA_HANDLE_WAN_UP_TETHER: 475 IPACMDBG_H("Received IPA_HANDLE_WAN_UP_TETHER event\n"); 476 477 data_wan_tether = (ipacm_event_iface_up_tehter*)param; 478 if(data_wan_tether == NULL) 479 { 480 IPACMERR("No event data is found.\n"); 481 return; 482 } 483 IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta, 484 data_wan_tether->if_index_tether, 485 IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name); 486#ifndef FEATURE_IPACM_HAL 487 if (data_wan_tether->if_index_tether != ipa_if_num) 488 { 489 IPACMERR("IPA_HANDLE_WAN_UP_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num); 490 return; 491 } 492#endif 493 if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) 494 { 495#ifdef FEATURE_IPACM_HAL 496 if (is_upstream_set[IPA_IP_v4] == false) 497 { 498 IPACMDBG_H("Add upstream for IPv4.\n"); 499 is_upstream_set[IPA_IP_v4] = true; 500 if (is_downstream_set[IPA_IP_v4] == true) 501 { 502 IPACMDBG_H("Downstream was set before, adding UL rules.\n"); 503 if (data_wan_tether->is_sta == false) 504 { 505 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4); 506 handle_wan_up_ex(ext_prop, IPA_IP_v4, 0); 507 } else { 508 handle_wan_up(IPA_IP_v4); 509 } 510 } 511 } 512#else 513 if (data_wan_tether->is_sta == false) 514 { 515 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4); 516 handle_wan_up_ex(ext_prop, IPA_IP_v4, 0); 517 } else { 518 handle_wan_up(IPA_IP_v4); 519 } 520#endif 521 } 522 break; 523 524 case IPA_HANDLE_WAN_UP_V6_TETHER: 525 IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6_TETHER event\n"); 526 527 data_wan_tether = (ipacm_event_iface_up_tehter*)param; 528 if (data_wan_tether == NULL) 529 { 530 IPACMERR("No event data is found.\n"); 531 return; 532 } 533 IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta, 534 data_wan_tether->if_index_tether, 535 IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name); 536#ifndef FEATURE_IPACM_HAL 537 if (data_wan_tether->if_index_tether != ipa_if_num) 538 { 539 IPACMERR("IPA_HANDLE_WAN_UP_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num); 540 return; 541 } 542#endif 543 if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) 544 { 545#ifdef FEATURE_IPACM_HAL 546 if (is_upstream_set[IPA_IP_v6] == false) 547 { 548 IPACMDBG_H("Add upstream for IPv6.\n"); 549 is_upstream_set[IPA_IP_v6] = true; 550 551 if (is_downstream_set[IPA_IP_v6] == true) 552 { 553 IPACMDBG_H("Downstream was set before, adding UL rules.\n"); 554 memcpy(ipv6_prefix, data_wan_tether->ipv6_prefix, sizeof(ipv6_prefix)); 555 install_ipv6_prefix_flt_rule(data_wan_tether->ipv6_prefix); 556 if (data_wan_tether->is_sta == false) 557 { 558 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6); 559 handle_wan_up_ex(ext_prop, IPA_IP_v6, 0); 560 } 561 else 562 { 563 handle_wan_up(IPA_IP_v6); 564 } 565 } 566 } 567#else 568 if (data_wan_tether->is_sta == false) 569 { 570 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6); 571 handle_wan_up_ex(ext_prop, IPA_IP_v6, 0); 572 } else { 573 handle_wan_up(IPA_IP_v6); 574 } 575#endif 576 } 577 break; 578 579 case IPA_HANDLE_WAN_DOWN_TETHER: 580 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_TETHER event\n"); 581 data_wan_tether = (ipacm_event_iface_up_tehter*)param; 582 if (data_wan_tether == NULL) 583 { 584 IPACMERR("No event data is found.\n"); 585 return; 586 } 587 IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta, 588 data_wan_tether->if_index_tether, 589 IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name); 590#ifndef FEATURE_IPACM_HAL 591 if (data_wan_tether->if_index_tether != ipa_if_num) 592 { 593 IPACMERR("IPA_HANDLE_WAN_DOWN_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num); 594 return; 595 } 596#endif 597 if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) 598 { 599#ifdef FEATURE_IPACM_HAL 600 if(is_upstream_set[IPA_IP_v4] == true) 601 { 602 IPACMDBG_H("Del upstream for IPv4.\n"); 603 is_upstream_set[IPA_IP_v4] = false; 604 if(is_downstream_set[IPA_IP_v4] == true) 605 { 606 IPACMDBG_H("Downstream was set before, deleting UL rules.\n"); 607 handle_wan_down(data_wan_tether->is_sta); 608 } 609 } 610#else 611 handle_wan_down(data_wan_tether->is_sta); 612#endif 613 } 614 break; 615 616 case IPA_HANDLE_WAN_DOWN_V6_TETHER: 617 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6_TETHER event\n"); 618 data_wan_tether = (ipacm_event_iface_up_tehter*)param; 619 if(data_wan_tether == NULL) 620 { 621 IPACMERR("No event data is found.\n"); 622 return; 623 } 624 IPACMDBG_H("Backhaul is sta mode?%d, if_index_tether:%d tether_if_name:%s\n", data_wan_tether->is_sta, 625 data_wan_tether->if_index_tether, 626 IPACM_Iface::ipacmcfg->iface_table[data_wan_tether->if_index_tether].iface_name); 627#ifndef FEATURE_IPACM_HAL 628 if (data_wan_tether->if_index_tether != ipa_if_num) 629 { 630 IPACMERR("IPA_HANDLE_WAN_DOWN_V6_TETHER tether_if(%d), not valid (%d) ignore\n", data_wan_tether->if_index_tether, ipa_if_num); 631 return; 632 } 633#endif 634 if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) 635 { 636#ifdef FEATURE_IPACM_HAL 637 if (is_upstream_set[IPA_IP_v6] == true) 638 { 639 IPACMDBG_H("Del upstream for IPv6.\n"); 640 is_upstream_set[IPA_IP_v6] = false; 641 if(is_downstream_set[IPA_IP_v6] == true) 642 { 643 IPACMDBG_H("Downstream was set before, deleting UL rules.\n"); 644 /* reset usb-client ipv6 rt-rules */ 645 handle_lan_client_reset_rt(IPA_IP_v6); 646 handle_wan_down_v6(data_wan_tether->is_sta); 647 } 648 } 649#else 650 /* reset usb-client ipv6 rt-rules */ 651 handle_lan_client_reset_rt(IPA_IP_v6); 652 handle_wan_down_v6(data_wan_tether->is_sta); 653#endif 654 } 655 break; 656 657 case IPA_DOWNSTREAM_ADD: 658 { 659 ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param; 660 ipa_interface_index = iface_ipa_index_query(data->if_index); 661 if (ipa_interface_index == ipa_if_num) 662 { 663 IPACMDBG_H("Received IPA_DOWNSTREAM_ADD event.\n"); 664 if (is_downstream_set[data->prefix.iptype] == false) 665 { 666 IPACMDBG_H("Add downstream for IP iptype %d\n", data->prefix.iptype); 667 is_downstream_set[data->prefix.iptype] = true; 668 memcpy(&prefix[data->prefix.iptype], &data->prefix, 669 sizeof(prefix[data->prefix.iptype])); 670 671 if (is_upstream_set[data->prefix.iptype] == true) 672 { 673 IPACMDBG_H("Upstream was set before, adding UL rules.\n"); 674 if (ip_type == IPA_IP_MAX || ip_type == data->prefix.iptype) 675 { 676 if (data->prefix.iptype == IPA_IP_v6) /* ipv6 only */ 677 { 678 /* Only offload clients has same prefix as Android gave */ 679 ipv6_prefix[0] = data->prefix.v6Addr[0]; 680 ipv6_prefix[1] = data->prefix.v6Addr[1]; 681 IPACMDBG_H("ipv6_prefix0x%x:%x\n", ipv6_prefix[0], ipv6_prefix[1]); 682 install_ipv6_prefix_flt_rule(ipv6_prefix); 683 } 684 685 if (IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */ 686 { 687 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(data->prefix.iptype); 688 handle_wan_up_ex(ext_prop, data->prefix.iptype, 0); 689 } else { 690 handle_wan_up(data->prefix.iptype); /* STA */ 691 } 692 } 693 } 694 } else { 695 IPACMDBG_H("downstream for IP iptype %d already set \n", data->prefix.iptype); 696 } 697 } 698 break; 699 } 700 701 case IPA_DOWNSTREAM_DEL: 702 { 703 ipacm_event_ipahal_stream *data = (ipacm_event_ipahal_stream *)param; 704 ipa_interface_index = iface_ipa_index_query(data->if_index); 705 if (ipa_interface_index == ipa_if_num) 706 { 707 IPACMDBG_H("Received IPA_DOWNSTREAM_DEL event.\n"); 708 if (is_downstream_set[data->prefix.iptype] == true) 709 { 710 IPACMDBG_H("Del downstream for IP iptype %d.\n", data->prefix.iptype); 711 is_downstream_set[data->prefix.iptype] = false; 712 713 if (is_upstream_set[data->prefix.iptype] == true) 714 { 715 IPACMDBG_H("Upstream was set before, deleting UL rules.\n"); 716 if (data->prefix.iptype == IPA_IP_v4) 717 { 718 handle_wan_down(IPACM_Wan::backhaul_is_sta_mode); /* LTE STA */ 719 } else { 720 handle_lan_client_reset_rt(IPA_IP_v6); 721 handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode); /* LTE STA */ 722 } 723 } 724 } 725 } 726 break; 727 } 728 729#else 730 case IPA_HANDLE_WAN_UP: 731 IPACMDBG_H("Received IPA_HANDLE_WAN_UP event\n"); 732 733 ipacm_event_iface_up* data_wan = (ipacm_event_iface_up*)param; 734 if (data_wan == NULL) 735 { 736 IPACMERR("No event data is found.\n"); 737 return; 738 } 739 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); 740 if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) 741 { 742 if (data_wan->is_sta == false) 743 { 744 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v4); 745 handle_wan_up_ex(ext_prop, IPA_IP_v4, data_wan->xlat_mux_id); 746 } 747 else 748 { 749 handle_wan_up(IPA_IP_v4); 750 } 751 } 752 break; 753 754 case IPA_HANDLE_WAN_UP_V6: 755 IPACMDBG_H("Received IPA_HANDLE_WAN_UP_V6 event\n"); 756 757 data_wan = (ipacm_event_iface_up*)param; 758 if (data_wan == NULL) 759 { 760 IPACMERR("No event data is found.\n"); 761 return; 762 } 763 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); 764 if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) 765 { 766 memcpy(ipv6_prefix, data_wan->ipv6_prefix, sizeof(ipv6_prefix)); 767 install_ipv6_prefix_flt_rule(data_wan->ipv6_prefix); 768 if (data_wan->is_sta == false) 769 { 770 ext_prop = IPACM_Iface::ipacmcfg->GetExtProp(IPA_IP_v6); 771 handle_wan_up_ex(ext_prop, IPA_IP_v6, 0); 772 } 773 else 774 { 775 handle_wan_up(IPA_IP_v6); 776 } 777 } 778 break; 779 780 case IPA_HANDLE_WAN_DOWN: 781 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN event\n"); 782 data_wan = (ipacm_event_iface_up*)param; 783 if (data_wan == NULL) 784 { 785 IPACMERR("No event data is found.\n"); 786 return; 787 } 788 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); 789 if (ip_type == IPA_IP_v4 || ip_type == IPA_IP_MAX) 790 { 791 handle_wan_down(data_wan->is_sta); 792 } 793 break; 794 795 case IPA_HANDLE_WAN_DOWN_V6: 796 IPACMDBG_H("Received IPA_HANDLE_WAN_DOWN_V6 event\n"); 797 data_wan = (ipacm_event_iface_up*)param; 798 if (data_wan == NULL) 799 { 800 IPACMERR("No event data is found.\n"); 801 return; 802 } 803 /* clean up v6 RT rules*/ 804 IPACMDBG_H("Received IPA_WAN_V6_DOWN in LAN-instance and need clean up client IPv6 address \n"); 805 /* reset usb-client ipv6 rt-rules */ 806 handle_lan_client_reset_rt(IPA_IP_v6); 807 808 IPACMDBG_H("Backhaul is sta mode?%d\n", data_wan->is_sta); 809 if (ip_type == IPA_IP_v6 || ip_type == IPA_IP_MAX) 810 { 811 handle_wan_down_v6(data_wan->is_sta); 812 } 813 break; 814#endif 815 816 case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT: 817 { 818 ipacm_event_data_all *data = (ipacm_event_data_all *)param; 819 ipa_interface_index = iface_ipa_index_query(data->if_index); 820 IPACMDBG_H("Recieved IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT event \n"); 821 IPACMDBG_H("check iface %s category: %d\n", dev_name, ipa_if_cate); 822 823 if (ipa_interface_index == ipa_if_num && ipa_if_cate == ODU_IF) 824 { 825 IPACMDBG_H("ODU iface got v4-ip \n"); 826 /* first construc ODU full header */ 827 if ((ipv4_header_set == false) && (ipv6_header_set == false)) 828 { 829 /* construct ODU RT tbl */ 830 handle_odu_hdr_init(data->mac_addr); 831 if (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true) 832 { 833 handle_odu_route_add(); 834 IPACMDBG_H("construct ODU header and route rules, embms_flag (%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable); 835 } 836 else 837 { 838 IPACMDBG_H("construct ODU header only, embms_flag (%d) \n", IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable); 839 } 840 } 841 /* if ODU in bridge mode, directly return */ 842 if(IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false) 843 { 844 IPACMDBG_H("ODU is in bridge mode, no action \n"); 845 return; 846 } 847 } 848 849 if (ipa_interface_index == ipa_if_num) 850 { 851 IPACMDBG_H("ETH iface got client \n"); 852 /* first construc ETH full header */ 853 handle_eth_hdr_init(data->mac_addr); 854 IPACMDBG_H("construct ETH header and route rules \n"); 855 /* Associate with IP and construct RT-rule */ 856 if (handle_eth_client_ipaddr(data) == IPACM_FAILURE) 857 { 858 return; 859 } 860 handle_eth_client_route_rule(data->mac_addr, data->iptype); 861 if (data->iptype == IPA_IP_v4) 862 { 863 /* Add NAT rules after ipv4 RT rules are set */ 864 CtList->HandleNeighIpAddrAddEvt(data); 865 } 866 eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_ADD, IPA_IP_MAX, data->mac_addr); 867 return; 868 } 869 } 870 break; 871 872 case IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT: 873 { 874 ipacm_event_data_all *data = (ipacm_event_data_all *)param; 875 ipa_interface_index = iface_ipa_index_query(data->if_index); 876 877 IPACMDBG_H("Received IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT event. \n"); 878 IPACMDBG_H("check iface %s category: %d\n", dev_name, ipa_if_cate); 879 /* if ODU in bridge mode, directly return */ 880 if (ipa_if_cate == ODU_IF && IPACM_Iface::ipacmcfg->ipacm_odu_router_mode == false) 881 { 882 IPACMDBG_H("ODU is in bridge mode, no action \n"); 883 return; 884 } 885 886 if (ipa_interface_index == ipa_if_num) 887 { 888 if (data->iptype == IPA_IP_v6) 889 { 890 handle_del_ipv6_addr(data); 891 return; 892 } 893 894 eth_bridge_post_event(IPA_ETH_BRIDGE_CLIENT_DEL, IPA_IP_MAX, data->mac_addr); 895 896 IPACMDBG_H("LAN iface delete client \n"); 897 handle_eth_client_down_evt(data->mac_addr); 898 return; 899 } 900 } 901 break; 902 903 case IPA_SW_ROUTING_ENABLE: 904 IPACMDBG_H("Received IPA_SW_ROUTING_ENABLE\n"); 905 /* handle software routing enable event*/ 906 handle_software_routing_enable(); 907 break; 908 909 case IPA_SW_ROUTING_DISABLE: 910 IPACMDBG_H("Received IPA_SW_ROUTING_DISABLE\n"); 911 /* handle software routing disable event*/ 912 handle_software_routing_disable(); 913 break; 914 915 case IPA_CRADLE_WAN_MODE_SWITCH: 916 { 917 IPACMDBG_H("Received IPA_CRADLE_WAN_MODE_SWITCH event.\n"); 918 ipacm_event_cradle_wan_mode* wan_mode = (ipacm_event_cradle_wan_mode*)param; 919 if(wan_mode == NULL) 920 { 921 IPACMERR("Event data is empty.\n"); 922 return; 923 } 924 925 if(wan_mode->cradle_wan_mode == BRIDGE) 926 { 927 handle_cradle_wan_mode_switch(true); 928 } 929 else 930 { 931 handle_cradle_wan_mode_switch(false); 932 } 933 } 934 break; 935 936 case IPA_TETHERING_STATS_UPDATE_EVENT: 937 { 938 IPACMDBG_H("Received IPA_TETHERING_STATS_UPDATE_EVENT event.\n"); 939 if (IPACM_Wan::isWanUP(ipa_if_num) || IPACM_Wan::isWanUP_V6(ipa_if_num)) 940 { 941 if(IPACM_Wan::backhaul_is_sta_mode == false) /* LTE */ 942 { 943 ipa_get_data_stats_resp_msg_v01 *data = (ipa_get_data_stats_resp_msg_v01 *)param; 944 IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data->ipa_stats_type); 945 IPACMDBG("Received %d UL, %d DL pipe stats\n",data->ul_src_pipe_stats_list_len, 946 data->dl_dst_pipe_stats_list_len); 947 if (data->ipa_stats_type != QMI_IPA_STATS_TYPE_PIPE_V01) 948 { 949 IPACMERR("not valid pipe stats enum(%d)\n", data->ipa_stats_type); 950 return; 951 } 952 handle_tethering_stats_event(data); 953 } 954 } 955 } 956 break; 957 958 default: 959 break; 960 } 961 962 return; 963} 964 965 966int IPACM_Lan::handle_del_ipv6_addr(ipacm_event_data_all *data) 967{ 968 uint32_t tx_index; 969 uint32_t rt_hdl; 970 int num_v6 =0, clnt_indx; 971 972 clnt_indx = get_eth_client_index(data->mac_addr); 973 if (clnt_indx == IPACM_INVALID_INDEX) 974 { 975 IPACMERR("eth client not found/attached \n"); 976 return IPACM_FAILURE; 977 } 978 979 if(data->iptype == IPA_IP_v6) 980 { 981 if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) || 982 (data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0)) 983 { 984 IPACMDBG_H("ipv6 address got: 0x%x:%x:%x:%x\n", data->ipv6_addr[0], data->ipv6_addr[1], data->ipv6_addr[2], data->ipv6_addr[3]); 985 for(num_v6=0;num_v6 < get_client_memptr(eth_client, clnt_indx)->ipv6_set;num_v6++) 986 { 987 if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][0] && 988 data->ipv6_addr[1] == get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][1] && 989 data->ipv6_addr[2]== get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][2] && 990 data->ipv6_addr[3] == get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][3]) 991 { 992 IPACMDBG_H("ipv6 addr is found at position:%d for client:%d\n", num_v6, clnt_indx); 993 break; 994 } 995 } 996 } 997 else 998 { 999 IPACMDBG_H("Invalid ipv6 address\n"); 1000 return IPACM_FAILURE; 1001 } 1002 if (num_v6 == IPV6_NUM_ADDR) 1003 { 1004 IPACMDBG_H("ipv6 addr is not found. \n"); 1005 return IPACM_FAILURE; 1006 } 1007 1008 for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) 1009 { 1010 if((tx_prop->tx[tx_index].ip == IPA_IP_v6) && (get_client_memptr(eth_client, clnt_indx)->route_rule_set_v6 != 0)) 1011 { 1012 IPACMDBG_H("Delete client index %d ipv6 RT-rules for %d-st ipv6 for tx:%d\n", clnt_indx, num_v6, tx_index); 1013 rt_hdl = get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6]; 1014 if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false) 1015 { 1016 return IPACM_FAILURE; 1017 } 1018 rt_hdl = get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6]; 1019 if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false) 1020 { 1021 return IPACM_FAILURE; 1022 } 1023 get_client_memptr(eth_client, clnt_indx)->ipv6_set--; 1024 get_client_memptr(eth_client, clnt_indx)->route_rule_set_v6--; 1025 1026 for(;num_v6< get_client_memptr(eth_client, clnt_indx)->ipv6_set;num_v6++) 1027 { 1028 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][0] = 1029 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][0]; 1030 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][1] = 1031 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][1]; 1032 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][2] = 1033 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][2]; 1034 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6][3] = 1035 get_client_memptr(eth_client, clnt_indx)->v6_addr[num_v6+1][3]; 1036 get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6] = 1037 get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6+1]; 1038 get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6] = 1039 get_client_memptr(eth_client, clnt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6+1]; 1040 } 1041 } 1042 } 1043 } 1044 return IPACM_SUCCESS; 1045} 1046 1047/* delete filter rule for wan_down event for IPv4*/ 1048int IPACM_Lan::handle_wan_down(bool is_sta_mode) 1049{ 1050 ipa_fltr_installed_notif_req_msg_v01 flt_index; 1051 int fd; 1052 1053 fd = open(IPA_DEVICE_NAME, O_RDWR); 1054 if (0 == fd) 1055 { 1056 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); 1057 return IPACM_FAILURE; 1058 } 1059 1060 if(is_sta_mode == false && modem_ul_v4_set == true) 1061 { 1062 if (num_wan_ul_fl_rule_v4 > MAX_WAN_UL_FILTER_RULES) 1063 { 1064 IPACMERR("number of wan_ul_fl_rule_v4 (%d) > MAX_WAN_UL_FILTER_RULES (%d), aborting...\n", num_wan_ul_fl_rule_v4, MAX_WAN_UL_FILTER_RULES); 1065 close(fd); 1066 return IPACM_FAILURE; 1067 } 1068 if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v4, 1069 IPA_IP_v4, num_wan_ul_fl_rule_v4) == false) 1070 { 1071 IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n"); 1072 close(fd); 1073 return IPACM_FAILURE; 1074 } 1075 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, num_wan_ul_fl_rule_v4); 1076 1077 memset(wan_ul_fl_rule_hdl_v4, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t)); 1078 num_wan_ul_fl_rule_v4 = 0; 1079 modem_ul_v4_set = false; 1080 1081 memset(&flt_index, 0, sizeof(flt_index)); 1082 flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe); 1083 flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01; 1084#ifndef FEATURE_IPA_V3 1085 flt_index.filter_index_list_len = 0; 1086#else /* defined (FEATURE_IPA_V3) */ 1087 flt_index.rule_id_valid = 1; 1088 flt_index.rule_id_len = 0; 1089#endif 1090 flt_index.embedded_pipe_index_valid = 1; 1091 flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD); 1092 flt_index.retain_header_valid = 1; 1093 flt_index.retain_header = 0; 1094 flt_index.embedded_call_mux_id_valid = 1; 1095 flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId(); 1096 1097 if(false == m_filtering.SendFilteringRuleIndex(&flt_index)) 1098 { 1099 IPACMERR("Error sending filtering rule index, aborting...\n"); 1100 close(fd); 1101 return IPACM_FAILURE; 1102 } 1103 } 1104 else 1105 { 1106 if (m_filtering.DeleteFilteringHdls(&lan_wan_fl_rule_hdl[0], IPA_IP_v4, 1) == false) 1107 { 1108 IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n"); 1109 close(fd); 1110 return IPACM_FAILURE; 1111 } 1112 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1); 1113 } 1114 1115 close(fd); 1116 return IPACM_SUCCESS; 1117} 1118 1119/* handle new_address event*/ 1120int IPACM_Lan::handle_addr_evt(ipacm_event_data_addr *data) 1121{ 1122 struct ipa_ioc_add_rt_rule *rt_rule; 1123 struct ipa_rt_rule_add *rt_rule_entry; 1124 const int NUM_RULES = 1; 1125 uint32_t num_ipv6_addr; 1126 int res = IPACM_SUCCESS; 1127#ifdef FEATURE_IPACM_HAL 1128 IPACM_OffloadManager* OffloadMng; 1129#endif 1130 1131 IPACMDBG_H("set route/filter rule ip-type: %d \n", data->iptype); 1132 1133/* Add private subnet*/ 1134#ifdef FEATURE_IPA_ANDROID 1135 if (data->iptype == IPA_IP_v4) 1136 { 1137 IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet); 1138 if_ipv4_subnet = (data->ipv4_addr >> 8) << 8; 1139 IPACMDBG_H(" Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); 1140 if(IPACM_Iface::ipacmcfg->AddPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false) 1141 { 1142 IPACMERR(" can't Add IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); 1143 } 1144 } 1145#endif /* defined(FEATURE_IPA_ANDROID)*/ 1146 1147 /* Update the IP Type. */ 1148 config_ip_type(data->iptype); 1149 1150 if (data->iptype == IPA_IP_v4) 1151 { 1152 rt_rule = (struct ipa_ioc_add_rt_rule *) 1153 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + 1154 NUM_RULES * sizeof(struct ipa_rt_rule_add)); 1155 1156 if (!rt_rule) 1157 { 1158 IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n"); 1159 return IPACM_FAILURE; 1160 } 1161 1162 rt_rule->commit = 1; 1163 rt_rule->num_rules = NUM_RULES; 1164 rt_rule->ip = data->iptype; 1165 rt_rule_entry = &rt_rule->rules[0]; 1166 rt_rule_entry->at_rear = false; 1167 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; //go to A5 1168 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; 1169 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, sizeof(rt_rule->rt_tbl_name)); 1170 rt_rule_entry->rule.attrib.u.v4.dst_addr = data->ipv4_addr; 1171 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; 1172#ifdef FEATURE_IPA_V3 1173 rt_rule_entry->rule.hashable = true; 1174#endif 1175 if (false == m_routing.AddRoutingRule(rt_rule)) 1176 { 1177 IPACMERR("Routing rule addition failed!\n"); 1178 res = IPACM_FAILURE; 1179 goto fail; 1180 } 1181 else if (rt_rule_entry->status) 1182 { 1183 IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status); 1184 res = rt_rule_entry->status; 1185 goto fail; 1186 } 1187 dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl; 1188 IPACMDBG_H("ipv4 iface rt-rule hdl1=0x%x\n", dft_rt_rule_hdl[0]); 1189 /* initial multicast/broadcast/fragment filter rule */ 1190 1191 init_fl_rule(data->iptype); 1192 install_ipv4_icmp_flt_rule(); 1193 1194 /* populate the flt rule offset for eth bridge */ 1195 eth_bridge_flt_rule_offset[data->iptype] = ipv4_icmp_flt_rule_hdl[0]; 1196 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v4, NULL); 1197 } 1198 else 1199 { 1200 /* check if see that v6-addr already or not*/ 1201 for(num_ipv6_addr=0;num_ipv6_addr<num_dft_rt_v6;num_ipv6_addr++) 1202 { 1203 if((ipv6_addr[num_ipv6_addr][0] == data->ipv6_addr[0]) && 1204 (ipv6_addr[num_ipv6_addr][1] == data->ipv6_addr[1]) && 1205 (ipv6_addr[num_ipv6_addr][2] == data->ipv6_addr[2]) && 1206 (ipv6_addr[num_ipv6_addr][3] == data->ipv6_addr[3])) 1207 { 1208 return IPACM_FAILURE; 1209 break; 1210 } 1211 } 1212 1213 rt_rule = (struct ipa_ioc_add_rt_rule *) 1214 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + 1215 NUM_RULES * sizeof(struct ipa_rt_rule_add)); 1216 1217 if (!rt_rule) 1218 { 1219 IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n"); 1220 return IPACM_FAILURE; 1221 } 1222 1223 rt_rule->commit = 1; 1224 rt_rule->num_rules = NUM_RULES; 1225 rt_rule->ip = data->iptype; 1226 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_v6.name, sizeof(rt_rule->rt_tbl_name)); 1227 1228 rt_rule_entry = &rt_rule->rules[0]; 1229 rt_rule_entry->at_rear = false; 1230 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; //go to A5 1231 rt_rule_entry->rule.attrib.attrib_mask = IPA_FLT_DST_ADDR; 1232 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = data->ipv6_addr[0]; 1233 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = data->ipv6_addr[1]; 1234 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = data->ipv6_addr[2]; 1235 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = data->ipv6_addr[3]; 1236 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; 1237 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; 1238 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; 1239 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; 1240 ipv6_addr[num_dft_rt_v6][0] = data->ipv6_addr[0]; 1241 ipv6_addr[num_dft_rt_v6][1] = data->ipv6_addr[1]; 1242 ipv6_addr[num_dft_rt_v6][2] = data->ipv6_addr[2]; 1243 ipv6_addr[num_dft_rt_v6][3] = data->ipv6_addr[3]; 1244#ifdef FEATURE_IPA_V3 1245 rt_rule_entry->rule.hashable = true; 1246#endif 1247 if (false == m_routing.AddRoutingRule(rt_rule)) 1248 { 1249 IPACMERR("Routing rule addition failed!\n"); 1250 res = IPACM_FAILURE; 1251 goto fail; 1252 } 1253 else if (rt_rule_entry->status) 1254 { 1255 IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status); 1256 res = rt_rule_entry->status; 1257 goto fail; 1258 } 1259 dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6] = rt_rule_entry->rt_rule_hdl; 1260 1261 /* setup same rule for v6_wan table*/ 1262 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name)); 1263 if (false == m_routing.AddRoutingRule(rt_rule)) 1264 { 1265 IPACMERR("Routing rule addition failed!\n"); 1266 res = IPACM_FAILURE; 1267 goto fail; 1268 } 1269 else if (rt_rule_entry->status) 1270 { 1271 IPACMERR("rt rule adding failed. Result=%d\n", rt_rule_entry->status); 1272 res = rt_rule_entry->status; 1273 goto fail; 1274 } 1275 dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1] = rt_rule_entry->rt_rule_hdl; 1276 1277 IPACMDBG_H("ipv6 wan iface rt-rule hdl=0x%x hdl=0x%x, num_dft_rt_v6: %d \n", 1278 dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6], 1279 dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + 2*num_dft_rt_v6+1],num_dft_rt_v6); 1280 1281 if (num_dft_rt_v6 == 0) 1282 { 1283 install_ipv6_icmp_flt_rule(); 1284 1285 /* populate the flt rule offset for eth bridge */ 1286 eth_bridge_flt_rule_offset[data->iptype] = ipv6_icmp_flt_rule_hdl[0]; 1287 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_UP, IPA_IP_v6, NULL); 1288 1289 init_fl_rule(data->iptype); 1290 } 1291 num_dft_rt_v6++; 1292 IPACMDBG_H("number of default route rules %d\n", num_dft_rt_v6); 1293 } 1294 1295#ifdef FEATURE_IPACM_HAL 1296 /* check if having pending add_downstream cache*/ 1297 OffloadMng = IPACM_OffloadManager::GetInstance(); 1298 if (OffloadMng == NULL) { 1299 IPACMERR("failed to get IPACM_OffloadManager instance !\n"); 1300 } else { 1301 IPACMDBG_H(" check iface %s if having add_downstream cache events\n", dev_name); 1302 OffloadMng->search_framwork_cache(dev_name); 1303 } 1304#endif 1305 1306 IPACMDBG_H("finish route/filter rule ip-type: %d, res(%d)\n", data->iptype, res); 1307 1308fail: 1309 free(rt_rule); 1310 return res; 1311} 1312 1313/* configure private subnet filter rules*/ 1314int IPACM_Lan::handle_private_subnet(ipa_ip_type iptype) 1315{ 1316 struct ipa_flt_rule_add flt_rule_entry; 1317 int i; 1318 1319 ipa_ioc_add_flt_rule *m_pFilteringTable; 1320 1321 IPACMDBG_H("lan->handle_private_subnet(); set route/filter rule \n"); 1322 1323 if (rx_prop == NULL) 1324 { 1325 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); 1326 return IPACM_SUCCESS; 1327 } 1328 1329 if (iptype == IPA_IP_v4) 1330 { 1331 1332 m_pFilteringTable = (struct ipa_ioc_add_flt_rule *) 1333 calloc(1, 1334 sizeof(struct ipa_ioc_add_flt_rule) + 1335 (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_add) 1336 ); 1337 if (!m_pFilteringTable) 1338 { 1339 PERROR("Error Locate ipa_flt_rule_add memory...\n"); 1340 return IPACM_FAILURE; 1341 } 1342 m_pFilteringTable->commit = 1; 1343 m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; 1344 m_pFilteringTable->global = false; 1345 m_pFilteringTable->ip = IPA_IP_v4; 1346 m_pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet; 1347 1348 /* Make LAN-traffic always go A5, use default IPA-RT table */ 1349 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4)) 1350 { 1351 IPACMERR("LAN m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_default_v4); 1352 free(m_pFilteringTable); 1353 return IPACM_FAILURE; 1354 } 1355 1356 for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++) 1357 { 1358 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 1359 flt_rule_entry.at_rear = true; 1360 flt_rule_entry.rule.retain_hdr = 1; 1361 flt_rule_entry.flt_rule_hdl = -1; 1362 flt_rule_entry.status = -1; 1363 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 1364#ifdef FEATURE_IPA_V3 1365 flt_rule_entry.rule.hashable = true; 1366#endif 1367 /* Support private subnet feature including guest-AP can't talk to primary AP etc */ 1368 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl; 1369 IPACMDBG_H(" private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name); 1370 1371 memcpy(&flt_rule_entry.rule.attrib, 1372 &rx_prop->rx[0].attrib, 1373 sizeof(flt_rule_entry.rule.attrib)); 1374 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 1375 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask; 1376 flt_rule_entry.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr; 1377 memcpy(&(m_pFilteringTable->rules[i]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 1378 IPACMDBG_H("Loop %d 5\n", i); 1379 } 1380 1381 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 1382 { 1383 IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); 1384 free(m_pFilteringTable); 1385 return IPACM_FAILURE; 1386 } 1387 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet); 1388 1389 /* copy filter rule hdls */ 1390 for (i = 0; i < IPACM_Iface::ipacmcfg->ipa_num_private_subnet; i++) 1391 { 1392 private_fl_rule_hdl[i] = m_pFilteringTable->rules[i].flt_rule_hdl; 1393 } 1394 free(m_pFilteringTable); 1395 } 1396 else 1397 { 1398 IPACMDBG_H("No private subnet rules for ipv6 iface %s\n", dev_name); 1399 } 1400 return IPACM_SUCCESS; 1401} 1402 1403 1404/* for STA mode wan up: configure filter rule for wan_up event*/ 1405int IPACM_Lan::handle_wan_up(ipa_ip_type ip_type) 1406{ 1407 struct ipa_flt_rule_add flt_rule_entry; 1408 int len = 0; 1409 ipa_ioc_add_flt_rule *m_pFilteringTable; 1410 1411 IPACMDBG_H("set WAN interface as default filter rule\n"); 1412 1413 if (rx_prop == NULL) 1414 { 1415 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); 1416 return IPACM_SUCCESS; 1417 } 1418 1419 if(ip_type == IPA_IP_v4) 1420 { 1421 len = sizeof(struct ipa_ioc_add_flt_rule) + (1 * sizeof(struct ipa_flt_rule_add)); 1422 m_pFilteringTable = (struct ipa_ioc_add_flt_rule *)calloc(1, len); 1423 if (m_pFilteringTable == NULL) 1424 { 1425 PERROR("Error Locate ipa_flt_rule_add memory...\n"); 1426 return IPACM_FAILURE; 1427 } 1428 1429 m_pFilteringTable->commit = 1; 1430 m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; 1431 m_pFilteringTable->global = false; 1432 m_pFilteringTable->ip = IPA_IP_v4; 1433 m_pFilteringTable->num_rules = (uint8_t)1; 1434 1435 IPACMDBG_H("Retrieving routing hanle for table: %s\n", 1436 IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name); 1437 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4)) 1438 { 1439 IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4=0x%p) Failed.\n", 1440 &IPACM_Iface::ipacmcfg->rt_tbl_wan_v4); 1441 free(m_pFilteringTable); 1442 return IPACM_FAILURE; 1443 } 1444 IPACMDBG_H("Routing hanle for table: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl); 1445 1446 1447 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); // Zero All Fields 1448 flt_rule_entry.at_rear = true; 1449 flt_rule_entry.flt_rule_hdl = -1; 1450 flt_rule_entry.status = -1; 1451 if(IPACM_Wan::isWan_Bridge_Mode()) 1452 { 1453 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 1454 } 1455 else 1456 { 1457 flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; //IPA_PASS_TO_ROUTING 1458 } 1459#ifdef FEATURE_IPA_V3 1460 flt_rule_entry.rule.hashable = true; 1461#endif 1462 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl; 1463 1464 memcpy(&flt_rule_entry.rule.attrib, 1465 &rx_prop->rx[0].attrib, 1466 sizeof(flt_rule_entry.rule.attrib)); 1467 1468 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 1469 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x0; 1470 flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x0; 1471 1472/* only offload UL traffic of certain clients */ 1473#ifdef FEATURE_IPACM_HAL 1474 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR; 1475 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = prefix[IPA_IP_v4].v4Mask; 1476 flt_rule_entry.rule.attrib.u.v4.dst_addr = prefix[IPA_IP_v4].v4Addr; 1477#endif 1478 memcpy(&m_pFilteringTable->rules[0], &flt_rule_entry, sizeof(flt_rule_entry)); 1479 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 1480 { 1481 IPACMERR("Error Adding RuleTable(0) to Filtering, aborting...\n"); 1482 free(m_pFilteringTable); 1483 return IPACM_FAILURE; 1484 } 1485 else 1486 { 1487 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1); 1488 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", 1489 m_pFilteringTable->rules[0].flt_rule_hdl, 1490 m_pFilteringTable->rules[0].status); 1491 } 1492 1493 1494 /* copy filter hdls */ 1495 lan_wan_fl_rule_hdl[0] = m_pFilteringTable->rules[0].flt_rule_hdl; 1496 free(m_pFilteringTable); 1497 } 1498 else if(ip_type == IPA_IP_v6) 1499 { 1500 /* add default v6 filter rule */ 1501 m_pFilteringTable = (struct ipa_ioc_add_flt_rule *) 1502 calloc(1, sizeof(struct ipa_ioc_add_flt_rule) + 1503 1 * sizeof(struct ipa_flt_rule_add)); 1504 1505 if (!m_pFilteringTable) 1506 { 1507 PERROR("Error Locate ipa_flt_rule_add memory...\n"); 1508 return IPACM_FAILURE; 1509 } 1510 1511 m_pFilteringTable->commit = 1; 1512 m_pFilteringTable->ep = rx_prop->rx[0].src_pipe; 1513 m_pFilteringTable->global = false; 1514 m_pFilteringTable->ip = IPA_IP_v6; 1515 m_pFilteringTable->num_rules = (uint8_t)1; 1516 1517 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_v6)) 1518 { 1519 IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_v6=0x%p) Failed.\n", &IPACM_Iface::ipacmcfg->rt_tbl_v6); 1520 free(m_pFilteringTable); 1521 return IPACM_FAILURE; 1522 } 1523 1524 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 1525 1526 flt_rule_entry.at_rear = true; 1527 flt_rule_entry.flt_rule_hdl = -1; 1528 flt_rule_entry.status = -1; 1529 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 1530#ifdef FEATURE_IPA_V3 1531 flt_rule_entry.rule.hashable = true; 1532#endif 1533 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_v6.hdl; 1534 1535 memcpy(&flt_rule_entry.rule.attrib, 1536 &rx_prop->rx[0].attrib, 1537 sizeof(flt_rule_entry.rule.attrib)); 1538 1539 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 1540 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0x00000000; 1541 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0x00000000; 1542 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x00000000; 1543 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x00000000; 1544 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = 0X00000000; 1545 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = 0x00000000; 1546 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x00000000; 1547 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0X00000000; 1548 1549/* only offload UL traffic of certain clients */ 1550#ifdef FEATURE_IPACM_HAL 1551 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_SRC_ADDR; 1552 flt_rule_entry.rule.attrib.u.v6.src_addr_mask[0] = ntohl(prefix[IPA_IP_v6].v6Mask[0]); 1553 flt_rule_entry.rule.attrib.u.v6.src_addr_mask[1] = ntohl(prefix[IPA_IP_v6].v6Mask[1]); 1554 flt_rule_entry.rule.attrib.u.v6.src_addr_mask[2] = ntohl(prefix[IPA_IP_v6].v6Mask[2]); 1555 flt_rule_entry.rule.attrib.u.v6.src_addr_mask[3] = ntohl(prefix[IPA_IP_v6].v6Mask[3]); 1556 flt_rule_entry.rule.attrib.u.v6.src_addr[0] = ntohl(prefix[IPA_IP_v6].v6Addr[0]); 1557 flt_rule_entry.rule.attrib.u.v6.src_addr[1] = ntohl(prefix[IPA_IP_v6].v6Addr[1]); 1558 flt_rule_entry.rule.attrib.u.v6.src_addr[2] = ntohl(prefix[IPA_IP_v6].v6Addr[2]); 1559 flt_rule_entry.rule.attrib.u.v6.src_addr[3] = ntohl(prefix[IPA_IP_v6].v6Addr[3]); 1560 1561#endif 1562 memcpy(&(m_pFilteringTable->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 1563 if (false == m_filtering.AddFilteringRule(m_pFilteringTable)) 1564 { 1565 IPACMERR("Error Adding Filtering rule, aborting...\n"); 1566 free(m_pFilteringTable); 1567 return IPACM_FAILURE; 1568 } 1569 else 1570 { 1571 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 1572 IPACMDBG_H("flt rule hdl0=0x%x, status=0x%x\n", m_pFilteringTable->rules[0].flt_rule_hdl, m_pFilteringTable->rules[0].status); 1573 } 1574 1575 /* copy filter hdls */ 1576 dft_v6fl_rule_hdl[IPV6_DEFAULT_FILTERTING_RULES] = m_pFilteringTable->rules[0].flt_rule_hdl; 1577 free(m_pFilteringTable); 1578 } 1579 1580 return IPACM_SUCCESS; 1581} 1582 1583int IPACM_Lan::handle_wan_up_ex(ipacm_ext_prop *ext_prop, ipa_ip_type iptype, uint8_t xlat_mux_id) 1584{ 1585 int fd, ret = IPACM_SUCCESS; 1586 uint32_t cnt; 1587 IPACM_Config* ipacm_config = IPACM_Iface::ipacmcfg; 1588 struct ipa_ioc_write_qmapid mux; 1589 1590 if(rx_prop != NULL) 1591 { 1592 /* give mud ID to IPA-driver for WLAN/LAN pkts */ 1593 fd = open(IPA_DEVICE_NAME, O_RDWR); 1594 if (0 == fd) 1595 { 1596 IPACMDBG_H("Failed opening %s.\n", IPA_DEVICE_NAME); 1597 return IPACM_FAILURE; 1598 } 1599 1600 mux.qmap_id = ipacm_config->GetQmapId(); 1601 for(cnt=0; cnt<rx_prop->num_rx_props; cnt++) 1602 { 1603 mux.client = rx_prop->rx[cnt].src_pipe; 1604 ret = ioctl(fd, IPA_IOC_WRITE_QMAPID, &mux); 1605 if (ret) 1606 { 1607 IPACMERR("Failed to write mux id %d\n", mux.qmap_id); 1608 close(fd); 1609 return IPACM_FAILURE; 1610 } 1611 } 1612 close(fd); 1613 } 1614 1615 /* check only add static UL filter rule once */ 1616 if (iptype ==IPA_IP_v6 && modem_ul_v6_set == false) 1617 { 1618 IPACMDBG_H("IPA_IP_v6 num_dft_rt_v6 %d xlat_mux_id: %d modem_ul_v6_set: %d\n", num_dft_rt_v6, xlat_mux_id, modem_ul_v6_set); 1619 ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id); 1620 modem_ul_v6_set = true; 1621 } else if (iptype ==IPA_IP_v4 && modem_ul_v4_set == false) { 1622 IPACMDBG_H("IPA_IP_v4 xlat_mux_id: %d, modem_ul_v4_set %d\n", xlat_mux_id, modem_ul_v4_set); 1623 ret = handle_uplink_filter_rule(ext_prop, iptype, xlat_mux_id); 1624 modem_ul_v4_set = true; 1625 } else { 1626 IPACMDBG_H("ip-type: %d modem_ul_v4_set: %d, modem_ul_v6_set %d\n", iptype, modem_ul_v4_set, modem_ul_v6_set); 1627 } 1628 return ret; 1629} 1630 1631/* handle ETH client initial, construct full headers (tx property) */ 1632int IPACM_Lan::handle_eth_hdr_init(uint8_t *mac_addr) 1633{ 1634 1635#define ETH_IFACE_INDEX_LEN 2 1636 1637 int res = IPACM_SUCCESS, len = 0; 1638 char index[ETH_IFACE_INDEX_LEN]; 1639 struct ipa_ioc_copy_hdr sCopyHeader; 1640 struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL; 1641 uint32_t cnt; 1642 int clnt_indx; 1643 1644 clnt_indx = get_eth_client_index(mac_addr); 1645 1646 if (clnt_indx != IPACM_INVALID_INDEX) 1647 { 1648 IPACMERR("eth client is found/attached already with index %d \n", clnt_indx); 1649 return IPACM_FAILURE; 1650 } 1651 1652 /* add header to IPA */ 1653 if (num_eth_client >= IPA_MAX_NUM_ETH_CLIENTS) 1654 { 1655 IPACMERR("Reached maximum number(%d) of eth clients\n", IPA_MAX_NUM_ETH_CLIENTS); 1656 return IPACM_FAILURE; 1657 } 1658 1659 IPACMDBG_H("ETH client number: %d\n", num_eth_client); 1660 1661 memcpy(get_client_memptr(eth_client, num_eth_client)->mac, 1662 mac_addr, 1663 sizeof(get_client_memptr(eth_client, num_eth_client)->mac)); 1664 1665 1666 IPACMDBG_H("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 1667 mac_addr[0], mac_addr[1], mac_addr[2], 1668 mac_addr[3], mac_addr[4], mac_addr[5]); 1669 1670 IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 1671 get_client_memptr(eth_client, num_eth_client)->mac[0], 1672 get_client_memptr(eth_client, num_eth_client)->mac[1], 1673 get_client_memptr(eth_client, num_eth_client)->mac[2], 1674 get_client_memptr(eth_client, num_eth_client)->mac[3], 1675 get_client_memptr(eth_client, num_eth_client)->mac[4], 1676 get_client_memptr(eth_client, num_eth_client)->mac[5]); 1677 1678 /* add header to IPA */ 1679 if(tx_prop != NULL) 1680 { 1681 len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add)); 1682 pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len); 1683 if (pHeaderDescriptor == NULL) 1684 { 1685 IPACMERR("calloc failed to allocate pHeaderDescriptor\n"); 1686 return IPACM_FAILURE; 1687 } 1688 1689 /* copy partial header for v4*/ 1690 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++) 1691 { 1692 if(tx_prop->tx[cnt].ip==IPA_IP_v4) 1693 { 1694 IPACMDBG_H("Got partial v4-header name from %d tx props\n", cnt); 1695 memset(&sCopyHeader, 0, sizeof(sCopyHeader)); 1696 memcpy(sCopyHeader.name, 1697 tx_prop->tx[cnt].hdr_name, 1698 sizeof(sCopyHeader.name)); 1699 1700 IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt); 1701 if (m_header.CopyHeader(&sCopyHeader) == false) 1702 { 1703 PERROR("ioctl copy header failed"); 1704 res = IPACM_FAILURE; 1705 goto fail; 1706 } 1707 1708 IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); 1709 IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); 1710 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) 1711 { 1712 IPACMERR("header oversize\n"); 1713 res = IPACM_FAILURE; 1714 goto fail; 1715 } 1716 else 1717 { 1718 memcpy(pHeaderDescriptor->hdr[0].hdr, 1719 sCopyHeader.hdr, 1720 sCopyHeader.hdr_len); 1721 } 1722 1723 /* copy client mac_addr to partial header */ 1724 if (sCopyHeader.is_eth2_ofst_valid) 1725 { 1726 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst], 1727 mac_addr, 1728 IPA_MAC_ADDR_SIZE); 1729 } 1730 /* replace src mac to bridge mac_addr if any */ 1731 if (IPACM_Iface::ipacmcfg->ipa_bridge_enable) 1732 { 1733 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE], 1734 IPACM_Iface::ipacmcfg->bridge_mac, 1735 IPA_MAC_ADDR_SIZE); 1736 IPACMDBG_H("device is in bridge mode \n"); 1737 } 1738 1739 pHeaderDescriptor->commit = true; 1740 pHeaderDescriptor->num_hdrs = 1; 1741 1742 memset(pHeaderDescriptor->hdr[0].name, 0, 1743 sizeof(pHeaderDescriptor->hdr[0].name)); 1744 1745 snprintf(index,sizeof(index), "%d", ipa_if_num); 1746 strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)); 1747 pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 1748 if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_ETH_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) 1749 { 1750 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name)); 1751 res = IPACM_FAILURE; 1752 goto fail; 1753 } 1754 1755 snprintf(index,sizeof(index), "%d", header_name_count); 1756 if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) 1757 { 1758 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name)); 1759 res = IPACM_FAILURE; 1760 goto fail; 1761 } 1762 1763 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; 1764 pHeaderDescriptor->hdr[0].hdr_hdl = -1; 1765 pHeaderDescriptor->hdr[0].is_partial = 0; 1766 pHeaderDescriptor->hdr[0].status = -1; 1767 1768 if (m_header.AddHeader(pHeaderDescriptor) == false || 1769 pHeaderDescriptor->hdr[0].status != 0) 1770 { 1771 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); 1772 res = IPACM_FAILURE; 1773 goto fail; 1774 } 1775 1776 get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl; 1777 IPACMDBG_H("eth-client(%d) v4 full header name:%s header handle:(0x%x)\n", 1778 num_eth_client, 1779 pHeaderDescriptor->hdr[0].name, 1780 get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v4); 1781 get_client_memptr(eth_client, num_eth_client)->ipv4_header_set=true; 1782 1783 break; 1784 } 1785 } 1786 1787 1788 /* copy partial header for v6*/ 1789 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++) 1790 { 1791 if(tx_prop->tx[cnt].ip==IPA_IP_v6) 1792 { 1793 1794 IPACMDBG_H("Got partial v6-header name from %d tx props\n", cnt); 1795 memset(&sCopyHeader, 0, sizeof(sCopyHeader)); 1796 memcpy(sCopyHeader.name, 1797 tx_prop->tx[cnt].hdr_name, 1798 sizeof(sCopyHeader.name)); 1799 1800 IPACMDBG_H("header name: %s in tx:%d\n", sCopyHeader.name,cnt); 1801 if (m_header.CopyHeader(&sCopyHeader) == false) 1802 { 1803 PERROR("ioctl copy header failed"); 1804 res = IPACM_FAILURE; 1805 goto fail; 1806 } 1807 1808 IPACMDBG_H("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); 1809 IPACMDBG_H("header eth2_ofst_valid: %d, eth2_ofst: %d\n", sCopyHeader.is_eth2_ofst_valid, sCopyHeader.eth2_ofst); 1810 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) 1811 { 1812 IPACMERR("header oversize\n"); 1813 res = IPACM_FAILURE; 1814 goto fail; 1815 } 1816 else 1817 { 1818 memcpy(pHeaderDescriptor->hdr[0].hdr, 1819 sCopyHeader.hdr, 1820 sCopyHeader.hdr_len); 1821 } 1822 1823 /* copy client mac_addr to partial header */ 1824 if (sCopyHeader.is_eth2_ofst_valid) 1825 { 1826 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst], 1827 mac_addr, 1828 IPA_MAC_ADDR_SIZE); 1829 } 1830 /* replace src mac to bridge mac_addr if any */ 1831 if (IPACM_Iface::ipacmcfg->ipa_bridge_enable) 1832 { 1833 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE], 1834 IPACM_Iface::ipacmcfg->bridge_mac, 1835 IPA_MAC_ADDR_SIZE); 1836 IPACMDBG_H("device is in bridge mode \n"); 1837 } 1838 1839 pHeaderDescriptor->commit = true; 1840 pHeaderDescriptor->num_hdrs = 1; 1841 1842 memset(pHeaderDescriptor->hdr[0].name, 0, 1843 sizeof(pHeaderDescriptor->hdr[0].name)); 1844 1845 snprintf(index,sizeof(index), "%d", ipa_if_num); 1846 strlcpy(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)); 1847 pHeaderDescriptor->hdr[0].name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 1848 if (strlcat(pHeaderDescriptor->hdr[0].name, IPA_ETH_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) 1849 { 1850 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name)); 1851 res = IPACM_FAILURE; 1852 goto fail; 1853 } 1854 snprintf(index,sizeof(index), "%d", header_name_count); 1855 if (strlcat(pHeaderDescriptor->hdr[0].name, index, sizeof(pHeaderDescriptor->hdr[0].name)) > IPA_RESOURCE_NAME_MAX) 1856 { 1857 IPACMERR(" header name construction failed exceed length (%zu)\n", strlen(pHeaderDescriptor->hdr[0].name)); 1858 res = IPACM_FAILURE; 1859 goto fail; 1860 } 1861 1862 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; 1863 pHeaderDescriptor->hdr[0].hdr_hdl = -1; 1864 pHeaderDescriptor->hdr[0].is_partial = 0; 1865 pHeaderDescriptor->hdr[0].status = -1; 1866 1867 if (m_header.AddHeader(pHeaderDescriptor) == false || 1868 pHeaderDescriptor->hdr[0].status != 0) 1869 { 1870 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); 1871 res = IPACM_FAILURE; 1872 goto fail; 1873 } 1874 1875 get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl; 1876 IPACMDBG_H("eth-client(%d) v6 full header name:%s header handle:(0x%x)\n", 1877 num_eth_client, 1878 pHeaderDescriptor->hdr[0].name, 1879 get_client_memptr(eth_client, num_eth_client)->hdr_hdl_v6); 1880 1881 get_client_memptr(eth_client, num_eth_client)->ipv6_header_set=true; 1882 1883 break; 1884 1885 } 1886 } 1887 /* initialize wifi client*/ 1888 get_client_memptr(eth_client, num_eth_client)->route_rule_set_v4 = false; 1889 get_client_memptr(eth_client, num_eth_client)->route_rule_set_v6 = 0; 1890 get_client_memptr(eth_client, num_eth_client)->ipv4_set = false; 1891 get_client_memptr(eth_client, num_eth_client)->ipv6_set = 0; 1892 num_eth_client++; 1893 header_name_count++; //keep increasing header_name_count 1894 res = IPACM_SUCCESS; 1895 IPACMDBG_H("eth client number: %d\n", num_eth_client); 1896 } 1897 else 1898 { 1899 return res; 1900 } 1901fail: 1902 free(pHeaderDescriptor); 1903 return res; 1904} 1905 1906/*handle eth client */ 1907int IPACM_Lan::handle_eth_client_ipaddr(ipacm_event_data_all *data) 1908{ 1909 int clnt_indx; 1910 int v6_num; 1911 uint32_t ipv6_link_local_prefix = 0xFE800000; 1912 uint32_t ipv6_link_local_prefix_mask = 0xFFC00000; 1913 1914 IPACMDBG_H("number of eth clients: %d\n", num_eth_client); 1915 IPACMDBG_H("event MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 1916 data->mac_addr[0], 1917 data->mac_addr[1], 1918 data->mac_addr[2], 1919 data->mac_addr[3], 1920 data->mac_addr[4], 1921 data->mac_addr[5]); 1922 1923 clnt_indx = get_eth_client_index(data->mac_addr); 1924 1925 if (clnt_indx == IPACM_INVALID_INDEX) 1926 { 1927 IPACMERR("eth client not found/attached \n"); 1928 return IPACM_FAILURE; 1929 } 1930 1931 IPACMDBG_H("Ip-type received %d\n", data->iptype); 1932 if (data->iptype == IPA_IP_v4) 1933 { 1934 IPACMDBG_H("ipv4 address: 0x%x\n", data->ipv4_addr); 1935 if (data->ipv4_addr != 0) /* not 0.0.0.0 */ 1936 { 1937 if (get_client_memptr(eth_client, clnt_indx)->ipv4_set == false) 1938 { 1939 get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr; 1940 get_client_memptr(eth_client, clnt_indx)->ipv4_set = true; 1941 } 1942 else 1943 { 1944 /* check if client got new IPv4 address*/ 1945 if(data->ipv4_addr == get_client_memptr(eth_client, clnt_indx)->v4_addr) 1946 { 1947 IPACMDBG_H("Already setup ipv4 addr for client:%d, ipv4 address didn't change\n", clnt_indx); 1948 return IPACM_FAILURE; 1949 } 1950 else 1951 { 1952 IPACMDBG_H("ipv4 addr for client:%d is changed \n", clnt_indx); 1953 /* delete NAT rules first */ 1954 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, clnt_indx)->v4_addr); 1955 delete_eth_rtrules(clnt_indx,IPA_IP_v4); 1956 get_client_memptr(eth_client, clnt_indx)->route_rule_set_v4 = false; 1957 get_client_memptr(eth_client, clnt_indx)->v4_addr = data->ipv4_addr; 1958 } 1959 } 1960 } 1961 else 1962 { 1963 IPACMDBG_H("Invalid client IPv4 address \n"); 1964 return IPACM_FAILURE; 1965 } 1966 } 1967 else 1968 { 1969 if ((data->ipv6_addr[0] != 0) || (data->ipv6_addr[1] != 0) || 1970 (data->ipv6_addr[2] != 0) || (data->ipv6_addr[3] != 0)) /* check if all 0 not valid ipv6 address */ 1971 { 1972 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]); 1973 if( (data->ipv6_addr[0] & ipv6_link_local_prefix_mask) != (ipv6_link_local_prefix & ipv6_link_local_prefix_mask) && 1974 memcmp(ipv6_prefix, data->ipv6_addr, sizeof(ipv6_prefix)) != 0) 1975 { 1976 IPACMDBG_H("This IPv6 address is not global IPv6 address with correct prefix, ignore.\n"); 1977 return IPACM_FAILURE; 1978 } 1979 1980 if(get_client_memptr(eth_client, clnt_indx)->ipv6_set < IPV6_NUM_ADDR) 1981 { 1982 1983 for(v6_num=0;v6_num < get_client_memptr(eth_client, clnt_indx)->ipv6_set;v6_num++) 1984 { 1985 if( data->ipv6_addr[0] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][0] && 1986 data->ipv6_addr[1] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][1] && 1987 data->ipv6_addr[2]== get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][2] && 1988 data->ipv6_addr[3] == get_client_memptr(eth_client, clnt_indx)->v6_addr[v6_num][3]) 1989 { 1990 IPACMDBG_H("Already see this ipv6 addr at position: %d for client:%d\n", v6_num, clnt_indx); 1991 return IPACM_FAILURE; /* not setup the RT rules*/ 1992 } 1993 } 1994 1995 /* not see this ipv6 before for wifi client*/ 1996 get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][0] = data->ipv6_addr[0]; 1997 get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][1] = data->ipv6_addr[1]; 1998 get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][2] = data->ipv6_addr[2]; 1999 get_client_memptr(eth_client, clnt_indx)->v6_addr[get_client_memptr(eth_client, clnt_indx)->ipv6_set][3] = data->ipv6_addr[3]; 2000 get_client_memptr(eth_client, clnt_indx)->ipv6_set++; 2001 } 2002 else 2003 { 2004 IPACMDBG_H("Already got %d ipv6 addr for client:%d\n", IPV6_NUM_ADDR, clnt_indx); 2005 return IPACM_FAILURE; /* not setup the RT rules*/ 2006 } 2007 } 2008 else 2009 { 2010 IPACMDBG_H("Invalid IPV6 address\n"); 2011 return IPACM_FAILURE; 2012 } 2013 } 2014 2015 return IPACM_SUCCESS; 2016} 2017 2018/*handle eth client routing rule*/ 2019int IPACM_Lan::handle_eth_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype) 2020{ 2021 struct ipa_ioc_add_rt_rule *rt_rule; 2022 struct ipa_rt_rule_add *rt_rule_entry; 2023 uint32_t tx_index; 2024 int eth_index,v6_num; 2025 const int NUM = 1; 2026 2027 if(tx_prop == NULL) 2028 { 2029 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); 2030 return IPACM_SUCCESS; 2031 } 2032 2033 IPACMDBG_H("Received mac_addr MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 2034 mac_addr[0], mac_addr[1], mac_addr[2], 2035 mac_addr[3], mac_addr[4], mac_addr[5]); 2036 2037 eth_index = get_eth_client_index(mac_addr); 2038 if (eth_index == IPACM_INVALID_INDEX) 2039 { 2040 IPACMDBG_H("eth client not found/attached \n"); 2041 return IPACM_SUCCESS; 2042 } 2043 2044 if (iptype==IPA_IP_v4) { 2045 IPACMDBG_H("eth client index: %d, ip-type: %d, ipv4_set:%d, ipv4_rule_set:%d \n", eth_index, iptype, 2046 get_client_memptr(eth_client, eth_index)->ipv4_set, 2047 get_client_memptr(eth_client, eth_index)->route_rule_set_v4); 2048 } else { 2049 IPACMDBG_H("eth client index: %d, ip-type: %d, ipv6_set:%d, ipv6_rule_num:%d \n", eth_index, iptype, 2050 get_client_memptr(eth_client, eth_index)->ipv6_set, 2051 get_client_memptr(eth_client, eth_index)->route_rule_set_v6); 2052 } 2053 /* Add default routing rules if not set yet */ 2054 if ((iptype == IPA_IP_v4 2055 && get_client_memptr(eth_client, eth_index)->route_rule_set_v4 == false 2056 && get_client_memptr(eth_client, eth_index)->ipv4_set == true) 2057 || (iptype == IPA_IP_v6 2058 && get_client_memptr(eth_client, eth_index)->route_rule_set_v6 < get_client_memptr(eth_client, eth_index)->ipv6_set 2059 )) 2060 { 2061 2062 /* Add corresponding ipa_rm_resource_name of TX-endpoint up before IPV6 RT-rule set */ 2063 IPACMDBG_H("dev %s add producer dependency\n", dev_name); 2064 if (tx_prop != NULL) 2065 { 2066 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]); 2067 IPACM_Iface::ipacmcfg->AddRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe],false); 2068 } 2069 rt_rule = (struct ipa_ioc_add_rt_rule *) 2070 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + 2071 NUM * sizeof(struct ipa_rt_rule_add)); 2072 2073 if (rt_rule == NULL) 2074 { 2075 PERROR("Error Locate ipa_ioc_add_rt_rule memory...\n"); 2076 return IPACM_FAILURE; 2077 } 2078 2079 rt_rule->commit = 1; 2080 rt_rule->num_rules = (uint8_t)NUM; 2081 rt_rule->ip = iptype; 2082 2083 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) 2084 { 2085 if(iptype != tx_prop->tx[tx_index].ip) 2086 { 2087 IPACMDBG_H("Tx:%d, ip-type: %d conflict ip-type: %d no RT-rule added\n", 2088 tx_index, tx_prop->tx[tx_index].ip,iptype); 2089 continue; 2090 } 2091 2092 rt_rule_entry = &rt_rule->rules[0]; 2093 rt_rule_entry->at_rear = 0; 2094 2095 if (iptype == IPA_IP_v4) 2096 { 2097 IPACMDBG_H("client index(%d):ipv4 address: 0x%x\n", eth_index, 2098 get_client_memptr(eth_client, eth_index)->v4_addr); 2099 2100 IPACMDBG_H("client(%d): v4 header handle:(0x%x)\n", 2101 eth_index, 2102 get_client_memptr(eth_client, eth_index)->hdr_hdl_v4); 2103 strlcpy(rt_rule->rt_tbl_name, 2104 IPACM_Iface::ipacmcfg->rt_tbl_lan_v4.name, 2105 sizeof(rt_rule->rt_tbl_name)); 2106 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 2107 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; 2108 memcpy(&rt_rule_entry->rule.attrib, 2109 &tx_prop->tx[tx_index].attrib, 2110 sizeof(rt_rule_entry->rule.attrib)); 2111 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 2112 rt_rule_entry->rule.hdr_hdl = get_client_memptr(eth_client, eth_index)->hdr_hdl_v4; 2113 rt_rule_entry->rule.attrib.u.v4.dst_addr = get_client_memptr(eth_client, eth_index)->v4_addr; 2114 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0xFFFFFFFF; 2115#ifdef FEATURE_IPA_V3 2116 rt_rule_entry->rule.hashable = false; 2117#endif 2118 if (false == m_routing.AddRoutingRule(rt_rule)) 2119 { 2120 IPACMERR("Routing rule addition failed!\n"); 2121 free(rt_rule); 2122 return IPACM_FAILURE; 2123 } 2124 2125 /* copy ipv4 RT hdl */ 2126 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4 = 2127 rt_rule->rules[0].rt_rule_hdl; 2128 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, 2129 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4, iptype); 2130 2131 } else { 2132 2133 for(v6_num = get_client_memptr(eth_client, eth_index)->route_rule_set_v6;v6_num < get_client_memptr(eth_client, eth_index)->ipv6_set;v6_num++) 2134 { 2135 IPACMDBG_H("client(%d): v6 header handle:(0x%x)\n", 2136 eth_index, 2137 get_client_memptr(eth_client, eth_index)->hdr_hdl_v6); 2138 2139 /* v6 LAN_RT_TBL */ 2140 strlcpy(rt_rule->rt_tbl_name, 2141 IPACM_Iface::ipacmcfg->rt_tbl_v6.name, 2142 sizeof(rt_rule->rt_tbl_name)); 2143 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 2144 /* Support QCMAP LAN traffic feature, send to A5 */ 2145 rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS; 2146 memset(&rt_rule_entry->rule.attrib, 0, sizeof(rt_rule_entry->rule.attrib)); 2147 rt_rule_entry->rule.hdr_hdl = 0; 2148 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 2149 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][0]; 2150 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][1]; 2151 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][2]; 2152 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][3]; 2153 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; 2154 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; 2155 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; 2156 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; 2157#ifdef FEATURE_IPA_V3 2158 rt_rule_entry->rule.hashable = true; 2159#endif 2160 if (false == m_routing.AddRoutingRule(rt_rule)) 2161 { 2162 IPACMERR("Routing rule addition failed!\n"); 2163 free(rt_rule); 2164 return IPACM_FAILURE; 2165 } 2166 2167 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[v6_num] = rt_rule->rules[0].rt_rule_hdl; 2168 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, 2169 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[v6_num], iptype); 2170 2171 /*Copy same rule to v6 WAN RT TBL*/ 2172 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_wan_v6.name, sizeof(rt_rule->rt_tbl_name)); 2173 rt_rule->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = '\0'; 2174 /* Downlink traffic from Wan iface, directly through IPA */ 2175 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; 2176 memcpy(&rt_rule_entry->rule.attrib, 2177 &tx_prop->tx[tx_index].attrib, 2178 sizeof(rt_rule_entry->rule.attrib)); 2179 rt_rule_entry->rule.hdr_hdl = get_client_memptr(eth_client, eth_index)->hdr_hdl_v6; 2180 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 2181 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][0]; 2182 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][1]; 2183 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][2]; 2184 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = get_client_memptr(eth_client, eth_index)->v6_addr[v6_num][3]; 2185 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; 2186 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; 2187 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0xFFFFFFFF; 2188 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0xFFFFFFFF; 2189#ifdef FEATURE_IPA_V3 2190 rt_rule_entry->rule.hashable = true; 2191#endif 2192 if (false == m_routing.AddRoutingRule(rt_rule)) 2193 { 2194 IPACMERR("Routing rule addition failed!\n"); 2195 free(rt_rule); 2196 return IPACM_FAILURE; 2197 } 2198 2199 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[v6_num] = rt_rule->rules[0].rt_rule_hdl; 2200 IPACMDBG_H("tx:%d, rt rule hdl=%x ip-type: %d\n", tx_index, 2201 get_client_memptr(eth_client, eth_index)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[v6_num], iptype); 2202 } 2203 } 2204 2205 } /* end of for loop */ 2206 2207 free(rt_rule); 2208 2209 if (iptype == IPA_IP_v4) 2210 { 2211 get_client_memptr(eth_client, eth_index)->route_rule_set_v4 = true; 2212 } 2213 else 2214 { 2215 get_client_memptr(eth_client, eth_index)->route_rule_set_v6 = get_client_memptr(eth_client, eth_index)->ipv6_set; 2216 } 2217 } 2218 return IPACM_SUCCESS; 2219} 2220 2221/* handle odu client initial, construct full headers (tx property) */ 2222int IPACM_Lan::handle_odu_hdr_init(uint8_t *mac_addr) 2223{ 2224 int res = IPACM_SUCCESS, len = 0; 2225 struct ipa_ioc_copy_hdr sCopyHeader; 2226 struct ipa_ioc_add_hdr *pHeaderDescriptor = NULL; 2227 uint32_t cnt; 2228 2229 IPACMDBG("Received Client MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 2230 mac_addr[0], mac_addr[1], mac_addr[2], 2231 mac_addr[3], mac_addr[4], mac_addr[5]); 2232 2233 /* add header to IPA */ 2234 if(tx_prop != NULL) 2235 { 2236 len = sizeof(struct ipa_ioc_add_hdr) + (1 * sizeof(struct ipa_hdr_add)); 2237 pHeaderDescriptor = (struct ipa_ioc_add_hdr *)calloc(1, len); 2238 if (pHeaderDescriptor == NULL) 2239 { 2240 IPACMERR("calloc failed to allocate pHeaderDescriptor\n"); 2241 return IPACM_FAILURE; 2242 } 2243 2244 /* copy partial header for v4*/ 2245 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++) 2246 { 2247 if(tx_prop->tx[cnt].ip==IPA_IP_v4) 2248 { 2249 IPACMDBG("Got partial v4-header name from %d tx props\n", cnt); 2250 memset(&sCopyHeader, 0, sizeof(sCopyHeader)); 2251 memcpy(sCopyHeader.name, 2252 tx_prop->tx[cnt].hdr_name, 2253 sizeof(sCopyHeader.name)); 2254 IPACMDBG("header name: %s in tx:%d\n", sCopyHeader.name,cnt); 2255 if (m_header.CopyHeader(&sCopyHeader) == false) 2256 { 2257 PERROR("ioctl copy header failed"); 2258 res = IPACM_FAILURE; 2259 goto fail; 2260 } 2261 IPACMDBG("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); 2262 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) 2263 { 2264 IPACMERR("header oversize\n"); 2265 res = IPACM_FAILURE; 2266 goto fail; 2267 } 2268 else 2269 { 2270 memcpy(pHeaderDescriptor->hdr[0].hdr, 2271 sCopyHeader.hdr, 2272 sCopyHeader.hdr_len); 2273 } 2274 /* copy client mac_addr to partial header */ 2275 if (sCopyHeader.is_eth2_ofst_valid) 2276 { 2277 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst], 2278 mac_addr, 2279 IPA_MAC_ADDR_SIZE); 2280 } 2281 /* replace src mac to bridge mac_addr if any */ 2282 if (IPACM_Iface::ipacmcfg->ipa_bridge_enable) 2283 { 2284 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE], 2285 IPACM_Iface::ipacmcfg->bridge_mac, 2286 IPA_MAC_ADDR_SIZE); 2287 IPACMDBG_H("device is in bridge mode \n"); 2288 } 2289 2290 pHeaderDescriptor->commit = true; 2291 pHeaderDescriptor->num_hdrs = 1; 2292 2293 memset(pHeaderDescriptor->hdr[0].name, 0, 2294 sizeof(pHeaderDescriptor->hdr[0].name)); 2295 strlcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v4, sizeof(pHeaderDescriptor->hdr[0].name)); 2296 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; 2297 pHeaderDescriptor->hdr[0].hdr_hdl = -1; 2298 pHeaderDescriptor->hdr[0].is_partial = 0; 2299 pHeaderDescriptor->hdr[0].status = -1; 2300 2301 if (m_header.AddHeader(pHeaderDescriptor) == false || 2302 pHeaderDescriptor->hdr[0].status != 0) 2303 { 2304 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); 2305 res = IPACM_FAILURE; 2306 goto fail; 2307 } 2308 2309 ODU_hdr_hdl_v4 = pHeaderDescriptor->hdr[0].hdr_hdl; 2310 ipv4_header_set = true ; 2311 IPACMDBG(" ODU v4 full header name:%s header handle:(0x%x)\n", 2312 pHeaderDescriptor->hdr[0].name, 2313 ODU_hdr_hdl_v4); 2314 break; 2315 } 2316 } 2317 2318 2319 /* copy partial header for v6*/ 2320 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++) 2321 { 2322 if(tx_prop->tx[cnt].ip==IPA_IP_v6) 2323 { 2324 2325 IPACMDBG("Got partial v6-header name from %d tx props\n", cnt); 2326 memset(&sCopyHeader, 0, sizeof(sCopyHeader)); 2327 memcpy(sCopyHeader.name, 2328 tx_prop->tx[cnt].hdr_name, 2329 sizeof(sCopyHeader.name)); 2330 2331 IPACMDBG("header name: %s in tx:%d\n", sCopyHeader.name,cnt); 2332 if (m_header.CopyHeader(&sCopyHeader) == false) 2333 { 2334 PERROR("ioctl copy header failed"); 2335 res = IPACM_FAILURE; 2336 goto fail; 2337 } 2338 2339 IPACMDBG("header length: %d, paritial: %d\n", sCopyHeader.hdr_len, sCopyHeader.is_partial); 2340 if (sCopyHeader.hdr_len > IPA_HDR_MAX_SIZE) 2341 { 2342 IPACMERR("header oversize\n"); 2343 res = IPACM_FAILURE; 2344 goto fail; 2345 } 2346 else 2347 { 2348 memcpy(pHeaderDescriptor->hdr[0].hdr, 2349 sCopyHeader.hdr, 2350 sCopyHeader.hdr_len); 2351 } 2352 2353 /* copy client mac_addr to partial header */ 2354 if (sCopyHeader.is_eth2_ofst_valid) 2355 { 2356 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst], 2357 mac_addr, 2358 IPA_MAC_ADDR_SIZE); 2359 } 2360 /* replace src mac to bridge mac_addr if any */ 2361 if (IPACM_Iface::ipacmcfg->ipa_bridge_enable) 2362 { 2363 memcpy(&pHeaderDescriptor->hdr[0].hdr[sCopyHeader.eth2_ofst+IPA_MAC_ADDR_SIZE], 2364 IPACM_Iface::ipacmcfg->bridge_mac, 2365 IPA_MAC_ADDR_SIZE); 2366 IPACMDBG_H("device is in bridge mode \n"); 2367 } 2368 2369 pHeaderDescriptor->commit = true; 2370 pHeaderDescriptor->num_hdrs = 1; 2371 2372 memset(pHeaderDescriptor->hdr[0].name, 0, 2373 sizeof(pHeaderDescriptor->hdr[0].name)); 2374 2375 strlcpy(pHeaderDescriptor->hdr[0].name, IPA_ODU_HDR_NAME_v6, sizeof(pHeaderDescriptor->hdr[0].name)); 2376 pHeaderDescriptor->hdr[0].hdr_len = sCopyHeader.hdr_len; 2377 pHeaderDescriptor->hdr[0].hdr_hdl = -1; 2378 pHeaderDescriptor->hdr[0].is_partial = 0; 2379 pHeaderDescriptor->hdr[0].status = -1; 2380 2381 if (m_header.AddHeader(pHeaderDescriptor) == false || 2382 pHeaderDescriptor->hdr[0].status != 0) 2383 { 2384 IPACMERR("ioctl IPA_IOC_ADD_HDR failed: %d\n", pHeaderDescriptor->hdr[0].status); 2385 res = IPACM_FAILURE; 2386 goto fail; 2387 } 2388 2389 ODU_hdr_hdl_v6 = pHeaderDescriptor->hdr[0].hdr_hdl; 2390 ipv6_header_set = true ; 2391 IPACMDBG(" ODU v4 full header name:%s header handle:(0x%x)\n", 2392 pHeaderDescriptor->hdr[0].name, 2393 ODU_hdr_hdl_v6); 2394 break; 2395 } 2396 } 2397 } 2398fail: 2399 free(pHeaderDescriptor); 2400 return res; 2401} 2402 2403 2404/* handle odu default route rule configuration */ 2405int IPACM_Lan::handle_odu_route_add() 2406{ 2407 /* add default WAN route */ 2408 struct ipa_ioc_add_rt_rule *rt_rule; 2409 struct ipa_rt_rule_add *rt_rule_entry; 2410 uint32_t tx_index; 2411 const int NUM = 1; 2412 2413 if(tx_prop == NULL) 2414 { 2415 IPACMDBG_H("No tx properties, ignore default route setting\n"); 2416 return IPACM_SUCCESS; 2417 } 2418 2419 rt_rule = (struct ipa_ioc_add_rt_rule *) 2420 calloc(1, sizeof(struct ipa_ioc_add_rt_rule) + 2421 NUM * sizeof(struct ipa_rt_rule_add)); 2422 2423 if (!rt_rule) 2424 { 2425 IPACMERR("Error Locate ipa_ioc_add_rt_rule memory...\n"); 2426 return IPACM_FAILURE; 2427 } 2428 2429 rt_rule->commit = 1; 2430 rt_rule->num_rules = (uint8_t)NUM; 2431 2432 2433 IPACMDBG_H("WAN table created %s \n", rt_rule->rt_tbl_name); 2434 rt_rule_entry = &rt_rule->rules[0]; 2435 rt_rule_entry->at_rear = true; 2436 2437 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) 2438 { 2439 2440 if (IPA_IP_v4 == tx_prop->tx[tx_index].ip) 2441 { 2442 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v4.name, sizeof(rt_rule->rt_tbl_name)); 2443 rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v4; 2444 rt_rule->ip = IPA_IP_v4; 2445 } 2446 else 2447 { 2448 strlcpy(rt_rule->rt_tbl_name, IPACM_Iface::ipacmcfg->rt_tbl_odu_v6.name, sizeof(rt_rule->rt_tbl_name)); 2449 rt_rule_entry->rule.hdr_hdl = ODU_hdr_hdl_v6; 2450 rt_rule->ip = IPA_IP_v6; 2451 } 2452 2453 rt_rule_entry->rule.dst = tx_prop->tx[tx_index].dst_pipe; 2454 memcpy(&rt_rule_entry->rule.attrib, 2455 &tx_prop->tx[tx_index].attrib, 2456 sizeof(rt_rule_entry->rule.attrib)); 2457 2458 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 2459 if (IPA_IP_v4 == tx_prop->tx[tx_index].ip) 2460 { 2461 rt_rule_entry->rule.attrib.u.v4.dst_addr = 0; 2462 rt_rule_entry->rule.attrib.u.v4.dst_addr_mask = 0; 2463#ifdef FEATURE_IPA_V3 2464 rt_rule_entry->rule.hashable = true; 2465#endif 2466 if (false == m_routing.AddRoutingRule(rt_rule)) 2467 { 2468 IPACMERR("Routing rule addition failed!\n"); 2469 free(rt_rule); 2470 return IPACM_FAILURE; 2471 } 2472 odu_route_rule_v4_hdl[tx_index] = rt_rule_entry->rt_rule_hdl; 2473 IPACMDBG_H("Got ipv4 ODU-route rule hdl:0x%x,tx:%d,ip-type: %d \n", 2474 odu_route_rule_v4_hdl[tx_index], 2475 tx_index, 2476 IPA_IP_v4); 2477 } 2478 else 2479 { 2480 rt_rule_entry->rule.attrib.u.v6.dst_addr[0] = 0; 2481 rt_rule_entry->rule.attrib.u.v6.dst_addr[1] = 0; 2482 rt_rule_entry->rule.attrib.u.v6.dst_addr[2] = 0; 2483 rt_rule_entry->rule.attrib.u.v6.dst_addr[3] = 0; 2484 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[0] = 0; 2485 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[1] = 0; 2486 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[2] = 0; 2487 rt_rule_entry->rule.attrib.u.v6.dst_addr_mask[3] = 0; 2488#ifdef FEATURE_IPA_V3 2489 rt_rule_entry->rule.hashable = true; 2490#endif 2491 if (false == m_routing.AddRoutingRule(rt_rule)) 2492 { 2493 IPACMERR("Routing rule addition failed!\n"); 2494 free(rt_rule); 2495 return IPACM_FAILURE; 2496 } 2497 odu_route_rule_v6_hdl[tx_index] = rt_rule_entry->rt_rule_hdl; 2498 IPACMDBG_H("Set ipv6 ODU-route rule hdl for v6_lan_table:0x%x,tx:%d,ip-type: %d \n", 2499 odu_route_rule_v6_hdl[tx_index], 2500 tx_index, 2501 IPA_IP_v6); 2502 } 2503 } 2504 free(rt_rule); 2505 return IPACM_SUCCESS; 2506} 2507 2508/* handle odu default route rule deletion */ 2509int IPACM_Lan::handle_odu_route_del() 2510{ 2511 uint32_t tx_index; 2512 2513 if(tx_prop == NULL) 2514 { 2515 IPACMDBG_H("No tx properties, ignore delete default route setting\n"); 2516 return IPACM_SUCCESS; 2517 } 2518 2519 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) 2520 { 2521 if (tx_prop->tx[tx_index].ip == IPA_IP_v4) 2522 { 2523 IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n", 2524 tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v4); 2525 2526 if (m_routing.DeleteRoutingHdl(odu_route_rule_v4_hdl[tx_index], IPA_IP_v4) 2527 == false) 2528 { 2529 IPACMERR("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v4, odu_route_rule_v4_hdl[tx_index], tx_index); 2530 return IPACM_FAILURE; 2531 } 2532 } 2533 else 2534 { 2535 IPACMDBG_H("Tx:%d, ip-type: %d match ip-type: %d, RT-rule deleted\n", 2536 tx_index, tx_prop->tx[tx_index].ip,IPA_IP_v6); 2537 2538 if (m_routing.DeleteRoutingHdl(odu_route_rule_v6_hdl[tx_index], IPA_IP_v6) 2539 == false) 2540 { 2541 IPACMERR("IP-family:%d, Routing rule(hdl:0x%x) deletion failed with tx_index %d!\n", IPA_IP_v6, odu_route_rule_v6_hdl[tx_index], tx_index); 2542 return IPACM_FAILURE; 2543 } 2544 } 2545 } 2546 2547 return IPACM_SUCCESS; 2548} 2549 2550/*handle eth client del mode*/ 2551int IPACM_Lan::handle_eth_client_down_evt(uint8_t *mac_addr) 2552{ 2553 int clt_indx; 2554 uint32_t tx_index; 2555 int num_eth_client_tmp = num_eth_client; 2556 int num_v6; 2557 2558 IPACMDBG_H("total client: %d\n", num_eth_client_tmp); 2559 2560 clt_indx = get_eth_client_index(mac_addr); 2561 if (clt_indx == IPACM_INVALID_INDEX) 2562 { 2563 IPACMDBG_H("eth client not attached\n"); 2564 return IPACM_SUCCESS; 2565 } 2566 2567 /* First reset nat rules and then route rules */ 2568 if(get_client_memptr(eth_client, clt_indx)->ipv4_set == true) 2569 { 2570 IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, clt_indx)->v4_addr); 2571 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, clt_indx)->v4_addr); 2572 } 2573 2574 if (delete_eth_rtrules(clt_indx, IPA_IP_v4)) 2575 { 2576 IPACMERR("unbale to delete ecm-client v4 route rules for index: %d\n", clt_indx); 2577 return IPACM_FAILURE; 2578 } 2579 2580 if (delete_eth_rtrules(clt_indx, IPA_IP_v6)) 2581 { 2582 IPACMERR("unbale to delete ecm-client v6 route rules for index: %d\n", clt_indx); 2583 return IPACM_FAILURE; 2584 } 2585 2586 /* Delete eth client header */ 2587 if(get_client_memptr(eth_client, clt_indx)->ipv4_header_set == true) 2588 { 2589 if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, clt_indx)->hdr_hdl_v4) 2590 == false) 2591 { 2592 return IPACM_FAILURE; 2593 } 2594 get_client_memptr(eth_client, clt_indx)->ipv4_header_set = false; 2595 } 2596 2597 if(get_client_memptr(eth_client, clt_indx)->ipv6_header_set == true) 2598 { 2599 if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, clt_indx)->hdr_hdl_v6) 2600 == false) 2601 { 2602 return IPACM_FAILURE; 2603 } 2604 get_client_memptr(eth_client, clt_indx)->ipv6_header_set = false; 2605 } 2606 2607 /* Reset ip_set to 0*/ 2608 get_client_memptr(eth_client, clt_indx)->ipv4_set = false; 2609 get_client_memptr(eth_client, clt_indx)->ipv6_set = 0; 2610 get_client_memptr(eth_client, clt_indx)->ipv4_header_set = false; 2611 get_client_memptr(eth_client, clt_indx)->ipv6_header_set = false; 2612 get_client_memptr(eth_client, clt_indx)->route_rule_set_v4 = false; 2613 get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 = 0; 2614 2615 for (; clt_indx < num_eth_client_tmp - 1; clt_indx++) 2616 { 2617 memcpy(get_client_memptr(eth_client, clt_indx)->mac, 2618 get_client_memptr(eth_client, (clt_indx + 1))->mac, 2619 sizeof(get_client_memptr(eth_client, clt_indx)->mac)); 2620 2621 get_client_memptr(eth_client, clt_indx)->hdr_hdl_v4 = get_client_memptr(eth_client, (clt_indx + 1))->hdr_hdl_v4; 2622 get_client_memptr(eth_client, clt_indx)->hdr_hdl_v6 = get_client_memptr(eth_client, (clt_indx + 1))->hdr_hdl_v6; 2623 get_client_memptr(eth_client, clt_indx)->v4_addr = get_client_memptr(eth_client, (clt_indx + 1))->v4_addr; 2624 2625 get_client_memptr(eth_client, clt_indx)->ipv4_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv4_set; 2626 get_client_memptr(eth_client, clt_indx)->ipv6_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv6_set; 2627 get_client_memptr(eth_client, clt_indx)->ipv4_header_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv4_header_set; 2628 get_client_memptr(eth_client, clt_indx)->ipv6_header_set = get_client_memptr(eth_client, (clt_indx + 1))->ipv6_header_set; 2629 2630 get_client_memptr(eth_client, clt_indx)->route_rule_set_v4 = get_client_memptr(eth_client, (clt_indx + 1))->route_rule_set_v4; 2631 get_client_memptr(eth_client, clt_indx)->route_rule_set_v6 = get_client_memptr(eth_client, (clt_indx + 1))->route_rule_set_v6; 2632 2633 for (num_v6=0;num_v6< get_client_memptr(eth_client, clt_indx)->ipv6_set;num_v6++) 2634 { 2635 get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6][0] = get_client_memptr(eth_client, (clt_indx + 1))->v6_addr[num_v6][0]; 2636 get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6][1] = get_client_memptr(eth_client, (clt_indx + 1))->v6_addr[num_v6][1]; 2637 get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6][2] = get_client_memptr(eth_client, (clt_indx + 1))->v6_addr[num_v6][2]; 2638 get_client_memptr(eth_client, clt_indx)->v6_addr[num_v6][3] = get_client_memptr(eth_client, (clt_indx + 1))->v6_addr[num_v6][3]; 2639 } 2640 2641 for (tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) 2642 { 2643 get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4 = 2644 get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v4; 2645 2646 for(num_v6=0;num_v6< get_client_memptr(eth_client, clt_indx)->route_rule_set_v6;num_v6++) 2647 { 2648 get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6] = 2649 get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6[num_v6]; 2650 get_client_memptr(eth_client, clt_indx)->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6] = 2651 get_client_memptr(eth_client, (clt_indx + 1))->eth_rt_hdl[tx_index].eth_rt_rule_hdl_v6_wan[num_v6]; 2652 } 2653 } 2654 } 2655 2656 IPACMDBG_H(" %d eth client deleted successfully \n", num_eth_client); 2657 num_eth_client = num_eth_client - 1; 2658 IPACMDBG_H(" Number of eth client: %d\n", num_eth_client); 2659 2660 /* Del RM dependency */ 2661 if(num_eth_client == 0) 2662 { 2663 /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule*/ 2664 IPACMDBG_H("dev %s add producer dependency\n", dev_name); 2665 if (tx_prop != NULL) 2666 { 2667 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]); 2668 IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); 2669 } 2670 } 2671 2672 return IPACM_SUCCESS; 2673} 2674 2675/*handle LAN iface down event*/ 2676int IPACM_Lan::handle_down_evt() 2677{ 2678 uint32_t i; 2679 int res = IPACM_SUCCESS; 2680 2681 IPACMDBG_H("lan handle_down_evt\n "); 2682 if (ipa_if_cate == ODU_IF) 2683 { 2684 /* delete ODU default RT rules */ 2685 if (IPACM_Iface::ipacmcfg->ipacm_odu_embms_enable == true) 2686 { 2687 IPACMDBG_H("eMBMS enable, delete eMBMS DL RT rule\n"); 2688 handle_odu_route_del(); 2689 } 2690 2691 /* delete full header */ 2692 if (ipv4_header_set) 2693 { 2694 if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v4) 2695 == false) 2696 { 2697 IPACMERR("ODU ipv4 header delete fail\n"); 2698 res = IPACM_FAILURE; 2699 goto fail; 2700 } 2701 IPACMDBG_H("ODU ipv4 header delete success\n"); 2702 } 2703 2704 if (ipv6_header_set) 2705 { 2706 if (m_header.DeleteHeaderHdl(ODU_hdr_hdl_v6) 2707 == false) 2708 { 2709 IPACMERR("ODU ipv6 header delete fail\n"); 2710 res = IPACM_FAILURE; 2711 goto fail; 2712 } 2713 IPACMERR("ODU ipv6 header delete success\n"); 2714 } 2715 } 2716 2717 /* no iface address up, directly close iface*/ 2718 if (ip_type == IPACM_IP_NULL) 2719 { 2720 goto fail; 2721 } 2722 2723 /* delete wan filter rule */ 2724 if (IPACM_Wan::isWanUP(ipa_if_num) && rx_prop != NULL) 2725 { 2726 IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode); 2727 handle_wan_down(IPACM_Wan::backhaul_is_sta_mode); 2728 } 2729 2730 if (IPACM_Wan::isWanUP_V6(ipa_if_num) && rx_prop != NULL) 2731 { 2732 IPACMDBG_H("LAN IF goes down, backhaul type %d\n", IPACM_Wan::backhaul_is_sta_mode); 2733 handle_wan_down_v6(IPACM_Wan::backhaul_is_sta_mode); 2734 } 2735 2736 /* delete default filter rules */ 2737 if (ip_type != IPA_IP_v6 && rx_prop != NULL) 2738 { 2739 if(m_filtering.DeleteFilteringHdls(ipv4_icmp_flt_rule_hdl, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE) == false) 2740 { 2741 IPACMERR("Error Deleting ICMPv4 Filtering Rule, aborting...\n"); 2742 res = IPACM_FAILURE; 2743 goto fail; 2744 } 2745 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, NUM_IPV4_ICMP_FLT_RULE); 2746 2747 if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES) == false) 2748 { 2749 IPACMERR("Error Deleting Filtering Rule, aborting...\n"); 2750 res = IPACM_FAILURE; 2751 goto fail; 2752 } 2753 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES); 2754 2755 /* free private-subnet ipv4 filter rules */ 2756 if (IPACM_Iface::ipacmcfg->ipa_num_private_subnet > IPA_PRIV_SUBNET_FILTER_RULE_HANDLES) 2757 { 2758 IPACMERR(" the number of rules are bigger than array, aborting...\n"); 2759 res = IPACM_FAILURE; 2760 goto fail; 2761 } 2762 2763#ifdef FEATURE_IPA_ANDROID 2764 if(m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES) == false) 2765 { 2766 IPACMERR("Error deleting private subnet IPv4 flt rules.\n"); 2767 res = IPACM_FAILURE; 2768 goto fail; 2769 } 2770 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES); 2771#else 2772 if (m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet) == false) 2773 { 2774 IPACMERR("Error deleting private subnet IPv4 flt rules.\n"); 2775 res = IPACM_FAILURE; 2776 goto fail; 2777 } 2778 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet); 2779#endif 2780 IPACMDBG_H("Deleted private subnet v4 filter rules successfully.\n"); 2781 } 2782 IPACMDBG_H("Finished delete default iface ipv4 filtering rules \n "); 2783 2784 if (ip_type != IPA_IP_v4 && rx_prop != NULL) 2785 { 2786 if(m_filtering.DeleteFilteringHdls(ipv6_icmp_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE) == false) 2787 { 2788 IPACMERR("Error Deleting ICMPv6 Filtering Rule, aborting...\n"); 2789 res = IPACM_FAILURE; 2790 goto fail; 2791 } 2792 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_ICMP_FLT_RULE); 2793 2794 if (m_filtering.DeleteFilteringHdls(dft_v6fl_rule_hdl, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES) == false) 2795 { 2796 IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n"); 2797 res = IPACM_FAILURE; 2798 goto fail; 2799 } 2800 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, IPV6_DEFAULT_FILTERTING_RULES); 2801 } 2802 IPACMDBG_H("Finished delete default iface ipv6 filtering rules \n "); 2803 2804 if (ip_type != IPA_IP_v6) 2805 { 2806 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[0], IPA_IP_v4) 2807 == false) 2808 { 2809 IPACMERR("Routing rule deletion failed!\n"); 2810 res = IPACM_FAILURE; 2811 goto fail; 2812 } 2813 } 2814 IPACMDBG_H("Finished delete default iface ipv4 rules \n "); 2815 2816 /* delete default v6 routing rule */ 2817 if (ip_type != IPA_IP_v4) 2818 { 2819 /* may have multiple ipv6 iface-RT rules*/ 2820 for (i = 0; i < 2*num_dft_rt_v6; i++) 2821 { 2822 if (m_routing.DeleteRoutingHdl(dft_rt_rule_hdl[MAX_DEFAULT_v4_ROUTE_RULES + i], IPA_IP_v6) 2823 == false) 2824 { 2825 IPACMERR("Routing rule deletion failed!\n"); 2826 res = IPACM_FAILURE; 2827 goto fail; 2828 } 2829 } 2830 } 2831 2832 IPACMDBG_H("Finished delete default iface ipv6 rules \n "); 2833 2834 /* free the edm clients cache */ 2835 IPACMDBG_H("Free ecm clients cache\n"); 2836 2837 /* Delete corresponding ipa_rm_resource_name of TX-endpoint after delete all IPV4V6 RT-rule */ 2838 IPACMDBG_H("dev %s delete producer dependency\n", dev_name); 2839 if (tx_prop != NULL) 2840 { 2841 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]); 2842 IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[tx_prop->tx[0].dst_pipe]); 2843 } 2844 2845 eth_bridge_post_event(IPA_ETH_BRIDGE_IFACE_DOWN, IPA_IP_MAX, NULL); 2846 2847/* Delete private subnet*/ 2848#ifdef FEATURE_IPA_ANDROID 2849 if (ip_type != IPA_IP_v6) 2850 { 2851 IPACMDBG_H("current IPACM private subnet_addr number(%d)\n", IPACM_Iface::ipacmcfg->ipa_num_private_subnet); 2852 IPACMDBG_H(" Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); 2853 if(IPACM_Iface::ipacmcfg->DelPrivateSubnet(if_ipv4_subnet, ipa_if_num) == false) 2854 { 2855 IPACMERR(" can't Delete IPACM private subnet_addr as: 0x%x \n", if_ipv4_subnet); 2856 } 2857 } 2858 2859 /* reset the IPA-client pipe enum */ 2860 if(ipa_if_cate != WAN_IF) 2861 { 2862#ifdef FEATURE_IPACM_HAL 2863 handle_tethering_client(true, IPACM_CLIENT_MAX); 2864#else 2865 handle_tethering_client(true, IPACM_CLIENT_USB); 2866#endif 2867 } 2868#endif /* defined(FEATURE_IPA_ANDROID)*/ 2869fail: 2870 /* clean eth-client header, routing rules */ 2871 IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client); 2872 for (i = 0; i < num_eth_client; i++) 2873 { 2874 /* First reset nat rules and then route rules */ 2875 if(get_client_memptr(eth_client, i)->ipv4_set == true) 2876 { 2877 IPACMDBG_H("Clean Nat Rules for ipv4:0x%x\n", get_client_memptr(eth_client, i)->v4_addr); 2878 CtList->HandleNeighIpAddrDelEvt(get_client_memptr(eth_client, i)->v4_addr); 2879 } 2880 2881 if (delete_eth_rtrules(i, IPA_IP_v4)) 2882 { 2883 IPACMERR("unbale to delete ecm-client v4 route rules for index %d\n", i); 2884 res = IPACM_FAILURE; 2885 } 2886 2887 if (delete_eth_rtrules(i, IPA_IP_v6)) 2888 { 2889 IPACMERR("unbale to delete ecm-client v6 route rules for index %d\n", i); 2890 res = IPACM_FAILURE; 2891 } 2892 2893 IPACMDBG_H("Delete %d client header\n", num_eth_client); 2894 2895 if(get_client_memptr(eth_client, i)->ipv4_header_set == true) 2896 { 2897 if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v4) 2898 == false) 2899 { 2900 res = IPACM_FAILURE; 2901 } 2902 } 2903 2904 if(get_client_memptr(eth_client, i)->ipv6_header_set == true) 2905 { 2906 if (m_header.DeleteHeaderHdl(get_client_memptr(eth_client, i)->hdr_hdl_v6) 2907 == false) 2908 { 2909 res = IPACM_FAILURE; 2910 } 2911 } 2912 } /* end of for loop */ 2913 2914 /* check software routing fl rule hdl */ 2915 if (softwarerouting_act == true && rx_prop != NULL) 2916 { 2917 handle_software_routing_disable(); 2918 } 2919 2920 if (odu_route_rule_v4_hdl != NULL) 2921 { 2922 free(odu_route_rule_v4_hdl); 2923 } 2924 if (odu_route_rule_v6_hdl != NULL) 2925 { 2926 free(odu_route_rule_v6_hdl); 2927 } 2928 /* Delete corresponding ipa_rm_resource_name of RX-endpoint after delete all IPV4V6 FT-rule */ 2929 if (rx_prop != NULL) 2930 { 2931 IPACMDBG_H("dev %s add producer dependency\n", dev_name); 2932 IPACMDBG_H("depend Got pipe %d rm index : %d \n", rx_prop->rx[0].src_pipe, IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]); 2933 IPACM_Iface::ipacmcfg->DelRmDepend(IPACM_Iface::ipacmcfg->ipa_client_rm_map_tbl[rx_prop->rx[0].src_pipe]); 2934 IPACMDBG_H("Finished delete dependency \n "); 2935 free(rx_prop); 2936 } 2937 2938 if (eth_client != NULL) 2939 { 2940 free(eth_client); 2941 } 2942 2943 if (tx_prop != NULL) 2944 { 2945 free(tx_prop); 2946 } 2947 if (iface_query != NULL) 2948 { 2949 free(iface_query); 2950 } 2951 2952 is_active = false; 2953 post_del_self_evt(); 2954 2955 return res; 2956} 2957 2958/* install UL filter rule from Q6 */ 2959int IPACM_Lan::handle_uplink_filter_rule(ipacm_ext_prop *prop, ipa_ip_type iptype, uint8_t xlat_mux_id) 2960{ 2961 ipa_flt_rule_add flt_rule_entry; 2962 int len = 0, cnt, ret = IPACM_SUCCESS; 2963 ipa_ioc_add_flt_rule *pFilteringTable; 2964 ipa_fltr_installed_notif_req_msg_v01 flt_index; 2965 int fd; 2966 int i, index, eq_index; 2967 uint32_t value = 0; 2968 2969 IPACMDBG_H("Set modem UL flt rules\n"); 2970 2971 if (rx_prop == NULL) 2972 { 2973 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); 2974 return IPACM_SUCCESS; 2975 } 2976 2977 if(prop == NULL || prop->num_ext_props <= 0) 2978 { 2979 IPACMDBG_H("No extended property.\n"); 2980 return IPACM_SUCCESS; 2981 } 2982 2983 fd = open(IPA_DEVICE_NAME, O_RDWR); 2984 if (0 == fd) 2985 { 2986 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); 2987 return IPACM_FAILURE; 2988 } 2989 if (prop->num_ext_props > MAX_WAN_UL_FILTER_RULES) 2990 { 2991 IPACMERR("number of modem UL rules > MAX_WAN_UL_FILTER_RULES, aborting...\n"); 2992 close(fd); 2993 return IPACM_FAILURE; 2994 } 2995 2996 memset(&flt_index, 0, sizeof(flt_index)); 2997 flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe); 2998 flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01; 2999#ifndef FEATURE_IPA_V3 3000 flt_index.filter_index_list_len = prop->num_ext_props; 3001#else /* defined (FEATURE_IPA_V3) */ 3002 flt_index.rule_id_valid = 1; 3003 flt_index.rule_id_len = prop->num_ext_props; 3004#endif 3005 flt_index.embedded_pipe_index_valid = 1; 3006 flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD); 3007 flt_index.retain_header_valid = 1; 3008 flt_index.retain_header = 0; 3009 flt_index.embedded_call_mux_id_valid = 1; 3010 flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId(); 3011#ifndef FEATURE_IPA_V3 3012 IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d\n", 3013 flt_index.source_pipe_index, flt_index.filter_index_list_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id); 3014#else /* defined (FEATURE_IPA_V3) */ 3015 IPACMDBG_H("flt_index: src pipe: %d, num of rules: %d, ebd pipe: %d, mux id: %d\n", 3016 flt_index.source_pipe_index, flt_index.rule_id_len, flt_index.embedded_pipe_index, flt_index.embedded_call_mux_id); 3017#endif 3018 len = sizeof(struct ipa_ioc_add_flt_rule) + prop->num_ext_props * sizeof(struct ipa_flt_rule_add); 3019 pFilteringTable = (struct ipa_ioc_add_flt_rule*)malloc(len); 3020 if (pFilteringTable == NULL) 3021 { 3022 IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); 3023 close(fd); 3024 return IPACM_FAILURE; 3025 } 3026 memset(pFilteringTable, 0, len); 3027 3028 pFilteringTable->commit = 1; 3029 pFilteringTable->ep = rx_prop->rx[0].src_pipe; 3030 pFilteringTable->global = false; 3031 pFilteringTable->ip = iptype; 3032 pFilteringTable->num_rules = prop->num_ext_props; 3033 3034 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); // Zero All Fields 3035 flt_rule_entry.at_rear = 1; 3036#ifdef FEATURE_IPA_V3 3037 if (flt_rule_entry.rule.eq_attrib.ipv4_frag_eq_present) 3038 flt_rule_entry.at_rear = 0; 3039#endif 3040 flt_rule_entry.flt_rule_hdl = -1; 3041 flt_rule_entry.status = -1; 3042 3043 flt_rule_entry.rule.retain_hdr = 0; 3044 flt_rule_entry.rule.to_uc = 0; 3045 flt_rule_entry.rule.eq_attrib_type = 1; 3046 if(iptype == IPA_IP_v4) 3047 { 3048 if (ipa_if_cate == ODU_IF && IPACM_Wan::isWan_Bridge_Mode()) 3049 { 3050 IPACMDBG_H("WAN, ODU are in bridge mode \n"); 3051 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 3052 } 3053 else 3054 { 3055 flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; 3056 } 3057 } 3058 else if(iptype == IPA_IP_v6) 3059 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 3060 else 3061 { 3062 IPACMERR("IP type is not expected.\n"); 3063 ret = IPACM_FAILURE; 3064 goto fail; 3065 } 3066 3067 index = IPACM_Iface::ipacmcfg->getFltRuleCount(rx_prop->rx[0].src_pipe, iptype); 3068 3069 for(cnt=0; cnt<prop->num_ext_props; cnt++) 3070 { 3071 memcpy(&flt_rule_entry.rule.eq_attrib, 3072 &prop->prop[cnt].eq_attrib, 3073 sizeof(prop->prop[cnt].eq_attrib)); 3074 flt_rule_entry.rule.rt_tbl_idx = prop->prop[cnt].rt_tbl_idx; 3075 3076 /* Handle XLAT configuration */ 3077 if ((iptype == IPA_IP_v4) && prop->prop[cnt].is_xlat_rule && (xlat_mux_id != 0)) 3078 { 3079 /* fill the value of meta-data */ 3080 value = xlat_mux_id; 3081 flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1; 3082 flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0; 3083 flt_rule_entry.rule.eq_attrib.metadata_meq32.value = (value & 0xFF) << 16; 3084 flt_rule_entry.rule.eq_attrib.metadata_meq32.mask = 0x00FF0000; 3085 IPACMDBG_H("xlat meta-data is modified for rule: %d has index %d with xlat_mux_id: %d\n", 3086 cnt, index, xlat_mux_id); 3087 } 3088 3089#ifdef FEATURE_IPACM_HAL 3090 /* add prefix equation in modem UL rules */ 3091 if(iptype == IPA_IP_v4) 3092 { 3093 flt_rule_entry.rule.eq_attrib.num_offset_meq_32++; 3094 if(flt_rule_entry.rule.eq_attrib.num_offset_meq_32 <= IPA_IPFLTR_NUM_MEQ_32_EQNS) 3095 { 3096 eq_index = flt_rule_entry.rule.eq_attrib.num_offset_meq_32 - 1; 3097#ifdef FEATURE_IPA_V3 3098 if(eq_index == 0) 3099 { 3100 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<5); 3101 } 3102 else 3103 { 3104 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<6); 3105 } 3106#else 3107 if(eq_index == 0) 3108 { 3109 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<2); 3110 } 3111 else 3112 { 3113 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<3); 3114 } 3115#endif 3116 flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].offset = 12; 3117 flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].mask = prefix[IPA_IP_v4].v4Mask; 3118 flt_rule_entry.rule.eq_attrib.offset_meq_32[eq_index].value = prefix[IPA_IP_v4].v4Addr; 3119 } 3120 else 3121 { 3122 IPACMERR("Run out of MEQ32 equation.\n"); 3123 flt_rule_entry.rule.eq_attrib.num_offset_meq_32--; 3124 } 3125 } 3126 else 3127 { 3128 flt_rule_entry.rule.eq_attrib.num_offset_meq_128++; 3129 if(flt_rule_entry.rule.eq_attrib.num_offset_meq_128 <= IPA_IPFLTR_NUM_MEQ_128_EQNS) 3130 { 3131 eq_index = flt_rule_entry.rule.eq_attrib.num_offset_meq_128 - 1; 3132#ifdef FEATURE_IPA_V3 3133 if(eq_index == 0) 3134 { 3135 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<3); 3136 } 3137 else 3138 { 3139 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<4); 3140 } 3141#else 3142 if(eq_index == 0) 3143 { 3144 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<9); 3145 } 3146 else 3147 { 3148 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<10); 3149 } 3150#endif 3151 flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].offset = 8; 3152 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 0) 3153 = prefix[IPA_IP_v6].v6Mask[3]; 3154 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 4) 3155 = prefix[IPA_IP_v6].v6Mask[2]; 3156 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 8) 3157 = prefix[IPA_IP_v6].v6Mask[1]; 3158 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].mask + 12) 3159 = prefix[IPA_IP_v6].v6Mask[0]; 3160 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 0) 3161 = prefix[IPA_IP_v6].v6Addr[3]; 3162 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 4) 3163 = prefix[IPA_IP_v6].v6Addr[2]; 3164 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 8) 3165 = prefix[IPA_IP_v6].v6Addr[1]; 3166 *(uint32_t *)(flt_rule_entry.rule.eq_attrib.offset_meq_128[eq_index].value + 12) 3167 = prefix[IPA_IP_v6].v6Addr[0]; 3168 } 3169 else 3170 { 3171 IPACMERR("Run out of MEQ128 equation.\n"); 3172 flt_rule_entry.rule.eq_attrib.num_offset_meq_128--; 3173 } 3174 } 3175#endif 3176 3177#ifdef FEATURE_IPA_V3 3178 flt_rule_entry.rule.hashable = prop->prop[cnt].is_rule_hashable; 3179 flt_rule_entry.rule.rule_id = prop->prop[cnt].rule_id; 3180 if(rx_prop->rx[0].attrib.attrib_mask & IPA_FLT_META_DATA) //turn on meta-data equation 3181 { 3182 flt_rule_entry.rule.eq_attrib.rule_eq_bitmap |= (1<<9); 3183 flt_rule_entry.rule.eq_attrib.metadata_meq32_present = 1; 3184 flt_rule_entry.rule.eq_attrib.metadata_meq32.offset = 0; 3185 flt_rule_entry.rule.eq_attrib.metadata_meq32.value |= rx_prop->rx[0].attrib.meta_data; 3186 flt_rule_entry.rule.eq_attrib.metadata_meq32.mask |= rx_prop->rx[0].attrib.meta_data_mask; 3187 } 3188#endif 3189 memcpy(&pFilteringTable->rules[cnt], &flt_rule_entry, sizeof(flt_rule_entry)); 3190 3191 IPACMDBG_H("Modem UL filtering rule %d has index %d\n", cnt, index); 3192#ifndef FEATURE_IPA_V3 3193 flt_index.filter_index_list[cnt].filter_index = index; 3194 flt_index.filter_index_list[cnt].filter_handle = prop->prop[cnt].filter_hdl; 3195#else /* defined (FEATURE_IPA_V3) */ 3196 flt_index.rule_id[cnt] = prop->prop[cnt].rule_id; 3197#endif 3198 index++; 3199 } 3200 3201 if(false == m_filtering.SendFilteringRuleIndex(&flt_index)) 3202 { 3203 IPACMERR("Error sending filtering rule index, aborting...\n"); 3204 ret = IPACM_FAILURE; 3205 goto fail; 3206 } 3207 3208 if(false == m_filtering.AddFilteringRule(pFilteringTable)) 3209 { 3210 IPACMERR("Error Adding RuleTable to Filtering, aborting...\n"); 3211 ret = IPACM_FAILURE; 3212 goto fail; 3213 } 3214 else 3215 { 3216 if(iptype == IPA_IP_v4) 3217 { 3218 for(i=0; i<pFilteringTable->num_rules; i++) 3219 { 3220 wan_ul_fl_rule_hdl_v4[num_wan_ul_fl_rule_v4] = pFilteringTable->rules[i].flt_rule_hdl; 3221 num_wan_ul_fl_rule_v4++; 3222 } 3223 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules); 3224 } 3225 else if(iptype == IPA_IP_v6) 3226 { 3227 for(i=0; i<pFilteringTable->num_rules; i++) 3228 { 3229 wan_ul_fl_rule_hdl_v6[num_wan_ul_fl_rule_v6] = pFilteringTable->rules[i].flt_rule_hdl; 3230 num_wan_ul_fl_rule_v6++; 3231 } 3232 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, iptype, pFilteringTable->num_rules); 3233 } 3234 else 3235 { 3236 IPACMERR("IP type is not expected.\n"); 3237 goto fail; 3238 } 3239 } 3240 3241fail: 3242 free(pFilteringTable); 3243 close(fd); 3244 return ret; 3245} 3246 3247int IPACM_Lan::handle_wan_down_v6(bool is_sta_mode) 3248{ 3249 ipa_fltr_installed_notif_req_msg_v01 flt_index; 3250 int fd; 3251 3252 fd = open(IPA_DEVICE_NAME, O_RDWR); 3253 if (0 == fd) 3254 { 3255 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); 3256 return IPACM_FAILURE; 3257 } 3258 3259 delete_ipv6_prefix_flt_rule(); 3260 3261 memset(ipv6_prefix, 0, sizeof(ipv6_prefix)); 3262 3263 if(is_sta_mode == false && modem_ul_v6_set == true) 3264 { 3265 if (num_wan_ul_fl_rule_v6 > MAX_WAN_UL_FILTER_RULES) 3266 { 3267 IPACMERR(" the number of rules (%d) are bigger than array (%d), aborting...\n", num_wan_ul_fl_rule_v6, MAX_WAN_UL_FILTER_RULES); 3268 close(fd); 3269 return IPACM_FAILURE; 3270 } 3271 if (num_wan_ul_fl_rule_v6 == 0) 3272 { 3273 IPACMERR("No modem UL rules were installed, return...\n"); 3274 close(fd); 3275 return IPACM_FAILURE; 3276 } 3277 3278 if (m_filtering.DeleteFilteringHdls(wan_ul_fl_rule_hdl_v6, 3279 IPA_IP_v6, num_wan_ul_fl_rule_v6) == false) 3280 { 3281 IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n"); 3282 close(fd); 3283 return IPACM_FAILURE; 3284 } 3285 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, num_wan_ul_fl_rule_v6); 3286 memset(wan_ul_fl_rule_hdl_v6, 0, MAX_WAN_UL_FILTER_RULES * sizeof(uint32_t)); 3287 num_wan_ul_fl_rule_v6 = 0; 3288 modem_ul_v6_set = false; 3289 3290 memset(&flt_index, 0, sizeof(flt_index)); 3291 flt_index.source_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[0].src_pipe); 3292 flt_index.install_status = IPA_QMI_RESULT_SUCCESS_V01; 3293#ifndef FEATURE_IPA_V3 3294 flt_index.filter_index_list_len = 0; 3295#else /* defined (FEATURE_IPA_V3) */ 3296 flt_index.rule_id_valid = 1; 3297 flt_index.rule_id_len = 0; 3298#endif 3299 flt_index.embedded_pipe_index_valid = 1; 3300 flt_index.embedded_pipe_index = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, IPA_CLIENT_APPS_LAN_WAN_PROD); 3301 flt_index.retain_header_valid = 1; 3302 flt_index.retain_header = 0; 3303 flt_index.embedded_call_mux_id_valid = 1; 3304 flt_index.embedded_call_mux_id = IPACM_Iface::ipacmcfg->GetQmapId(); 3305 if(false == m_filtering.SendFilteringRuleIndex(&flt_index)) 3306 { 3307 IPACMERR("Error sending filtering rule index, aborting...\n"); 3308 close(fd); 3309 return IPACM_FAILURE; 3310 } 3311 } 3312 else 3313 { 3314 if (m_filtering.DeleteFilteringHdls(&dft_v6fl_rule_hdl[IPV6_DEFAULT_FILTERTING_RULES], 3315 IPA_IP_v6, 1) == false) 3316 { 3317 IPACMERR("Error Adding RuleTable(1) to Filtering, aborting...\n"); 3318 close(fd); 3319 return IPACM_FAILURE; 3320 } 3321 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 3322 } 3323 close(fd); 3324 return IPACM_SUCCESS; 3325} 3326 3327int IPACM_Lan::reset_to_dummy_flt_rule(ipa_ip_type iptype, uint32_t rule_hdl) 3328{ 3329 int len, res = IPACM_SUCCESS; 3330 struct ipa_flt_rule_mdfy flt_rule; 3331 struct ipa_ioc_mdfy_flt_rule* pFilteringTable; 3332 3333 IPACMDBG_H("Reset flt rule to dummy, IP type: %d, hdl: %d\n", iptype, rule_hdl); 3334 len = sizeof(struct ipa_ioc_mdfy_flt_rule) + sizeof(struct ipa_flt_rule_mdfy); 3335 pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); 3336 3337 if (pFilteringTable == NULL) 3338 { 3339 IPACMERR("Error allocate flt rule memory...\n"); 3340 return IPACM_FAILURE; 3341 } 3342 memset(pFilteringTable, 0, len); 3343 3344 pFilteringTable->commit = 1; 3345 pFilteringTable->ip = iptype; 3346 pFilteringTable->num_rules = 1; 3347 3348 memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); 3349 flt_rule.status = -1; 3350 flt_rule.rule_hdl = rule_hdl; 3351 3352 flt_rule.rule.retain_hdr = 0; 3353 flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; 3354 3355 if(iptype == IPA_IP_v4) 3356 { 3357 IPACMDBG_H("Reset IPv4 flt rule to dummy\n"); 3358 3359 flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; 3360 flt_rule.rule.attrib.u.v4.dst_addr = ~0; 3361 flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; 3362 flt_rule.rule.attrib.u.v4.src_addr = ~0; 3363 flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; 3364 3365 memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); 3366 if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) 3367 { 3368 IPACMERR("Error modifying filtering rule.\n"); 3369 res = IPACM_FAILURE; 3370 goto fail; 3371 } 3372 else 3373 { 3374 IPACMDBG_H("Flt rule reset to dummy, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl, 3375 pFilteringTable->rules[0].status); 3376 } 3377 } 3378 else if(iptype == IPA_IP_v6) 3379 { 3380 IPACMDBG_H("Reset IPv6 flt rule to dummy\n"); 3381 3382 flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; 3383 flt_rule.rule.attrib.u.v6.src_addr[0] = ~0; 3384 flt_rule.rule.attrib.u.v6.src_addr[1] = ~0; 3385 flt_rule.rule.attrib.u.v6.src_addr[2] = ~0; 3386 flt_rule.rule.attrib.u.v6.src_addr[3] = ~0; 3387 flt_rule.rule.attrib.u.v6.src_addr_mask[0] = ~0; 3388 flt_rule.rule.attrib.u.v6.src_addr_mask[1] = ~0; 3389 flt_rule.rule.attrib.u.v6.src_addr_mask[2] = ~0; 3390 flt_rule.rule.attrib.u.v6.src_addr_mask[3] = ~0; 3391 flt_rule.rule.attrib.u.v6.dst_addr[0] = ~0; 3392 flt_rule.rule.attrib.u.v6.dst_addr[1] = ~0; 3393 flt_rule.rule.attrib.u.v6.dst_addr[2] = ~0; 3394 flt_rule.rule.attrib.u.v6.dst_addr[3] = ~0; 3395 flt_rule.rule.attrib.u.v6.dst_addr_mask[0] = ~0; 3396 flt_rule.rule.attrib.u.v6.dst_addr_mask[1] = ~0; 3397 flt_rule.rule.attrib.u.v6.dst_addr_mask[2] = ~0; 3398 flt_rule.rule.attrib.u.v6.dst_addr_mask[3] = ~0; 3399 3400 3401 memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); 3402 if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) 3403 { 3404 IPACMERR("Error modifying filtering rule.\n"); 3405 res = IPACM_FAILURE; 3406 goto fail; 3407 } 3408 else 3409 { 3410 IPACMDBG_H("Flt rule reset to dummy, hdl: 0x%x, status: %d\n", pFilteringTable->rules[0].rule_hdl, 3411 pFilteringTable->rules[0].status); 3412 } 3413 } 3414 else 3415 { 3416 IPACMERR("IP type is not expected.\n"); 3417 res = IPACM_FAILURE; 3418 goto fail; 3419 } 3420 3421fail: 3422 free(pFilteringTable); 3423 return res; 3424} 3425 3426void IPACM_Lan::post_del_self_evt() 3427{ 3428 ipacm_cmd_q_data evt; 3429 ipacm_event_data_fid* fid; 3430 fid = (ipacm_event_data_fid*)malloc(sizeof(ipacm_event_data_fid)); 3431 if(fid == NULL) 3432 { 3433 IPACMERR("Failed to allocate fid memory.\n"); 3434 return; 3435 } 3436 memset(fid, 0, sizeof(ipacm_event_data_fid)); 3437 memset(&evt, 0, sizeof(ipacm_cmd_q_data)); 3438 3439 fid->if_index = ipa_if_num; 3440 3441 evt.evt_data = (void*)fid; 3442 evt.event = IPA_LAN_DELETE_SELF; 3443 3444 IPACMDBG_H("Posting event IPA_LAN_DELETE_SELF\n"); 3445 IPACM_EvtDispatcher::PostEvt(&evt); 3446} 3447 3448/*handle reset usb-client rt-rules */ 3449int IPACM_Lan::handle_lan_client_reset_rt(ipa_ip_type iptype) 3450{ 3451 uint32_t i; 3452 int res = IPACM_SUCCESS; 3453 3454 /* clean eth-client routing rules */ 3455 IPACMDBG_H("left %d eth clients need to be deleted \n ", num_eth_client); 3456 for (i = 0; i < num_eth_client; i++) 3457 { 3458 res = delete_eth_rtrules(i, iptype); 3459 if (res != IPACM_SUCCESS) 3460 { 3461 IPACMERR("Failed to delete old iptype(%d) rules.\n", iptype); 3462 return res; 3463 } 3464 } /* end of for loop */ 3465 3466 /* Reset ip-address */ 3467 for (i = 0; i < num_eth_client; i++) 3468 { 3469 if(iptype == IPA_IP_v4) 3470 { 3471 get_client_memptr(eth_client, i)->ipv4_set = false; 3472 } 3473 else 3474 { 3475 get_client_memptr(eth_client, i)->ipv6_set = 0; 3476 } 3477 } /* end of for loop */ 3478 return res; 3479} 3480 3481int IPACM_Lan::install_ipv4_icmp_flt_rule() 3482{ 3483 int len; 3484 struct ipa_ioc_add_flt_rule* flt_rule; 3485 struct ipa_flt_rule_add flt_rule_entry; 3486 3487 if(rx_prop != NULL) 3488 { 3489 len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); 3490 3491 flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len); 3492 if (!flt_rule) 3493 { 3494 IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); 3495 return IPACM_FAILURE; 3496 } 3497 3498 flt_rule->commit = 1; 3499 flt_rule->ep = rx_prop->rx[0].src_pipe; 3500 flt_rule->global = false; 3501 flt_rule->ip = IPA_IP_v4; 3502 flt_rule->num_rules = 1; 3503 3504 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 3505 3506 flt_rule_entry.rule.retain_hdr = 1; 3507 flt_rule_entry.rule.to_uc = 0; 3508 flt_rule_entry.rule.eq_attrib_type = 0; 3509 flt_rule_entry.at_rear = true; 3510 flt_rule_entry.flt_rule_hdl = -1; 3511 flt_rule_entry.status = -1; 3512 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 3513#ifdef FEATURE_IPA_V3 3514 flt_rule_entry.rule.hashable = true; 3515#endif 3516 memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); 3517 3518 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_PROTOCOL; 3519 flt_rule_entry.rule.attrib.u.v4.protocol = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP; 3520 memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3521 3522 if (m_filtering.AddFilteringRule(flt_rule) == false) 3523 { 3524 IPACMERR("Error Adding Filtering rule, aborting...\n"); 3525 free(flt_rule); 3526 return IPACM_FAILURE; 3527 } 3528 else 3529 { 3530 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, 1); 3531 ipv4_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl; 3532 IPACMDBG_H("IPv4 icmp filter rule HDL:0x%x\n", ipv4_icmp_flt_rule_hdl[0]); 3533 free(flt_rule); 3534 } 3535 } 3536 return IPACM_SUCCESS; 3537} 3538 3539int IPACM_Lan::install_ipv6_icmp_flt_rule() 3540{ 3541 3542 int len; 3543 struct ipa_ioc_add_flt_rule* flt_rule; 3544 struct ipa_flt_rule_add flt_rule_entry; 3545 3546 if(rx_prop != NULL) 3547 { 3548 len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); 3549 3550 flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len); 3551 if (!flt_rule) 3552 { 3553 IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); 3554 return IPACM_FAILURE; 3555 } 3556 3557 flt_rule->commit = 1; 3558 flt_rule->ep = rx_prop->rx[0].src_pipe; 3559 flt_rule->global = false; 3560 flt_rule->ip = IPA_IP_v6; 3561 flt_rule->num_rules = 1; 3562 3563 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 3564 3565 flt_rule_entry.rule.retain_hdr = 1; 3566 flt_rule_entry.rule.to_uc = 0; 3567 flt_rule_entry.rule.eq_attrib_type = 0; 3568 flt_rule_entry.at_rear = true; 3569 flt_rule_entry.flt_rule_hdl = -1; 3570 flt_rule_entry.status = -1; 3571 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 3572#ifdef FEATURE_IPA_V3 3573 flt_rule_entry.rule.hashable = false; 3574#endif 3575 memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); 3576 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_NEXT_HDR; 3577 flt_rule_entry.rule.attrib.u.v6.next_hdr = (uint8_t)IPACM_FIREWALL_IPPROTO_ICMP6; 3578 memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3579 3580 if (m_filtering.AddFilteringRule(flt_rule) == false) 3581 { 3582 IPACMERR("Error Adding Filtering rule, aborting...\n"); 3583 free(flt_rule); 3584 return IPACM_FAILURE; 3585 } 3586 else 3587 { 3588 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 3589 ipv6_icmp_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl; 3590 IPACMDBG_H("IPv6 icmp filter rule HDL:0x%x\n", ipv6_icmp_flt_rule_hdl[0]); 3591 free(flt_rule); 3592 } 3593 } 3594 return IPACM_SUCCESS; 3595} 3596 3597int IPACM_Lan::add_dummy_private_subnet_flt_rule(ipa_ip_type iptype) 3598{ 3599 if(rx_prop == NULL) 3600 { 3601 IPACMDBG_H("There is no rx_prop for iface %s, not able to add dummy private subnet filtering rule.\n", dev_name); 3602 return 0; 3603 } 3604 3605 if(iptype == IPA_IP_v6) 3606 { 3607 IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\n", dev_name); 3608 return 0; 3609 } 3610 int i, len, res = IPACM_SUCCESS; 3611 struct ipa_flt_rule_add flt_rule; 3612 ipa_ioc_add_flt_rule* pFilteringTable; 3613 3614 len = sizeof(struct ipa_ioc_add_flt_rule) + IPA_MAX_PRIVATE_SUBNET_ENTRIES * sizeof(struct ipa_flt_rule_add); 3615 3616 pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len); 3617 if (pFilteringTable == NULL) 3618 { 3619 IPACMERR("Error allocate flt table memory...\n"); 3620 return IPACM_FAILURE; 3621 } 3622 memset(pFilteringTable, 0, len); 3623 3624 pFilteringTable->commit = 1; 3625 pFilteringTable->ep = rx_prop->rx[0].src_pipe; 3626 pFilteringTable->global = false; 3627 pFilteringTable->ip = iptype; 3628 pFilteringTable->num_rules = IPA_MAX_PRIVATE_SUBNET_ENTRIES; 3629 3630 memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add)); 3631 3632 flt_rule.rule.retain_hdr = 0; 3633 flt_rule.at_rear = true; 3634 flt_rule.flt_rule_hdl = -1; 3635 flt_rule.status = -1; 3636 flt_rule.rule.action = IPA_PASS_TO_EXCEPTION; 3637#ifdef FEATURE_IPA_V3 3638 flt_rule.rule.hashable = true; 3639#endif 3640 memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, 3641 sizeof(flt_rule.rule.attrib)); 3642 3643 if(iptype == IPA_IP_v4) 3644 { 3645 flt_rule.rule.attrib.attrib_mask = IPA_FLT_SRC_ADDR | IPA_FLT_DST_ADDR; 3646 flt_rule.rule.attrib.u.v4.src_addr_mask = ~0; 3647 flt_rule.rule.attrib.u.v4.src_addr = ~0; 3648 flt_rule.rule.attrib.u.v4.dst_addr_mask = ~0; 3649 flt_rule.rule.attrib.u.v4.dst_addr = ~0; 3650 3651 for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++) 3652 { 3653 memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_add)); 3654 } 3655 3656 if (false == m_filtering.AddFilteringRule(pFilteringTable)) 3657 { 3658 IPACMERR("Error adding dummy private subnet v4 flt rule\n"); 3659 res = IPACM_FAILURE; 3660 goto fail; 3661 } 3662 else 3663 { 3664 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v4, IPA_MAX_PRIVATE_SUBNET_ENTRIES); 3665 /* copy filter rule hdls */ 3666 for (int i = 0; i < IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++) 3667 { 3668 if (pFilteringTable->rules[i].status == 0) 3669 { 3670 private_fl_rule_hdl[i] = pFilteringTable->rules[i].flt_rule_hdl; 3671 IPACMDBG_H("Private subnet v4 flt rule %d hdl:0x%x\n", i, private_fl_rule_hdl[i]); 3672 } 3673 else 3674 { 3675 IPACMERR("Failed adding lan2lan v4 flt rule %d\n", i); 3676 res = IPACM_FAILURE; 3677 goto fail; 3678 } 3679 } 3680 } 3681 } 3682fail: 3683 free(pFilteringTable); 3684 return res; 3685} 3686 3687int IPACM_Lan::handle_private_subnet_android(ipa_ip_type iptype) 3688{ 3689 int i, len, res = IPACM_SUCCESS; 3690 struct ipa_flt_rule_mdfy flt_rule; 3691 struct ipa_ioc_mdfy_flt_rule* pFilteringTable; 3692 3693 if (rx_prop == NULL) 3694 { 3695 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); 3696 return IPACM_SUCCESS; 3697 } 3698 3699 if(iptype == IPA_IP_v6) 3700 { 3701 IPACMDBG_H("There is no ipv6 dummy filter rules needed for iface %s\n", dev_name); 3702 return 0; 3703 } 3704 else 3705 { 3706 for(i=0; i<IPA_MAX_PRIVATE_SUBNET_ENTRIES; i++) 3707 { 3708 reset_to_dummy_flt_rule(IPA_IP_v4, private_fl_rule_hdl[i]); 3709 } 3710 3711 len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_mdfy); 3712 pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len); 3713 if (!pFilteringTable) 3714 { 3715 IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n"); 3716 return IPACM_FAILURE; 3717 } 3718 memset(pFilteringTable, 0, len); 3719 3720 pFilteringTable->commit = 1; 3721 pFilteringTable->ip = iptype; 3722 pFilteringTable->num_rules = (uint8_t)IPACM_Iface::ipacmcfg->ipa_num_private_subnet; 3723 3724 /* Make LAN-traffic always go A5, use default IPA-RT table */ 3725 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_default_v4)) 3726 { 3727 IPACMERR("Failed to get routing table handle.\n"); 3728 res = IPACM_FAILURE; 3729 goto fail; 3730 } 3731 3732 memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy)); 3733 flt_rule.status = -1; 3734 3735 flt_rule.rule.retain_hdr = 1; 3736 flt_rule.rule.to_uc = 0; 3737 flt_rule.rule.action = IPA_PASS_TO_ROUTING; 3738 flt_rule.rule.eq_attrib_type = 0; 3739 flt_rule.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_default_v4.hdl; 3740 IPACMDBG_H("Private filter rule use table: %s\n",IPACM_Iface::ipacmcfg->rt_tbl_default_v4.name); 3741 3742 memcpy(&flt_rule.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule.rule.attrib)); 3743 flt_rule.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 3744 3745 for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++) 3746 { 3747 flt_rule.rule_hdl = private_fl_rule_hdl[i]; 3748 flt_rule.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask; 3749 flt_rule.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr; 3750 memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy)); 3751 IPACMDBG_H(" IPACM private subnet_addr as: 0x%x entry(%d)\n", flt_rule.rule.attrib.u.v4.dst_addr, i); 3752 } 3753 3754 if (false == m_filtering.ModifyFilteringRule(pFilteringTable)) 3755 { 3756 IPACMERR("Failed to modify private subnet filtering rules.\n"); 3757 res = IPACM_FAILURE; 3758 goto fail; 3759 } 3760 } 3761fail: 3762 if(pFilteringTable != NULL) 3763 { 3764 free(pFilteringTable); 3765 } 3766 return res; 3767} 3768 3769int IPACM_Lan::install_ipv6_prefix_flt_rule(uint32_t* prefix) 3770{ 3771 if(prefix == NULL) 3772 { 3773 IPACMERR("IPv6 prefix is empty.\n"); 3774 return IPACM_FAILURE; 3775 } 3776 IPACMDBG_H("Receive IPv6 prefix: 0x%08x%08x.\n", prefix[0], prefix[1]); 3777 3778 int len; 3779 struct ipa_ioc_add_flt_rule* flt_rule; 3780 struct ipa_flt_rule_add flt_rule_entry; 3781 3782 if(rx_prop != NULL) 3783 { 3784 len = sizeof(struct ipa_ioc_add_flt_rule) + sizeof(struct ipa_flt_rule_add); 3785 3786 flt_rule = (struct ipa_ioc_add_flt_rule *)calloc(1, len); 3787 if (!flt_rule) 3788 { 3789 IPACMERR("Error Locate ipa_flt_rule_add memory...\n"); 3790 return IPACM_FAILURE; 3791 } 3792 3793 flt_rule->commit = 1; 3794 flt_rule->ep = rx_prop->rx[0].src_pipe; 3795 flt_rule->global = false; 3796 flt_rule->ip = IPA_IP_v6; 3797 flt_rule->num_rules = 1; 3798 3799 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); 3800 3801 flt_rule_entry.rule.retain_hdr = 1; 3802 flt_rule_entry.rule.to_uc = 0; 3803 flt_rule_entry.rule.eq_attrib_type = 0; 3804 flt_rule_entry.at_rear = true; 3805 flt_rule_entry.flt_rule_hdl = -1; 3806 flt_rule_entry.status = -1; 3807 flt_rule_entry.rule.action = IPA_PASS_TO_EXCEPTION; 3808#ifdef FEATURE_IPA_V3 3809 flt_rule_entry.rule.hashable = true; 3810#endif 3811 memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); 3812 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 3813 flt_rule_entry.rule.attrib.u.v6.dst_addr[0] = prefix[0]; 3814 flt_rule_entry.rule.attrib.u.v6.dst_addr[1] = prefix[1]; 3815 flt_rule_entry.rule.attrib.u.v6.dst_addr[2] = 0x0; 3816 flt_rule_entry.rule.attrib.u.v6.dst_addr[3] = 0x0; 3817 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[0] = 0xFFFFFFFF; 3818 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[1] = 0xFFFFFFFF; 3819 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[2] = 0x0; 3820 flt_rule_entry.rule.attrib.u.v6.dst_addr_mask[3] = 0x0; 3821 memcpy(&(flt_rule->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); 3822 3823 if (m_filtering.AddFilteringRule(flt_rule) == false) 3824 { 3825 IPACMERR("Error Adding Filtering rule, aborting...\n"); 3826 free(flt_rule); 3827 return IPACM_FAILURE; 3828 } 3829 else 3830 { 3831 IPACM_Iface::ipacmcfg->increaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, 1); 3832 ipv6_prefix_flt_rule_hdl[0] = flt_rule->rules[0].flt_rule_hdl; 3833 IPACMDBG_H("IPv6 prefix filter rule HDL:0x%x\n", ipv6_prefix_flt_rule_hdl[0]); 3834 free(flt_rule); 3835 } 3836 } 3837 return IPACM_SUCCESS; 3838} 3839 3840void IPACM_Lan::delete_ipv6_prefix_flt_rule() 3841{ 3842 if(m_filtering.DeleteFilteringHdls(ipv6_prefix_flt_rule_hdl, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE) == false) 3843 { 3844 IPACMERR("Failed to delete ipv6 prefix flt rule.\n"); 3845 return; 3846 } 3847 IPACM_Iface::ipacmcfg->decreaseFltRuleCount(rx_prop->rx[0].src_pipe, IPA_IP_v6, NUM_IPV6_PREFIX_FLT_RULE); 3848 return; 3849} 3850 3851int IPACM_Lan::handle_addr_evt_odu_bridge(ipacm_event_data_addr* data) 3852{ 3853 int fd, res = IPACM_SUCCESS; 3854 struct in6_addr ipv6_addr; 3855 if(data == NULL) 3856 { 3857 IPACMERR("Failed to get interface IP address.\n"); 3858 return IPACM_FAILURE; 3859 } 3860 3861 if(data->iptype == IPA_IP_v6) 3862 { 3863 fd = open(IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU, O_RDWR); 3864 if(fd == 0) 3865 { 3866 IPACMERR("Failed to open %s.\n", IPACM_Iface::ipacmcfg->DEVICE_NAME_ODU); 3867 return IPACM_FAILURE; 3868 } 3869 3870 memcpy(&ipv6_addr, data->ipv6_addr, sizeof(struct in6_addr)); 3871 3872 if( ioctl(fd, ODU_BRIDGE_IOC_SET_LLV6_ADDR, &ipv6_addr) ) 3873 { 3874 IPACMERR("Failed to write IPv6 address to odu driver.\n"); 3875 res = IPACM_FAILURE; 3876 } 3877 num_dft_rt_v6++; 3878 close(fd); 3879 } 3880 3881 return res; 3882} 3883 3884ipa_hdr_proc_type IPACM_Lan::eth_bridge_get_hdr_proc_type(ipa_hdr_l2_type t1, ipa_hdr_l2_type t2) 3885{ 3886 if(t1 == IPA_HDR_L2_ETHERNET_II) 3887 { 3888 if(t2 == IPA_HDR_L2_ETHERNET_II) 3889 { 3890 return IPA_HDR_PROC_ETHII_TO_ETHII; 3891 } 3892 if(t2 == IPA_HDR_L2_802_3) 3893 { 3894 return IPA_HDR_PROC_ETHII_TO_802_3; 3895 } 3896 } 3897 3898 if(t1 == IPA_HDR_L2_802_3) 3899 { 3900 if(t2 == IPA_HDR_L2_ETHERNET_II) 3901 { 3902 return IPA_HDR_PROC_802_3_TO_ETHII; 3903 } 3904 if(t2 == IPA_HDR_L2_802_3) 3905 { 3906 return IPA_HDR_PROC_802_3_TO_802_3; 3907 } 3908 } 3909 3910 return IPA_HDR_PROC_NONE; 3911} 3912 3913int IPACM_Lan::eth_bridge_get_hdr_template_hdl(uint32_t* hdr_hdl) 3914{ 3915 if(hdr_hdl == NULL) 3916 { 3917 IPACMDBG_H("Hdr handle pointer is empty.\n"); 3918 return IPACM_FAILURE; 3919 } 3920 3921 struct ipa_ioc_get_hdr hdr; 3922 memset(&hdr, 0, sizeof(hdr)); 3923 3924 memcpy(hdr.name, tx_prop->tx[0].hdr_name, sizeof(hdr.name)); 3925 if(m_header.GetHeaderHandle(&hdr) == false) 3926 { 3927 IPACMERR("Failed to get template hdr hdl.\n"); 3928 return IPACM_FAILURE; 3929 } 3930 3931 *hdr_hdl = hdr.hdl; 3932 return IPACM_SUCCESS; 3933} 3934 3935int IPACM_Lan::handle_cradle_wan_mode_switch(bool is_wan_bridge_mode) 3936{ 3937 struct ipa_flt_rule_mdfy flt_rule_entry; 3938 int len = 0; 3939 ipa_ioc_mdfy_flt_rule *m_pFilteringTable; 3940 3941 IPACMDBG_H("Handle wan mode swtich: is wan bridge mode?%d\n", is_wan_bridge_mode); 3942 3943 if (rx_prop == NULL) 3944 { 3945 IPACMDBG_H("No rx properties registered for iface %s\n", dev_name); 3946 return IPACM_SUCCESS; 3947 } 3948 3949 len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (1 * sizeof(struct ipa_flt_rule_mdfy)); 3950 m_pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len); 3951 if (m_pFilteringTable == NULL) 3952 { 3953 PERROR("Error Locate ipa_ioc_mdfy_flt_rule memory...\n"); 3954 return IPACM_FAILURE; 3955 } 3956 3957 m_pFilteringTable->commit = 1; 3958 m_pFilteringTable->ip = IPA_IP_v4; 3959 m_pFilteringTable->num_rules = (uint8_t)1; 3960 3961 IPACMDBG_H("Retrieving routing hanle for table: %s\n", 3962 IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.name); 3963 if (false == m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4)) 3964 { 3965 IPACMERR("m_routing.GetRoutingTable(&IPACM_Iface::ipacmcfg->rt_tbl_wan_v4=0x%p) Failed.\n", 3966 &IPACM_Iface::ipacmcfg->rt_tbl_wan_v4); 3967 free(m_pFilteringTable); 3968 return IPACM_FAILURE; 3969 } 3970 IPACMDBG_H("Routing handle for table: %d\n", IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl); 3971 3972 3973 memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_mdfy)); // Zero All Fields 3974 flt_rule_entry.status = -1; 3975 flt_rule_entry.rule_hdl = lan_wan_fl_rule_hdl[0]; 3976 3977 flt_rule_entry.rule.retain_hdr = 0; 3978 flt_rule_entry.rule.to_uc = 0; 3979 flt_rule_entry.rule.eq_attrib_type = 0; 3980 if(is_wan_bridge_mode) 3981 { 3982 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 3983 } 3984 else 3985 { 3986 flt_rule_entry.rule.action = IPA_PASS_TO_SRC_NAT; 3987 } 3988 flt_rule_entry.rule.rt_tbl_hdl = IPACM_Iface::ipacmcfg->rt_tbl_wan_v4.hdl; 3989 3990 memcpy(&flt_rule_entry.rule.attrib, 3991 &rx_prop->rx[0].attrib, 3992 sizeof(flt_rule_entry.rule.attrib)); 3993 3994 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_DST_ADDR; 3995 flt_rule_entry.rule.attrib.u.v4.dst_addr_mask = 0x0; 3996 flt_rule_entry.rule.attrib.u.v4.dst_addr = 0x0; 3997 3998 memcpy(&m_pFilteringTable->rules[0], &flt_rule_entry, sizeof(flt_rule_entry)); 3999 if (false == m_filtering.ModifyFilteringRule(m_pFilteringTable)) 4000 { 4001 IPACMERR("Error Modifying RuleTable(0) to Filtering, aborting...\n"); 4002 free(m_pFilteringTable); 4003 return IPACM_FAILURE; 4004 } 4005 else 4006 { 4007 IPACMDBG_H("flt rule hdl = %d, status = %d\n", 4008 m_pFilteringTable->rules[0].rule_hdl, 4009 m_pFilteringTable->rules[0].status); 4010 } 4011 free(m_pFilteringTable); 4012 return IPACM_SUCCESS; 4013} 4014 4015/*handle reset usb-client rt-rules */ 4016int IPACM_Lan::handle_tethering_stats_event(ipa_get_data_stats_resp_msg_v01 *data) 4017{ 4018 int fd; 4019 uint32_t pipe_len, cnt; 4020 uint64_t num_ul_packets, num_ul_bytes; 4021 uint64_t num_dl_packets, num_dl_bytes; 4022 bool ul_pipe_found, dl_pipe_found; 4023 FILE *fp = NULL; 4024 4025 fd = open(IPA_DEVICE_NAME, O_RDWR); 4026 if (fd < 0) 4027 { 4028 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); 4029 return IPACM_FAILURE; 4030 } 4031 4032 4033 ul_pipe_found = false; 4034 dl_pipe_found = false; 4035 num_ul_packets = 0; 4036 num_dl_packets = 0; 4037 num_ul_bytes = 0; 4038 num_dl_bytes = 0; 4039 4040 if (data->dl_dst_pipe_stats_list_valid) 4041 { 4042 if(tx_prop != NULL) 4043 { 4044 for (pipe_len = 0; pipe_len < data->dl_dst_pipe_stats_list_len; pipe_len++) 4045 { 4046 IPACMDBG_H("Check entry(%d) dl_dst_pipe(%d)\n", pipe_len, data->dl_dst_pipe_stats_list[pipe_len].pipe_index); 4047 for (cnt=0; cnt<tx_prop->num_tx_props; cnt++) 4048 { 4049 IPACMDBG_H("Check Tx_prop_entry(%d) pipe(%d)\n", cnt, ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe)); 4050 if(ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe) == (int)data->dl_dst_pipe_stats_list[pipe_len].pipe_index) 4051 { 4052 /* update the DL stats */ 4053 dl_pipe_found = true; 4054 num_dl_packets += data->dl_dst_pipe_stats_list[pipe_len].num_ipv4_packets; 4055 num_dl_packets += data->dl_dst_pipe_stats_list[pipe_len].num_ipv6_packets; 4056 num_dl_bytes += data->dl_dst_pipe_stats_list[pipe_len].num_ipv4_bytes; 4057 num_dl_bytes += data->dl_dst_pipe_stats_list[pipe_len].num_ipv6_bytes; 4058 IPACMDBG_H("Got matched dst-pipe (%d) from %d tx props\n", data->dl_dst_pipe_stats_list[pipe_len].pipe_index, cnt); 4059 IPACMDBG_H("DL_packets:(%lu) DL_bytes:(%lu) \n", num_dl_packets, num_dl_bytes); 4060 break; 4061 } 4062 } 4063 } 4064 } 4065 } 4066 4067 if (data->ul_src_pipe_stats_list_valid) 4068 { 4069 if(rx_prop != NULL) 4070 { 4071 for (pipe_len = 0; pipe_len < data->ul_src_pipe_stats_list_len; pipe_len++) 4072 { 4073 IPACMDBG_H("Check entry(%d) dl_dst_pipe(%d)\n", pipe_len, data->ul_src_pipe_stats_list[pipe_len].pipe_index); 4074 for (cnt=0; cnt < rx_prop->num_rx_props; cnt++) 4075 { 4076 IPACMDBG_H("Check Rx_prop_entry(%d) pipe(%d)\n", cnt, ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe)); 4077 //Typecasting to avoid -Wall -Werror errors 4078 if(ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe) == (int)data->ul_src_pipe_stats_list[pipe_len].pipe_index) 4079 { 4080 /* update the UL stats */ 4081 ul_pipe_found = true; 4082 num_ul_packets += data->ul_src_pipe_stats_list[pipe_len].num_ipv4_packets; 4083 num_ul_packets += data->ul_src_pipe_stats_list[pipe_len].num_ipv6_packets; 4084 num_ul_bytes += data->ul_src_pipe_stats_list[pipe_len].num_ipv4_bytes; 4085 num_ul_bytes += data->ul_src_pipe_stats_list[pipe_len].num_ipv6_bytes; 4086 IPACMDBG_H("Got matched dst-pipe (%d) from %d tx props\n", data->ul_src_pipe_stats_list[pipe_len].pipe_index, cnt); 4087 IPACMDBG_H("UL_packets:(%lu) UL_bytes:(%lu) \n", num_ul_packets, num_ul_bytes); 4088 break; 4089 } 4090 } 4091 } 4092 } 4093 } 4094 close(fd); 4095 4096 if (ul_pipe_found || dl_pipe_found) 4097 { 4098 IPACMDBG_H("Update IPA_TETHERING_STATS_UPDATE_EVENT, TX(P%lu/B%lu) RX(P%lu/B%lu) DEV(%s) to LTE(%s) \n", 4099 num_ul_packets, 4100 num_ul_bytes, 4101 num_dl_packets, 4102 num_dl_bytes, 4103 dev_name, 4104 IPACM_Wan::wan_up_dev_name); 4105 fp = fopen(IPA_PIPE_STATS_FILE_NAME, "w"); 4106 if ( fp == NULL ) 4107 { 4108 IPACMERR("Failed to write pipe stats to %s, error is %d - %s\n", 4109 IPA_PIPE_STATS_FILE_NAME, errno, strerror(errno)); 4110 return IPACM_FAILURE; 4111 } 4112 4113 fprintf(fp, PIPE_STATS, 4114 dev_name, 4115 IPACM_Wan::wan_up_dev_name, 4116 num_ul_bytes, 4117 num_ul_packets, 4118 num_dl_bytes, 4119 num_dl_packets); 4120 fclose(fp); 4121 } 4122 return IPACM_SUCCESS; 4123} 4124 4125/*handle tether client */ 4126int IPACM_Lan::handle_tethering_client(bool reset, ipacm_client_enum ipa_client) 4127{ 4128 int fd, ret = IPACM_SUCCESS; 4129 uint32_t cnt; 4130 int fd_wwan_ioctl = open(WWAN_QMI_IOCTL_DEVICE_NAME, O_RDWR); 4131 wan_ioctl_set_tether_client_pipe tether_client; 4132 4133 if(fd_wwan_ioctl < 0) 4134 { 4135 IPACMERR("Failed to open %s.\n",WWAN_QMI_IOCTL_DEVICE_NAME); 4136 return IPACM_FAILURE; 4137 } 4138 4139 fd = open(IPA_DEVICE_NAME, O_RDWR); 4140 if (fd < 0) 4141 { 4142 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME); 4143 close(fd_wwan_ioctl); 4144 return IPACM_FAILURE; 4145 } 4146 4147 memset(&tether_client, 0, sizeof(tether_client)); 4148 tether_client.reset_client = reset; 4149 tether_client.ipa_client = ipa_client; 4150 4151 if(tx_prop != NULL) 4152 { 4153 tether_client.dl_dst_pipe_len = tx_prop->num_tx_props; 4154 for (cnt = 0; cnt < tx_prop->num_tx_props; cnt++) 4155 { 4156 IPACMDBG_H("Tx(%d), dst_pipe: %d, ipa_pipe: %d\n", 4157 cnt, tx_prop->tx[cnt].dst_pipe, 4158 ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe)); 4159 tether_client.dl_dst_pipe_list[cnt] = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, tx_prop->tx[cnt].dst_pipe); 4160 } 4161 } 4162 4163 if(rx_prop != NULL) 4164 { 4165 tether_client.ul_src_pipe_len = rx_prop->num_rx_props; 4166 for (cnt = 0; cnt < rx_prop->num_rx_props; cnt++) 4167 { 4168 IPACMDBG_H("Rx(%d), src_pipe: %d, ipa_pipe: %d\n", 4169 cnt, rx_prop->rx[cnt].src_pipe, 4170 ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe)); 4171 tether_client.ul_src_pipe_list[cnt] = ioctl(fd, IPA_IOC_QUERY_EP_MAPPING, rx_prop->rx[cnt].src_pipe); 4172 } 4173 } 4174 4175 ret = ioctl(fd_wwan_ioctl, WAN_IOC_SET_TETHER_CLIENT_PIPE, &tether_client); 4176 if (ret != 0) 4177 { 4178 IPACMERR("Failed set tether-client-pipe %p with ret %d\n ", &tether_client, ret); 4179 } 4180 IPACMDBG("Set tether-client-pipe %p\n", &tether_client); 4181 close(fd); 4182 close(fd_wwan_ioctl); 4183 return ret; 4184} 4185 4186/* mac address has to be provided for client related events */ 4187void IPACM_Lan::eth_bridge_post_event(ipa_cm_event_id evt, ipa_ip_type iptype, uint8_t *mac) 4188{ 4189 ipacm_cmd_q_data eth_bridge_evt; 4190 ipacm_event_eth_bridge *evt_data; 4191 4192 evt_data = (ipacm_event_eth_bridge*)malloc(sizeof(ipacm_event_eth_bridge)); 4193 if(evt_data == NULL) 4194 { 4195 IPACMERR("Failed to allocate memory.\n"); 4196 return; 4197 } 4198 memset(evt_data, 0, sizeof(ipacm_event_eth_bridge)); 4199 4200 evt_data->p_iface = this; 4201 evt_data->iptype = iptype; 4202 if(mac) 4203 { 4204 IPACMDBG_H("Client mac: 0x%02x%02x%02x%02x%02x%02x \n", 4205 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 4206 memcpy(evt_data->mac_addr, mac, sizeof(evt_data->mac_addr)); 4207 } 4208 4209 memset(ð_bridge_evt, 0, sizeof(ipacm_cmd_q_data)); 4210 eth_bridge_evt.evt_data = (void*)evt_data; 4211 eth_bridge_evt.event = evt; 4212 4213 IPACMDBG_H("Posting event %s\n", 4214 IPACM_Iface::ipacmcfg->getEventName(evt)); 4215 IPACM_EvtDispatcher::PostEvt(ð_bridge_evt); 4216} 4217 4218/* add header processing context and return handle to lan2lan controller */ 4219int IPACM_Lan::eth_bridge_add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_hdr_type, uint32_t *hdl) 4220{ 4221 int len, res = IPACM_SUCCESS; 4222 uint32_t hdr_template; 4223 ipa_ioc_add_hdr_proc_ctx* pHeaderProcTable = NULL; 4224 4225 if(tx_prop == NULL) 4226 { 4227 IPACMERR("No tx prop.\n"); 4228 return IPACM_FAILURE; 4229 } 4230 4231 len = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + sizeof(struct ipa_hdr_proc_ctx_add); 4232 pHeaderProcTable = (ipa_ioc_add_hdr_proc_ctx*)malloc(len); 4233 if(pHeaderProcTable == NULL) 4234 { 4235 IPACMERR("Cannot allocate header processing context table.\n"); 4236 return IPACM_FAILURE; 4237 } 4238 4239 memset(pHeaderProcTable, 0, len); 4240 pHeaderProcTable->commit = 1; 4241 pHeaderProcTable->num_proc_ctxs = 1; 4242 pHeaderProcTable->proc_ctx[0].type = eth_bridge_get_hdr_proc_type(peer_l2_hdr_type, tx_prop->tx[0].hdr_l2_type); 4243 eth_bridge_get_hdr_template_hdl(&hdr_template); 4244 pHeaderProcTable->proc_ctx[0].hdr_hdl = hdr_template; 4245 if (m_header.AddHeaderProcCtx(pHeaderProcTable) == false) 4246 { 4247 IPACMERR("Adding hdr proc ctx failed with status: %d\n", pHeaderProcTable->proc_ctx[0].status); 4248 res = IPACM_FAILURE; 4249 goto end; 4250 } 4251 4252 *hdl = pHeaderProcTable->proc_ctx[0].proc_ctx_hdl; 4253 4254end: 4255 free(pHeaderProcTable); 4256 return res; 4257} 4258 4259/* add routing rule and return handle to lan2lan controller */ 4260int IPACM_Lan::eth_bridge_add_rt_rule(uint8_t *mac, char *rt_tbl_name, uint32_t hdr_proc_ctx_hdl, 4261 ipa_hdr_l2_type peer_l2_hdr_type, ipa_ip_type iptype, uint32_t *rt_rule_hdl, int *rt_rule_count) 4262{ 4263 int len, res = IPACM_SUCCESS; 4264 uint32_t i, position, num_rt_rule; 4265 struct ipa_ioc_add_rt_rule* rt_rule_table = NULL; 4266 struct ipa_rt_rule_add rt_rule; 4267 4268 IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x.\n", 4269 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 4270 4271 num_rt_rule = each_client_rt_rule_count[iptype]; 4272 4273 len = sizeof(ipa_ioc_add_rt_rule) + num_rt_rule * sizeof(ipa_rt_rule_add); 4274 rt_rule_table = (ipa_ioc_add_rt_rule*)malloc(len); 4275 if (rt_rule_table == NULL) 4276 { 4277 IPACMERR("Failed to allocate memory.\n"); 4278 return IPACM_FAILURE; 4279 } 4280 memset(rt_rule_table, 0, len); 4281 4282 rt_rule_table->commit = 1; 4283 rt_rule_table->ip = iptype; 4284 rt_rule_table->num_rules = num_rt_rule; 4285 strlcpy(rt_rule_table->rt_tbl_name, rt_tbl_name, sizeof(rt_rule_table->rt_tbl_name)); 4286 rt_rule_table->rt_tbl_name[IPA_RESOURCE_NAME_MAX-1] = 0; 4287 4288 memset(&rt_rule, 0, sizeof(ipa_rt_rule_add)); 4289 rt_rule.at_rear = false; 4290 rt_rule.status = -1; 4291 rt_rule.rt_rule_hdl = -1; 4292#ifdef FEATURE_IPA_V3 4293 rt_rule.rule.hashable = true; 4294#endif 4295 rt_rule.rule.hdr_hdl = 0; 4296 rt_rule.rule.hdr_proc_ctx_hdl = hdr_proc_ctx_hdl; 4297 4298 position = 0; 4299 for(i=0; i<iface_query->num_tx_props; i++) 4300 { 4301 if(tx_prop->tx[i].ip == iptype) 4302 { 4303 if(position >= num_rt_rule || position >= MAX_NUM_PROP) 4304 { 4305 IPACMERR("Number of routing rules already exceeds limit.\n"); 4306 res = IPACM_FAILURE; 4307 goto end; 4308 } 4309 4310 if(ipa_if_cate == WLAN_IF && IPACM_Iface::ipacmcfg->isMCC_Mode) 4311 { 4312 IPACMDBG_H("In WLAN MCC mode, use alt dst pipe: %d\n", 4313 tx_prop->tx[i].alt_dst_pipe); 4314 rt_rule.rule.dst = tx_prop->tx[i].alt_dst_pipe; 4315 } 4316 else 4317 { 4318 IPACMDBG_H("It is not WLAN MCC mode, use dst pipe: %d\n", 4319 tx_prop->tx[i].dst_pipe); 4320 rt_rule.rule.dst = tx_prop->tx[i].dst_pipe; 4321 } 4322 4323 memcpy(&rt_rule.rule.attrib, &tx_prop->tx[i].attrib, sizeof(rt_rule.rule.attrib)); 4324 if(peer_l2_hdr_type == IPA_HDR_L2_ETHERNET_II) 4325 rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; 4326 else 4327 rt_rule.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; 4328 memcpy(rt_rule.rule.attrib.dst_mac_addr, mac, sizeof(rt_rule.rule.attrib.dst_mac_addr)); 4329 memset(rt_rule.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(rt_rule.rule.attrib.dst_mac_addr_mask)); 4330 4331 memcpy(&(rt_rule_table->rules[position]), &rt_rule, sizeof(rt_rule_table->rules[position])); 4332 position++; 4333 } 4334 } 4335 if(false == m_routing.AddRoutingRule(rt_rule_table)) 4336 { 4337 IPACMERR("Routing rule addition failed!\n"); 4338 res = IPACM_FAILURE; 4339 goto end; 4340 } 4341 else 4342 { 4343 *rt_rule_count = position; 4344 for(i=0; i<position; i++) 4345 rt_rule_hdl[i] = rt_rule_table->rules[i].rt_rule_hdl; 4346 } 4347 4348end: 4349 free(rt_rule_table); 4350 return res; 4351} 4352 4353/* modify routing rule*/ 4354int IPACM_Lan::eth_bridge_modify_rt_rule(uint8_t *mac, uint32_t hdr_proc_ctx_hdl, 4355 ipa_hdr_l2_type peer_l2_hdr_type, ipa_ip_type iptype, uint32_t *rt_rule_hdl, int rt_rule_count) 4356{ 4357 struct ipa_ioc_mdfy_rt_rule *rt_rule = NULL; 4358 struct ipa_rt_rule_mdfy *rt_rule_entry; 4359 int len, res = IPACM_SUCCESS; 4360 uint32_t index; 4361 4362 if(tx_prop == NULL) 4363 { 4364 IPACMDBG_H("No tx properties \n"); 4365 return IPACM_FAILURE; 4366 } 4367 4368 if(ipa_if_cate != WLAN_IF) 4369 { 4370 IPACMDBG_H("This is not WLAN IF, no need to modify rt rule.\n"); 4371 return IPACM_SUCCESS; 4372 } 4373 4374 IPACMDBG_H("Receive WLAN client MAC 0x%02x%02x%02x%02x%02x%02x.\n", 4375 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 4376 4377 len = sizeof(struct ipa_ioc_mdfy_rt_rule) + rt_rule_count * sizeof(struct ipa_rt_rule_mdfy); 4378 rt_rule = (struct ipa_ioc_mdfy_rt_rule *)malloc(len); 4379 if(rt_rule == NULL) 4380 { 4381 IPACMERR("Unable to allocate memory for modify rt rule\n"); 4382 return IPACM_FAILURE; 4383 } 4384 memset(rt_rule, 0, len); 4385 4386 rt_rule->commit = 1; 4387 rt_rule->num_rules = 0; 4388 rt_rule->ip = iptype; 4389 4390 for (index = 0; index < tx_prop->num_tx_props; index++) 4391 { 4392 if (tx_prop->tx[index].ip == iptype) 4393 { 4394 if (rt_rule->num_rules >= rt_rule_count || 4395 rt_rule->num_rules >= MAX_NUM_PROP) 4396 { 4397 IPACMERR("Number of routing rules exceeds limit.\n"); 4398 res = IPACM_FAILURE; 4399 goto end; 4400 } 4401 4402 rt_rule_entry = &rt_rule->rules[rt_rule->num_rules]; 4403 4404 if (IPACM_Iface::ipacmcfg->isMCC_Mode) 4405 { 4406 IPACMDBG_H("In WLAN MCC mode, use alt dst pipe: %d\n", 4407 tx_prop->tx[index].alt_dst_pipe); 4408 rt_rule_entry->rule.dst = tx_prop->tx[index].alt_dst_pipe; 4409 } 4410 else 4411 { 4412 IPACMDBG_H("In WLAN SCC mode, use dst pipe: %d\n", 4413 tx_prop->tx[index].dst_pipe); 4414 rt_rule_entry->rule.dst = tx_prop->tx[index].dst_pipe; 4415 } 4416 4417 rt_rule_entry->rule.hdr_hdl = 0; 4418 rt_rule_entry->rule.hdr_proc_ctx_hdl = hdr_proc_ctx_hdl; 4419#ifdef FEATURE_IPA_V3 4420 rt_rule_entry->rule.hashable = true; 4421#endif 4422 memcpy(&rt_rule_entry->rule.attrib, &tx_prop->tx[index].attrib, 4423 sizeof(rt_rule_entry->rule.attrib)); 4424 if(peer_l2_hdr_type == IPA_HDR_L2_ETHERNET_II) 4425 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; 4426 else 4427 rt_rule_entry->rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; 4428 memcpy(rt_rule_entry->rule.attrib.dst_mac_addr, mac, 4429 sizeof(rt_rule_entry->rule.attrib.dst_mac_addr)); 4430 memset(rt_rule_entry->rule.attrib.dst_mac_addr_mask, 0xFF, 4431 sizeof(rt_rule_entry->rule.attrib.dst_mac_addr_mask)); 4432 4433 rt_rule_entry->rt_rule_hdl = rt_rule_hdl[rt_rule->num_rules]; 4434 rt_rule->num_rules++; 4435 } 4436 } 4437 4438 if(m_routing.ModifyRoutingRule(rt_rule) == false) 4439 { 4440 IPACMERR("Failed to modify routing rules.\n"); 4441 res = IPACM_FAILURE; 4442 goto end; 4443 } 4444 if(m_routing.Commit(iptype) == false) 4445 { 4446 IPACMERR("Failed to commit routing rules.\n"); 4447 res = IPACM_FAILURE; 4448 goto end; 4449 } 4450 IPACMDBG("Modified routing rules successfully.\n"); 4451 4452end: 4453 free(rt_rule); 4454 return res; 4455} 4456 4457int IPACM_Lan::eth_bridge_add_flt_rule(uint8_t *mac, uint32_t rt_tbl_hdl, ipa_ip_type iptype, uint32_t *flt_rule_hdl) 4458{ 4459 int len, res = IPACM_SUCCESS; 4460 struct ipa_flt_rule_add flt_rule_entry; 4461 struct ipa_ioc_add_flt_rule_after *pFilteringTable = NULL; 4462 4463#ifdef FEATURE_IPA_V3 4464 if (rx_prop == NULL || tx_prop == NULL) 4465 { 4466 IPACMDBG_H("No rx or tx properties registered for iface %s\n", dev_name); 4467 return IPACM_FAILURE; 4468 } 4469 4470 IPACMDBG_H("Received client MAC 0x%02x%02x%02x%02x%02x%02x.\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 4471 4472 len = sizeof(struct ipa_ioc_add_flt_rule_after) + sizeof(struct ipa_flt_rule_add); 4473 pFilteringTable = (struct ipa_ioc_add_flt_rule_after*)malloc(len); 4474 if (!pFilteringTable) 4475 { 4476 IPACMERR("Failed to allocate ipa_ioc_add_flt_rule_after memory...\n"); 4477 return IPACM_FAILURE; 4478 } 4479 memset(pFilteringTable, 0, len); 4480 4481 /* add mac based rule*/ 4482 pFilteringTable->commit = 1; 4483 pFilteringTable->ep = rx_prop->rx[0].src_pipe; 4484 pFilteringTable->ip = iptype; 4485 pFilteringTable->num_rules = 1; 4486 pFilteringTable->add_after_hdl = eth_bridge_flt_rule_offset[iptype]; 4487 4488 memset(&flt_rule_entry, 0, sizeof(flt_rule_entry)); 4489 flt_rule_entry.at_rear = 1; 4490 4491 flt_rule_entry.rule.retain_hdr = 0; 4492 flt_rule_entry.rule.to_uc = 0; 4493 flt_rule_entry.rule.action = IPA_PASS_TO_ROUTING; 4494 flt_rule_entry.rule.eq_attrib_type = 0; 4495 flt_rule_entry.rule.rt_tbl_hdl = rt_tbl_hdl; 4496 flt_rule_entry.rule.hashable = true; 4497 4498 memcpy(&flt_rule_entry.rule.attrib, &rx_prop->rx[0].attrib, sizeof(flt_rule_entry.rule.attrib)); 4499 if(tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_ETHERNET_II) 4500 { 4501 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_ETHER_II; 4502 } 4503 else 4504 { 4505 flt_rule_entry.rule.attrib.attrib_mask |= IPA_FLT_MAC_DST_ADDR_802_3; 4506 } 4507 4508 memcpy(flt_rule_entry.rule.attrib.dst_mac_addr, mac, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr)); 4509 memset(flt_rule_entry.rule.attrib.dst_mac_addr_mask, 0xFF, sizeof(flt_rule_entry.rule.attrib.dst_mac_addr_mask)); 4510 4511 memcpy(&(pFilteringTable->rules[0]), &flt_rule_entry, sizeof(flt_rule_entry)); 4512 if (false == m_filtering.AddFilteringRuleAfter(pFilteringTable)) 4513 { 4514 IPACMERR("Failed to add client filtering rules.\n"); 4515 res = IPACM_FAILURE; 4516 goto end; 4517 } 4518 *flt_rule_hdl = pFilteringTable->rules[0].flt_rule_hdl; 4519 4520end: 4521 free(pFilteringTable); 4522#endif 4523 return res; 4524} 4525 4526int IPACM_Lan::eth_bridge_del_flt_rule(uint32_t flt_rule_hdl, ipa_ip_type iptype) 4527{ 4528 if(m_filtering.DeleteFilteringHdls(&flt_rule_hdl, iptype, 1) == false) 4529 { 4530 IPACMERR("Failed to delete the client specific flt rule.\n"); 4531 return IPACM_FAILURE; 4532 } 4533 return IPACM_SUCCESS; 4534} 4535 4536int IPACM_Lan::eth_bridge_del_rt_rule(uint32_t rt_rule_hdl, ipa_ip_type iptype) 4537{ 4538 if(m_routing.DeleteRoutingHdl(rt_rule_hdl, iptype) == false) 4539 { 4540 IPACMERR("Failed to delete routing rule.\n"); 4541 return IPACM_FAILURE; 4542 } 4543 return IPACM_SUCCESS; 4544} 4545 4546/* delete header processing context */ 4547int IPACM_Lan::eth_bridge_del_hdr_proc_ctx(uint32_t hdr_proc_ctx_hdl) 4548{ 4549 if(m_header.DeleteHeaderProcCtx(hdr_proc_ctx_hdl) == false) 4550 { 4551 IPACMERR("Failed to delete hdr proc ctx.\n"); 4552 return IPACM_FAILURE; 4553 } 4554 return IPACM_SUCCESS; 4555} 4556