1 /* 2 Copyright (c) 2014, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are 6 met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above 10 copyright notice, this list of conditions and the following 11 disclaimer in the documentation and/or other materials provided 12 with the distribution. 13 * Neither the name of The Linux Foundation nor the names of its 14 contributors may be used to endorse or promote products derived 15 from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 /*! 30 @file 31 IPACM_LanToLan.cpp 32 33 @brief 34 This file implements the functionality of offloading LAN to LAN traffic. 35 36 @Author 37 Shihuan Liu 38 39 */ 40 41 #include <stdlib.h> 42 #include "IPACM_LanToLan.h" 43 #include "IPACM_Wlan.h" 44 45 #define __stringify(x...) #x 46 47 const char *ipa_l2_hdr_type[] = { 48 __stringify(NONE), 49 __stringify(ETH_II), 50 __stringify(802_3), 51 __stringify(L2_MAX) 52 }; 53 54 IPACM_LanToLan_Iface::IPACM_LanToLan_Iface(IPACM_Lan *p_iface) 55 { 56 int i; 57 58 m_p_iface = p_iface; 59 memset(m_is_ip_addr_assigned, 0, sizeof(m_is_ip_addr_assigned)); 60 m_support_inter_iface_offload = true; 61 m_support_intra_iface_offload = false; 62 for(i = 0; i < IPA_HDR_L2_MAX; i++) 63 { 64 ref_cnt_peer_l2_hdr_type[i] = 0; 65 hdr_proc_ctx_for_inter_interface[i] = 0; 66 } 67 hdr_proc_ctx_for_intra_interface = 0; 68 69 if(p_iface->ipa_if_cate == WLAN_IF) 70 { 71 IPACMDBG_H("Interface %s is WLAN interface.\n", p_iface->dev_name); 72 m_support_intra_iface_offload = true; 73 if( ((IPACM_Wlan*)p_iface)->is_guest_ap() ) 74 { 75 IPACMDBG_H("Interface %s is guest AP.\n", p_iface->dev_name); 76 m_support_inter_iface_offload = false; 77 } 78 } 79 return; 80 } 81 82 IPACM_LanToLan_Iface::~IPACM_LanToLan_Iface() 83 { 84 } 85 86 IPACM_LanToLan::IPACM_LanToLan() 87 { 88 IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_IFACE_UP, this); 89 IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_IFACE_DOWN, this); 90 IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_CLIENT_ADD, this); 91 IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_CLIENT_DEL, this); 92 IPACM_EvtDispatcher::registr(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH, this); 93 94 return; 95 } 96 97 IPACM_LanToLan::~IPACM_LanToLan() 98 { 99 IPACMDBG_DMESG("WARNING: UNEXPECTEDLY KILL LAN2LAN CONTROLLER!\n"); 100 return; 101 } 102 103 void IPACM_LanToLan::event_callback(ipa_cm_event_id event, void* param) 104 { 105 ipacm_event_eth_bridge *data = (ipacm_event_eth_bridge*)param; 106 IPACMDBG_H("Get %s event.\n", IPACM_Iface::ipacmcfg->getEventName(event)); 107 108 switch(event) 109 { 110 case IPA_ETH_BRIDGE_IFACE_UP: 111 { 112 handle_iface_up(data); 113 break; 114 } 115 116 case IPA_ETH_BRIDGE_IFACE_DOWN: 117 { 118 handle_iface_down(data); 119 break; 120 } 121 122 case IPA_ETH_BRIDGE_CLIENT_ADD: 123 { 124 handle_client_add(data); 125 break; 126 } 127 128 case IPA_ETH_BRIDGE_CLIENT_DEL: 129 { 130 handle_client_del(data); 131 break; 132 } 133 134 case IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH: 135 { 136 handle_wlan_scc_mcc_switch(data); 137 break; 138 } 139 default: 140 break; 141 } 142 143 print_data_structure_info(); 144 return; 145 } 146 147 void IPACM_LanToLan::handle_iface_up(ipacm_event_eth_bridge *data) 148 { 149 list<IPACM_LanToLan_Iface>::iterator it; 150 151 IPACMDBG_H("Interface name: %s IP type: %d\n", data->p_iface->dev_name, data->iptype); 152 for(it = m_iface.begin(); it != m_iface.end(); it++) 153 { 154 if(it->get_iface_pointer() == data->p_iface) 155 { 156 IPACMDBG_H("Found the interface.\n"); 157 if(it->get_m_is_ip_addr_assigned(data->iptype) == false) 158 { 159 IPACMDBG_H("IP type %d was not active before, activating it now.\n", data->iptype); 160 it->set_m_is_ip_addr_assigned(data->iptype, true); 161 162 /* install inter-interface rules */ 163 if(it->get_m_support_inter_iface_offload()) 164 it->add_all_inter_interface_client_flt_rule(data->iptype); 165 166 /* install intra-BSS rules */ 167 if(it->get_m_support_intra_iface_offload()) 168 it->add_all_intra_interface_client_flt_rule(data->iptype); 169 } 170 break; 171 } 172 } 173 174 if(it == m_iface.end()) //If the interface has not been created before 175 { 176 if(m_iface.size() == MAX_NUM_IFACE) 177 { 178 IPACMERR("The number of interfaces has reached maximum %d.\n", MAX_NUM_IFACE); 179 return; 180 } 181 182 if(!data->p_iface->tx_prop || !data->p_iface->rx_prop) 183 { 184 IPACMERR("The interface %s does not have tx_prop or rx_prop.\n", data->p_iface->dev_name); 185 return; 186 } 187 188 if(data->p_iface->tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_NONE || data->p_iface->tx_prop->tx[0].hdr_l2_type == IPA_HDR_L2_MAX) 189 { 190 IPACMERR("Invalid l2 header type %s!\n", ipa_l2_hdr_type[data->p_iface->tx_prop->tx[0].hdr_l2_type]); 191 return; 192 } 193 194 IPACMDBG_H("Does not find the interface, insert a new one.\n"); 195 IPACM_LanToLan_Iface new_iface(data->p_iface); 196 new_iface.set_m_is_ip_addr_assigned(data->iptype, true); 197 198 m_iface.push_front(new_iface); 199 IPACMDBG_H("Now the total number of interfaces is %d.\n", m_iface.size()); 200 201 IPACM_LanToLan_Iface &front_iface = m_iface.front(); 202 203 /* install inter-interface rules */ 204 if(front_iface.get_m_support_inter_iface_offload()) 205 { 206 for(it = ++m_iface.begin(); it != m_iface.end(); it++) 207 { 208 /* add peer info only when both interfaces support inter-interface communication */ 209 if(it->get_m_support_inter_iface_offload()) 210 { 211 /* populate hdr_proc_ctx and routing table handle */ 212 handle_new_iface_up(&front_iface, &(*it)); 213 214 /* add client specific routing rule on existing interface */ 215 it->add_client_rt_rule_for_new_iface(); 216 } 217 } 218 219 /* add client specific filtering rule on new interface */ 220 front_iface.add_all_inter_interface_client_flt_rule(data->iptype); 221 } 222 223 /* populate the intra-interface information */ 224 if(front_iface.get_m_support_intra_iface_offload()) 225 { 226 front_iface.handle_intra_interface_info(); 227 } 228 229 /* handle cached client add event */ 230 handle_cached_client_add_event(front_iface.get_iface_pointer()); 231 } 232 return; 233 } 234 235 void IPACM_LanToLan::handle_iface_down(ipacm_event_eth_bridge *data) 236 { 237 list<IPACM_LanToLan_Iface>::iterator it_target_iface; 238 239 IPACMDBG_H("Interface name: %s\n", data->p_iface->dev_name); 240 241 for(it_target_iface = m_iface.begin(); it_target_iface != m_iface.end(); it_target_iface++) 242 { 243 if(it_target_iface->get_iface_pointer() == data->p_iface) 244 { 245 IPACMDBG_H("Found the interface.\n"); 246 break; 247 } 248 } 249 250 if(it_target_iface == m_iface.end()) 251 { 252 IPACMDBG_H("The interface has not been found.\n"); 253 /* clear cached client add event for the unfound interface*/ 254 clear_cached_client_add_event(data->p_iface); 255 return; 256 } 257 258 it_target_iface->handle_down_event(); 259 m_iface.erase(it_target_iface); 260 261 return; 262 } 263 264 void IPACM_LanToLan::handle_new_iface_up(IPACM_LanToLan_Iface *new_iface, IPACM_LanToLan_Iface *exist_iface) 265 { 266 char rt_tbl_name_for_flt[IPA_IP_MAX][IPA_RESOURCE_NAME_MAX]; 267 char rt_tbl_name_for_rt[IPA_IP_MAX][IPA_RESOURCE_NAME_MAX]; 268 269 IPACMDBG_H("Populate peer info between: new_iface %s, existing iface %s\n", new_iface->get_iface_pointer()->dev_name, 270 exist_iface->get_iface_pointer()->dev_name); 271 272 /* populate the routing table information */ 273 snprintf(rt_tbl_name_for_flt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX, "eth_v4_%s_to_%s", 274 ipa_l2_hdr_type[exist_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type], 275 ipa_l2_hdr_type[new_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type]); 276 IPACMDBG_H("IPv4 routing table for flt name: %s\n", rt_tbl_name_for_flt[IPA_IP_v4]); 277 278 snprintf(rt_tbl_name_for_flt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX, "eth_v6_%s_to_%s", 279 ipa_l2_hdr_type[exist_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type], 280 ipa_l2_hdr_type[new_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type]); 281 IPACMDBG_H("IPv6 routing table for flt name: %s\n", rt_tbl_name_for_flt[IPA_IP_v6]); 282 283 snprintf(rt_tbl_name_for_rt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX, "eth_v4_%s_to_%s", 284 ipa_l2_hdr_type[new_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type], 285 ipa_l2_hdr_type[exist_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type]); 286 IPACMDBG_H("IPv4 routing table for rt name: %s\n", rt_tbl_name_for_rt[IPA_IP_v4]); 287 288 snprintf(rt_tbl_name_for_rt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX, "eth_v6_%s_to_%s", 289 ipa_l2_hdr_type[new_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type], 290 ipa_l2_hdr_type[exist_iface->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type]); 291 IPACMDBG_H("IPv6 routing table for rt name: %s\n", rt_tbl_name_for_rt[IPA_IP_v6]); 292 293 /* add new peer info in both new iface and existing iface */ 294 exist_iface->handle_new_iface_up(rt_tbl_name_for_flt, rt_tbl_name_for_rt, new_iface); 295 296 new_iface->handle_new_iface_up(rt_tbl_name_for_rt, rt_tbl_name_for_flt, exist_iface); 297 298 return; 299 } 300 301 void IPACM_LanToLan::handle_client_add(ipacm_event_eth_bridge *data) 302 { 303 list<IPACM_LanToLan_Iface>::iterator it_iface; 304 305 IPACMDBG_H("Incoming client MAC: 0x%02x%02x%02x%02x%02x%02x, interface: %s\n", data->mac_addr[0], data->mac_addr[1], 306 data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->p_iface->dev_name); 307 308 for(it_iface = m_iface.begin(); it_iface != m_iface.end(); it_iface++) 309 { 310 if(it_iface->get_iface_pointer() == data->p_iface) //find the interface 311 { 312 IPACMDBG_H("Found the interface.\n"); 313 it_iface->handle_client_add(data->mac_addr); 314 break; 315 } 316 } 317 318 /* if the iface was not found, cache the client add event */ 319 if(it_iface == m_iface.end()) 320 { 321 IPACMDBG_H("The interface is not found.\n"); 322 if(m_cached_client_add_event.size() < MAX_NUM_CACHED_CLIENT_ADD_EVENT) 323 { 324 IPACMDBG_H("Cached the client information.\n"); 325 m_cached_client_add_event.push_front(*data); 326 } 327 else 328 { 329 IPACMDBG_H("Cached client add event has reached maximum number.\n"); 330 } 331 } 332 return; 333 } 334 335 void IPACM_LanToLan::handle_client_del(ipacm_event_eth_bridge *data) 336 { 337 list<IPACM_LanToLan_Iface>::iterator it_iface; 338 339 IPACMDBG_H("Incoming client MAC: 0x%02x%02x%02x%02x%02x%02x, interface: %s\n", data->mac_addr[0], data->mac_addr[1], 340 data->mac_addr[2], data->mac_addr[3], data->mac_addr[4], data->mac_addr[5], data->p_iface->dev_name); 341 342 for(it_iface = m_iface.begin(); it_iface != m_iface.end(); it_iface++) 343 { 344 if(it_iface->get_iface_pointer() == data->p_iface) //found the interface 345 { 346 IPACMDBG_H("Found the interface.\n"); 347 it_iface->handle_client_del(data->mac_addr); 348 break; 349 } 350 } 351 352 if(it_iface == m_iface.end()) 353 { 354 IPACMDBG_H("The interface is not found.\n"); 355 } 356 357 return; 358 } 359 360 void IPACM_LanToLan::handle_wlan_scc_mcc_switch(ipacm_event_eth_bridge *data) 361 { 362 list<IPACM_LanToLan_Iface>::iterator it_iface; 363 364 IPACMDBG_H("Incoming interface: %s\n", data->p_iface->dev_name); 365 for(it_iface = m_iface.begin(); it_iface != m_iface.end(); it_iface++) 366 { 367 if(it_iface->get_iface_pointer() == data->p_iface) 368 { 369 it_iface->handle_wlan_scc_mcc_switch(); 370 break; 371 } 372 } 373 return; 374 } 375 376 void IPACM_LanToLan::handle_cached_client_add_event(IPACM_Lan *p_iface) 377 { 378 list<ipacm_event_eth_bridge>::iterator it; 379 380 it = m_cached_client_add_event.begin(); 381 while(it != m_cached_client_add_event.end()) 382 { 383 if(it->p_iface == p_iface) 384 { 385 IPACMDBG_H("Found client with MAC: 0x%02x%02x%02x%02x%02x%02x\n", it->mac_addr[0], it->mac_addr[1], 386 it->mac_addr[2], it->mac_addr[3], it->mac_addr[4], it->mac_addr[5]); 387 handle_client_add(&(*it)); 388 it = m_cached_client_add_event.erase(it); 389 } 390 else 391 { 392 it++; 393 } 394 } 395 return; 396 } 397 398 void IPACM_LanToLan::clear_cached_client_add_event(IPACM_Lan *p_iface) 399 { 400 list<ipacm_event_eth_bridge>::iterator it; 401 402 it = m_cached_client_add_event.begin(); 403 while(it != m_cached_client_add_event.end()) 404 { 405 if(it->p_iface == p_iface) 406 { 407 IPACMDBG_H("Found client with MAC: 0x%02x%02x%02x%02x%02x%02x\n", it->mac_addr[0], it->mac_addr[1], 408 it->mac_addr[2], it->mac_addr[3], it->mac_addr[4], it->mac_addr[5]); 409 it = m_cached_client_add_event.erase(it); 410 } 411 else 412 { 413 it++; 414 } 415 } 416 return; 417 } 418 419 void IPACM_LanToLan::print_data_structure_info() 420 { 421 list<IPACM_LanToLan_Iface>::iterator it; 422 list<ipacm_event_eth_bridge>::iterator it_event; 423 int i; 424 425 IPACMDBG_H("There are %d interfaces in total.\n", m_iface.size()); 426 427 for(it = m_iface.begin(); it != m_iface.end(); it++) 428 { 429 it->print_data_structure_info(); 430 } 431 432 IPACMDBG_H("There are %d cached client add events in total.\n", m_cached_client_add_event.size()); 433 434 i = 1; 435 for(it_event = m_cached_client_add_event.begin(); it_event != m_cached_client_add_event.end(); it_event++) 436 { 437 IPACMDBG_H("Client %d MAC: 0x%02x%02x%02x%02x%02x%02x, interface: %s\n", i, it_event->mac_addr[0], it_event->mac_addr[1], it_event->mac_addr[2], 438 it_event->mac_addr[3], it_event->mac_addr[4], it_event->mac_addr[5], it_event->p_iface->dev_name); 439 i++; 440 } 441 442 return; 443 } 444 445 void IPACM_LanToLan_Iface::add_client_rt_rule_for_new_iface() 446 { 447 list<client_info>::iterator it; 448 ipa_hdr_l2_type peer_l2_type; 449 peer_iface_info &peer = m_peer_iface_info.front(); 450 451 peer_l2_type = peer.peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type; 452 if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 1) 453 { 454 for(it = m_client_info.begin(); it != m_client_info.end(); it++) 455 { 456 add_client_rt_rule(&peer, &(*it)); 457 } 458 } 459 460 return; 461 } 462 463 void IPACM_LanToLan_Iface::add_client_rt_rule(peer_iface_info *peer_info, client_info *client) 464 { 465 int i, num_rt_rule; 466 uint32_t rt_rule_hdl[MAX_NUM_PROP]; 467 ipa_hdr_l2_type peer_l2_hdr_type; 468 469 peer_l2_hdr_type = peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type; 470 471 /* if the peer info is not for intra interface communication */ 472 if(peer_info->peer != this) 473 { 474 IPACMDBG_H("This is for inter interface communication.\n"); 475 476 m_p_iface->eth_bridge_add_rt_rule(client->mac_addr, peer_info->rt_tbl_name_for_rt[IPA_IP_v4], hdr_proc_ctx_for_inter_interface[peer_l2_hdr_type], 477 peer_l2_hdr_type, IPA_IP_v4, rt_rule_hdl, &num_rt_rule); 478 479 client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4] = num_rt_rule; 480 IPACMDBG_H("Number of IPv4 routing rule is %d.\n", num_rt_rule); 481 for(i=0; i<num_rt_rule; i++) 482 { 483 IPACMDBG_H("Routing rule %d handle %d\n", i, rt_rule_hdl[i]); 484 client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4][i] = rt_rule_hdl[i]; 485 } 486 487 m_p_iface->eth_bridge_add_rt_rule(client->mac_addr, peer_info->rt_tbl_name_for_rt[IPA_IP_v6], hdr_proc_ctx_for_inter_interface[peer_l2_hdr_type], 488 peer_l2_hdr_type, IPA_IP_v6, rt_rule_hdl, &num_rt_rule); 489 490 client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6] = num_rt_rule; 491 IPACMDBG_H("Number of IPv6 routing rule is %d.\n", num_rt_rule); 492 for(i=0; i<num_rt_rule; i++) 493 { 494 IPACMDBG_H("Routing rule %d handle %d\n", i, rt_rule_hdl[i]); 495 client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6][i] = rt_rule_hdl[i]; 496 } 497 } 498 else 499 { 500 IPACMDBG_H("This is for intra interface communication.\n"); 501 m_p_iface->eth_bridge_add_rt_rule(client->mac_addr, peer_info->rt_tbl_name_for_rt[IPA_IP_v4], hdr_proc_ctx_for_intra_interface, 502 peer_l2_hdr_type, IPA_IP_v4, rt_rule_hdl, &num_rt_rule); 503 504 client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4] = num_rt_rule; 505 IPACMDBG_H("Number of IPv4 routing rule is %d.\n", num_rt_rule); 506 for(i=0; i<num_rt_rule; i++) 507 { 508 IPACMDBG_H("Routing rule %d handle %d\n", i, rt_rule_hdl[i]); 509 client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][i] = rt_rule_hdl[i]; 510 } 511 512 m_p_iface->eth_bridge_add_rt_rule(client->mac_addr, peer_info->rt_tbl_name_for_rt[IPA_IP_v6], hdr_proc_ctx_for_intra_interface, 513 peer_l2_hdr_type, IPA_IP_v6, rt_rule_hdl, &num_rt_rule); 514 515 client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6] = num_rt_rule; 516 IPACMDBG_H("Number of IPv6 routing rule is %d.\n", num_rt_rule); 517 for(i=0; i<num_rt_rule; i++) 518 { 519 IPACMDBG_H("Routing rule %d handle %d\n", i, rt_rule_hdl[i]); 520 client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][i] = rt_rule_hdl[i]; 521 } 522 } 523 524 return; 525 } 526 527 void IPACM_LanToLan_Iface::add_all_inter_interface_client_flt_rule(ipa_ip_type iptype) 528 { 529 list<peer_iface_info>::iterator it_iface; 530 list<client_info>::iterator it_client; 531 532 for(it_iface = m_peer_iface_info.begin(); it_iface != m_peer_iface_info.end(); it_iface++) 533 { 534 IPACMDBG_H("Add flt rules for clients of interface %s.\n", it_iface->peer->get_iface_pointer()->dev_name); 535 for(it_client = it_iface->peer->m_client_info.begin(); it_client != it_iface->peer->m_client_info.end(); it_client++) 536 { 537 add_client_flt_rule(&(*it_iface), &(*it_client), iptype); 538 } 539 } 540 return; 541 } 542 543 void IPACM_LanToLan_Iface::add_all_intra_interface_client_flt_rule(ipa_ip_type iptype) 544 { 545 list<client_info>::iterator it_client; 546 547 IPACMDBG_H("Add flt rules for own clients.\n"); 548 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) 549 { 550 add_client_flt_rule(&m_intra_interface_info, &(*it_client), iptype); 551 } 552 553 return; 554 } 555 556 void IPACM_LanToLan_Iface::add_one_client_flt_rule(IPACM_LanToLan_Iface *peer_iface, client_info *client) 557 { 558 list<peer_iface_info>::iterator it; 559 560 for(it = m_peer_iface_info.begin(); it != m_peer_iface_info.end(); it++) 561 { 562 if(it->peer == peer_iface) 563 { 564 IPACMDBG_H("Found the peer iface info.\n"); 565 if(m_is_ip_addr_assigned[IPA_IP_v4]) 566 { 567 add_client_flt_rule(&(*it), client, IPA_IP_v4); 568 } 569 if(m_is_ip_addr_assigned[IPA_IP_v6]) 570 { 571 add_client_flt_rule(&(*it), client, IPA_IP_v6); 572 } 573 574 break; 575 } 576 } 577 return; 578 } 579 580 void IPACM_LanToLan_Iface::add_client_flt_rule(peer_iface_info *peer, client_info *client, ipa_ip_type iptype) 581 { 582 list<flt_rule_info>::iterator it_flt; 583 uint32_t flt_rule_hdl; 584 flt_rule_info new_flt_info; 585 ipa_ioc_get_rt_tbl rt_tbl; 586 587 rt_tbl.ip = iptype; 588 memcpy(rt_tbl.name, peer->rt_tbl_name_for_flt[iptype], sizeof(rt_tbl.name)); 589 IPACMDBG_H("This flt rule points to rt tbl %s.\n", rt_tbl.name); 590 591 if(IPACM_Iface::m_routing.GetRoutingTable(&rt_tbl) == false) 592 { 593 IPACMERR("Failed to get routing table.\n"); 594 return; 595 } 596 597 m_p_iface->eth_bridge_add_flt_rule(client->mac_addr, rt_tbl.hdl, 598 iptype, &flt_rule_hdl); 599 IPACMDBG_H("Installed flt rule for IP type %d: handle %d\n", iptype, flt_rule_hdl); 600 601 for(it_flt = peer->flt_rule.begin(); it_flt != peer->flt_rule.end(); it_flt++) 602 { 603 if(it_flt->p_client == client) //the client is already in the flt info list 604 { 605 IPACMDBG_H("The client is found in flt info list.\n"); 606 it_flt->flt_rule_hdl[iptype] = flt_rule_hdl; 607 break; 608 } 609 } 610 611 if(it_flt == peer->flt_rule.end()) //the client is not in the flt info list 612 { 613 IPACMDBG_H("The client is not found in flt info list, insert a new one.\n"); 614 memset(&new_flt_info, 0, sizeof(new_flt_info)); 615 new_flt_info.p_client = client; 616 new_flt_info.flt_rule_hdl[iptype] = flt_rule_hdl; 617 618 peer->flt_rule.push_front(new_flt_info); 619 } 620 621 return; 622 } 623 624 void IPACM_LanToLan_Iface::del_one_client_flt_rule(IPACM_LanToLan_Iface *peer_iface, client_info *client) 625 { 626 list<peer_iface_info>::iterator it; 627 628 for(it = m_peer_iface_info.begin(); it != m_peer_iface_info.end(); it++) 629 { 630 if(it->peer == peer_iface) 631 { 632 IPACMDBG_H("Found the peer iface info.\n"); 633 del_client_flt_rule(&(*it), client); 634 break; 635 } 636 } 637 return; 638 } 639 640 void IPACM_LanToLan_Iface::del_client_flt_rule(peer_iface_info *peer, client_info *client) 641 { 642 list<flt_rule_info>::iterator it_flt; 643 644 for(it_flt = peer->flt_rule.begin(); it_flt != peer->flt_rule.end(); it_flt++) 645 { 646 if(it_flt->p_client == client) //found the client in flt info list 647 { 648 IPACMDBG_H("Found the client in flt info list.\n"); 649 if(m_is_ip_addr_assigned[IPA_IP_v4]) 650 { 651 m_p_iface->eth_bridge_del_flt_rule(it_flt->flt_rule_hdl[IPA_IP_v4], IPA_IP_v4); 652 IPACMDBG_H("IPv4 flt rule %d is deleted.\n", it_flt->flt_rule_hdl[IPA_IP_v4]); 653 } 654 if(m_is_ip_addr_assigned[IPA_IP_v6]) 655 { 656 m_p_iface->eth_bridge_del_flt_rule(it_flt->flt_rule_hdl[IPA_IP_v6], IPA_IP_v6); 657 IPACMDBG_H("IPv6 flt rule %d is deleted.\n", it_flt->flt_rule_hdl[IPA_IP_v6]); 658 } 659 660 peer->flt_rule.erase(it_flt); 661 break; 662 } 663 } 664 return; 665 } 666 667 void IPACM_LanToLan_Iface::del_client_rt_rule(peer_iface_info *peer, client_info *client) 668 { 669 ipa_hdr_l2_type peer_l2_hdr_type; 670 int i, num_rules; 671 672 peer_l2_hdr_type = peer->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type; 673 /* if the peer info is not for intra interface communication */ 674 if(peer->peer != this) 675 { 676 IPACMDBG_H("Delete routing rules for inter interface communication.\n"); 677 678 num_rules = client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4]; 679 for(i = 0; i < num_rules; i++) 680 { 681 m_p_iface->eth_bridge_del_rt_rule(client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4][i], IPA_IP_v4); 682 IPACMDBG_H("IPv4 rt rule %d is deleted.\n", client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4][i]); 683 } 684 client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4] = 0; 685 686 num_rules = client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6]; 687 for(i = 0; i < num_rules; i++) 688 { 689 m_p_iface->eth_bridge_del_rt_rule(client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6][i], IPA_IP_v6); 690 IPACMDBG_H("IPv6 rt rule %d is deleted.\n", client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6][i]); 691 } 692 client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6] = 0; 693 } 694 else 695 { 696 IPACMDBG_H("Delete routing rules for intra interface communication.\n"); 697 num_rules = client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]; 698 for(i = 0; i < num_rules; i++) 699 { 700 m_p_iface->eth_bridge_del_rt_rule(client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][i], IPA_IP_v4); 701 IPACMDBG_H("IPv4 rt rule %d is deleted.\n", client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][i]); 702 } 703 client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4] = 0; 704 705 num_rules = client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]; 706 for(i = 0; i < num_rules; i++) 707 { 708 m_p_iface->eth_bridge_del_rt_rule(client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][i], IPA_IP_v6); 709 IPACMDBG_H("IPv6 rt rule %d is deleted.\n", client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][i]); 710 } 711 client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6] = 0; 712 } 713 714 return; 715 } 716 717 void IPACM_LanToLan_Iface::handle_down_event() 718 { 719 list<IPACM_LanToLan_Iface>::iterator it_other_iface; 720 list<peer_iface_info>::iterator it_own_peer_info, it_other_iface_peer_info; 721 IPACM_LanToLan_Iface *other_iface; 722 723 /* clear inter-interface rules */ 724 if(m_support_inter_iface_offload) 725 { 726 for(it_own_peer_info = m_peer_iface_info.begin(); it_own_peer_info != m_peer_iface_info.end(); 727 it_own_peer_info++) 728 { 729 /* decrement reference count of peer l2 header type on both interfaces*/ 730 decrement_ref_cnt_peer_l2_hdr_type(it_own_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type); 731 it_own_peer_info->peer->decrement_ref_cnt_peer_l2_hdr_type(m_p_iface->tx_prop->tx[0].hdr_l2_type); 732 733 /* first clear all flt rule on target interface */ 734 IPACMDBG_H("Clear all flt rule on target interface.\n"); 735 clear_all_flt_rule_for_one_peer_iface(&(*it_own_peer_info)); 736 737 other_iface = it_own_peer_info->peer; 738 /* then clear all flt/rt rule and hdr proc ctx for target interface on peer interfaces */ 739 IPACMDBG_H("Clear all flt/rt rules and hdr proc ctx for target interface on peer interfaces %s.\n", 740 it_own_peer_info->peer->get_iface_pointer()->dev_name); 741 for(it_other_iface_peer_info = other_iface->m_peer_iface_info.begin(); 742 it_other_iface_peer_info != other_iface->m_peer_iface_info.end(); 743 it_other_iface_peer_info++) 744 { 745 if(it_other_iface_peer_info->peer == this) //found myself in other iface's peer info list 746 { 747 IPACMDBG_H("Found the right peer info on other iface.\n"); 748 other_iface->clear_all_flt_rule_for_one_peer_iface(&(*it_other_iface_peer_info)); 749 other_iface->clear_all_rt_rule_for_one_peer_iface(&(*it_other_iface_peer_info)); 750 /* remove the peer info from the list */ 751 other_iface->m_peer_iface_info.erase(it_other_iface_peer_info); 752 other_iface->del_hdr_proc_ctx(m_p_iface->tx_prop->tx[0].hdr_l2_type); 753 break; 754 } 755 } 756 757 /* then clear rt rule and hdr proc ctx and release rt table on target interface */ 758 IPACMDBG_H("Clear rt rules and hdr proc ctx and release rt table on target interface.\n"); 759 clear_all_rt_rule_for_one_peer_iface(&(*it_own_peer_info)); 760 del_hdr_proc_ctx(it_own_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type); 761 } 762 m_peer_iface_info.clear(); 763 } 764 765 /* clear intra interface rules */ 766 if(m_support_intra_iface_offload) 767 { 768 IPACMDBG_H("Clear intra interface flt/rt rules and hdr proc ctx, release rt tables.\n"); 769 clear_all_flt_rule_for_one_peer_iface(&m_intra_interface_info); 770 clear_all_rt_rule_for_one_peer_iface(&m_intra_interface_info); 771 m_p_iface->eth_bridge_del_hdr_proc_ctx(hdr_proc_ctx_for_intra_interface); 772 IPACMDBG_H("Hdr proc ctx with hdl %d is deleted.\n", hdr_proc_ctx_for_intra_interface); 773 } 774 775 /* then clear the client info list */ 776 m_client_info.clear(); 777 778 return; 779 } 780 781 void IPACM_LanToLan_Iface::clear_all_flt_rule_for_one_peer_iface(peer_iface_info *peer) 782 { 783 list<flt_rule_info>::iterator it; 784 785 for(it = peer->flt_rule.begin(); it != peer->flt_rule.end(); it++) 786 { 787 if(m_is_ip_addr_assigned[IPA_IP_v4]) 788 { 789 m_p_iface->eth_bridge_del_flt_rule(it->flt_rule_hdl[IPA_IP_v4], IPA_IP_v4); 790 IPACMDBG_H("IPv4 flt rule %d is deleted.\n", it->flt_rule_hdl[IPA_IP_v4]); 791 } 792 if(m_is_ip_addr_assigned[IPA_IP_v6]) 793 { 794 m_p_iface->eth_bridge_del_flt_rule(it->flt_rule_hdl[IPA_IP_v6], IPA_IP_v6); 795 IPACMDBG_H("IPv6 flt rule %d is deleted.\n", it->flt_rule_hdl[IPA_IP_v6]); 796 } 797 } 798 peer->flt_rule.clear(); 799 return; 800 } 801 802 void IPACM_LanToLan_Iface::clear_all_rt_rule_for_one_peer_iface(peer_iface_info *peer) 803 { 804 list<client_info>::iterator it; 805 ipa_hdr_l2_type peer_l2_type; 806 807 peer_l2_type = peer->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type; 808 if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 0) 809 { 810 for(it = m_client_info.begin(); it != m_client_info.end(); it++) 811 { 812 del_client_rt_rule(peer, &(*it)); 813 } 814 } 815 816 return; 817 } 818 819 void IPACM_LanToLan_Iface::handle_wlan_scc_mcc_switch() 820 { 821 list<peer_iface_info>::iterator it_peer_info; 822 list<client_info>::iterator it_client; 823 ipa_hdr_l2_type peer_l2_hdr_type; 824 bool flag[IPA_HDR_L2_MAX]; 825 int i; 826 827 /* modify inter-interface routing rules */ 828 if(m_support_inter_iface_offload) 829 { 830 IPACMDBG_H("Modify rt rules for peer interfaces.\n"); 831 memset(flag, 0, sizeof(flag)); 832 for(it_peer_info = m_peer_iface_info.begin(); it_peer_info != m_peer_iface_info.end(); it_peer_info++) 833 { 834 peer_l2_hdr_type = it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type; 835 if(flag[peer_l2_hdr_type] == false) 836 { 837 flag[peer_l2_hdr_type] = true; 838 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) 839 { 840 m_p_iface->eth_bridge_modify_rt_rule(it_client->mac_addr, hdr_proc_ctx_for_inter_interface[peer_l2_hdr_type], 841 peer_l2_hdr_type, IPA_IP_v4, it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4], 842 it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4]); 843 IPACMDBG_H("The following IPv4 routing rules are modified:\n"); 844 for(i = 0; i < it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v4]; i++) 845 { 846 IPACMDBG_H("%d\n", it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v4][i]); 847 } 848 849 m_p_iface->eth_bridge_modify_rt_rule(it_client->mac_addr, hdr_proc_ctx_for_inter_interface[peer_l2_hdr_type], 850 peer_l2_hdr_type, IPA_IP_v6, it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6], 851 it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6]); 852 IPACMDBG_H("The following IPv6 routing rules are modified:\n"); 853 for(i = 0; i < it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].num_hdl[IPA_IP_v6]; i++) 854 { 855 IPACMDBG_H("%d\n", it_client->inter_iface_rt_rule_hdl[peer_l2_hdr_type].rule_hdl[IPA_IP_v6][i]); 856 } 857 } 858 } 859 } 860 } 861 862 /* modify routing rules for intra-interface communication */ 863 IPACMDBG_H("Modify rt rules for intra-interface communication.\n"); 864 if(m_support_intra_iface_offload) 865 { 866 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) 867 { 868 m_p_iface->eth_bridge_modify_rt_rule(it_client->mac_addr, hdr_proc_ctx_for_intra_interface, 869 m_p_iface->tx_prop->tx[0].hdr_l2_type, IPA_IP_v4, it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4], 870 it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]); 871 IPACMDBG_H("The following IPv4 routing rules are modified:\n"); 872 for(i = 0; i < it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]; i++) 873 { 874 IPACMDBG_H("%d\n", it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][i]); 875 } 876 877 m_p_iface->eth_bridge_modify_rt_rule(it_client->mac_addr, hdr_proc_ctx_for_intra_interface, 878 m_p_iface->tx_prop->tx[0].hdr_l2_type, IPA_IP_v6, it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6], 879 it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]); 880 IPACMDBG_H("The following IPv6 routing rules are modified:\n"); 881 for(i = 0; i < it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]; i++) 882 { 883 IPACMDBG_H("%d\n", it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][i]); 884 } 885 } 886 } 887 888 return; 889 } 890 891 void IPACM_LanToLan_Iface::handle_intra_interface_info() 892 { 893 uint32_t hdr_proc_ctx_hdl; 894 895 if(m_p_iface->tx_prop == NULL) 896 { 897 IPACMERR("No tx prop.\n"); 898 return; 899 } 900 901 m_intra_interface_info.peer = this; 902 903 snprintf(m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX, 904 "eth_v4_intra_interface"); 905 IPACMDBG_H("IPv4 routing table for flt name: %s\n", m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4]); 906 snprintf(m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX, 907 "eth_v6_intra_interface"); 908 IPACMDBG_H("IPv6 routing table for flt name: %s\n", m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v6]); 909 910 memcpy(m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v4], m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v4], 911 IPA_RESOURCE_NAME_MAX); 912 IPACMDBG_H("IPv4 routing table for rt name: %s\n", m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v4]); 913 memcpy(m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v6], m_intra_interface_info.rt_tbl_name_for_flt[IPA_IP_v6], 914 IPA_RESOURCE_NAME_MAX); 915 IPACMDBG_H("IPv6 routing table for rt name: %s\n", m_intra_interface_info.rt_tbl_name_for_rt[IPA_IP_v6]); 916 917 m_p_iface->eth_bridge_add_hdr_proc_ctx(m_p_iface->tx_prop->tx[0].hdr_l2_type, 918 &hdr_proc_ctx_hdl); 919 hdr_proc_ctx_for_intra_interface = hdr_proc_ctx_hdl; 920 IPACMDBG_H("Hdr proc ctx for intra-interface communication: hdl %d\n", hdr_proc_ctx_hdl); 921 922 return; 923 } 924 925 void IPACM_LanToLan_Iface::handle_new_iface_up(char rt_tbl_name_for_flt[][IPA_RESOURCE_NAME_MAX], char rt_tbl_name_for_rt[][IPA_RESOURCE_NAME_MAX], 926 IPACM_LanToLan_Iface *peer_iface) 927 { 928 peer_iface_info new_peer; 929 ipa_hdr_l2_type peer_l2_hdr_type; 930 931 new_peer.peer = peer_iface; 932 memcpy(new_peer.rt_tbl_name_for_rt[IPA_IP_v4], rt_tbl_name_for_rt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX); 933 memcpy(new_peer.rt_tbl_name_for_rt[IPA_IP_v6], rt_tbl_name_for_rt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX); 934 memcpy(new_peer.rt_tbl_name_for_flt[IPA_IP_v4], rt_tbl_name_for_flt[IPA_IP_v4], IPA_RESOURCE_NAME_MAX); 935 memcpy(new_peer.rt_tbl_name_for_flt[IPA_IP_v6], rt_tbl_name_for_flt[IPA_IP_v6], IPA_RESOURCE_NAME_MAX); 936 937 peer_l2_hdr_type = peer_iface->m_p_iface->tx_prop->tx[0].hdr_l2_type; 938 increment_ref_cnt_peer_l2_hdr_type(peer_l2_hdr_type); 939 add_hdr_proc_ctx(peer_l2_hdr_type); 940 941 /* push the new peer_iface_info into the list */ 942 m_peer_iface_info.push_front(new_peer); 943 944 return; 945 } 946 947 void IPACM_LanToLan_Iface::handle_client_add(uint8_t *mac) 948 { 949 list<client_info>::iterator it_client; 950 list<peer_iface_info>::iterator it_peer_info; 951 client_info new_client; 952 bool flag[IPA_HDR_L2_MAX]; 953 954 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) 955 { 956 if(memcmp(it_client->mac_addr, mac, sizeof(it_client->mac_addr)) == 0) 957 { 958 IPACMDBG_H("This client has been added before.\n"); 959 return; 960 } 961 } 962 963 if(m_client_info.size() == MAX_NUM_CLIENT) 964 { 965 IPACMDBG_H("The number of clients has reached maximum %d.\n", MAX_NUM_CLIENT); 966 return; 967 } 968 969 memcpy(new_client.mac_addr, mac, sizeof(new_client.mac_addr)); 970 m_client_info.push_front(new_client); 971 972 client_info &front_client = m_client_info.front(); 973 974 /* install inter-interface rules */ 975 if(m_support_inter_iface_offload) 976 { 977 memset(flag, 0, sizeof(flag)); 978 for(it_peer_info = m_peer_iface_info.begin(); it_peer_info != m_peer_iface_info.end(); it_peer_info++) 979 { 980 /* make sure add routing rule only once for each peer l2 header type */ 981 if(flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] == false) 982 { 983 /* add client routing rule for each peer interface */ 984 add_client_rt_rule(&(*it_peer_info), &front_client); 985 flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] = true; 986 } 987 988 /* add client filtering rule on peer interfaces */ 989 it_peer_info->peer->add_one_client_flt_rule(this, &front_client); 990 } 991 } 992 993 /* install intra-interface rules */ 994 if(m_support_intra_iface_offload) 995 { 996 /* add routing rule first */ 997 add_client_rt_rule(&m_intra_interface_info, &front_client); 998 999 /* add filtering rule */ 1000 if(m_is_ip_addr_assigned[IPA_IP_v4]) 1001 { 1002 add_client_flt_rule(&m_intra_interface_info, &front_client, IPA_IP_v4); 1003 } 1004 if(m_is_ip_addr_assigned[IPA_IP_v6]) 1005 { 1006 add_client_flt_rule(&m_intra_interface_info, &front_client, IPA_IP_v6); 1007 } 1008 } 1009 1010 return; 1011 } 1012 1013 void IPACM_LanToLan_Iface::handle_client_del(uint8_t *mac) 1014 { 1015 list<client_info>::iterator it_client; 1016 list<peer_iface_info>::iterator it_peer_info; 1017 bool flag[IPA_HDR_L2_MAX]; 1018 1019 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) 1020 { 1021 if(memcmp(it_client->mac_addr, mac, sizeof(it_client->mac_addr)) == 0) //found the client 1022 { 1023 IPACMDBG_H("Found the client.\n"); 1024 break; 1025 } 1026 } 1027 1028 if(it_client != m_client_info.end()) //if we found the client 1029 { 1030 /* uninstall inter-interface rules */ 1031 if(m_support_inter_iface_offload) 1032 { 1033 memset(flag, 0, sizeof(flag)); 1034 for(it_peer_info = m_peer_iface_info.begin(); it_peer_info != m_peer_iface_info.end(); 1035 it_peer_info++) 1036 { 1037 IPACMDBG_H("Delete client filtering rule on peer interface.\n"); 1038 it_peer_info->peer->del_one_client_flt_rule(this, &(*it_client)); 1039 1040 /* make sure to delete routing rule only once for each peer l2 header type */ 1041 if(flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] == false) 1042 { 1043 IPACMDBG_H("Delete client routing rule for peer interface.\n"); 1044 del_client_rt_rule(&(*it_peer_info), &(*it_client)); 1045 flag[it_peer_info->peer->get_iface_pointer()->tx_prop->tx[0].hdr_l2_type] = true; 1046 } 1047 } 1048 } 1049 1050 /* uninstall intra-interface rules */ 1051 if(m_support_intra_iface_offload) 1052 { 1053 /* delete filtering rule first */ 1054 IPACMDBG_H("Delete client filtering rule for intra-interface communication.\n"); 1055 del_client_flt_rule(&m_intra_interface_info, &(*it_client)); 1056 1057 /* delete routing rule */ 1058 IPACMDBG_H("Delete client routing rule for intra-interface communication.\n"); 1059 del_client_rt_rule(&m_intra_interface_info, &(*it_client)); 1060 } 1061 1062 /* erase the client from client info list */ 1063 m_client_info.erase(it_client); 1064 } 1065 else 1066 { 1067 IPACMDBG_H("The client is not found.\n"); 1068 } 1069 1070 return; 1071 } 1072 1073 void IPACM_LanToLan_Iface::add_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_type) 1074 { 1075 uint32_t hdr_proc_ctx_hdl; 1076 1077 if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 1) 1078 { 1079 m_p_iface->eth_bridge_add_hdr_proc_ctx(peer_l2_type, &hdr_proc_ctx_hdl); 1080 hdr_proc_ctx_for_inter_interface[peer_l2_type] = hdr_proc_ctx_hdl; 1081 IPACMDBG_H("Installed inter-interface hdr proc ctx on iface %s: handle %d\n", m_p_iface->dev_name, hdr_proc_ctx_hdl); 1082 } 1083 return; 1084 } 1085 1086 void IPACM_LanToLan_Iface::del_hdr_proc_ctx(ipa_hdr_l2_type peer_l2_type) 1087 { 1088 if(ref_cnt_peer_l2_hdr_type[peer_l2_type] == 0) 1089 { 1090 m_p_iface->eth_bridge_del_hdr_proc_ctx(hdr_proc_ctx_for_inter_interface[peer_l2_type]); 1091 IPACMDBG_H("Hdr proc ctx with hdl %d is deleted.\n", hdr_proc_ctx_for_inter_interface[peer_l2_type]); 1092 } 1093 return; 1094 } 1095 1096 void IPACM_LanToLan_Iface::print_data_structure_info() 1097 { 1098 list<peer_iface_info>::iterator it_peer; 1099 list<client_info>::iterator it_client; 1100 int i, j, k; 1101 1102 IPACMDBG_H("\n"); 1103 IPACMDBG_H("Interface %s:\n", m_p_iface->dev_name); 1104 IPACMDBG_H("Is IPv4 addr assigned? %d\n", m_is_ip_addr_assigned[IPA_IP_v4]); 1105 IPACMDBG_H("Is IPv6 addr assigned? %d\n", m_is_ip_addr_assigned[IPA_IP_v6]); 1106 IPACMDBG_H("Support inter interface offload? %d\n", m_support_inter_iface_offload); 1107 IPACMDBG_H("Support intra interface offload? %d\n", m_support_intra_iface_offload); 1108 1109 if(m_support_inter_iface_offload) 1110 { 1111 for(i = 0; i < IPA_HDR_L2_MAX; i++) 1112 { 1113 IPACMDBG_H("Ref_cnt of peer l2 type %s is %d.\n", ipa_l2_hdr_type[i], ref_cnt_peer_l2_hdr_type[i]); 1114 if(ref_cnt_peer_l2_hdr_type[i] > 0) 1115 { 1116 IPACMDBG_H("Hdr proc ctx for peer l2 type %s: %d\n", ipa_l2_hdr_type[i], hdr_proc_ctx_for_inter_interface[i]); 1117 } 1118 } 1119 } 1120 1121 if(m_support_intra_iface_offload) 1122 { 1123 IPACMDBG_H("Hdr proc ctx for intra-interface: %d\n", hdr_proc_ctx_for_intra_interface); 1124 } 1125 1126 i = 1; 1127 IPACMDBG_H("There are %d clients in total.\n", m_client_info.size()); 1128 for(it_client = m_client_info.begin(); it_client != m_client_info.end(); it_client++) 1129 { 1130 IPACMDBG_H("Client %d MAC: 0x%02x%02x%02x%02x%02x%02x Pointer: 0x%08x\n", i, it_client->mac_addr[0], it_client->mac_addr[1], 1131 it_client->mac_addr[2], it_client->mac_addr[3], it_client->mac_addr[4], it_client->mac_addr[5], &(*it_client)); 1132 1133 if(m_support_inter_iface_offload) 1134 { 1135 for(j = 0; j < IPA_HDR_L2_MAX; j++) 1136 { 1137 if(ref_cnt_peer_l2_hdr_type[j] > 0) 1138 { 1139 IPACMDBG_H("Printing routing rule info for inter-interface communication for peer l2 type %s.\n", 1140 ipa_l2_hdr_type[j]); 1141 IPACMDBG_H("Number of IPv4 routing rules is %d, handles:\n", it_client->inter_iface_rt_rule_hdl[j].num_hdl[IPA_IP_v4]); 1142 for(k = 0; k < it_client->inter_iface_rt_rule_hdl[j].num_hdl[IPA_IP_v4]; k++) 1143 { 1144 IPACMDBG_H("%d\n", it_client->inter_iface_rt_rule_hdl[j].rule_hdl[IPA_IP_v4][k]); 1145 } 1146 1147 IPACMDBG_H("Number of IPv6 routing rules is %d, handles:\n", it_client->inter_iface_rt_rule_hdl[j].num_hdl[IPA_IP_v6]); 1148 for(k = 0; k < it_client->inter_iface_rt_rule_hdl[j].num_hdl[IPA_IP_v6]; k++) 1149 { 1150 IPACMDBG_H("%d\n", it_client->inter_iface_rt_rule_hdl[j].rule_hdl[IPA_IP_v6][k]); 1151 } 1152 } 1153 } 1154 } 1155 1156 if(m_support_intra_iface_offload) 1157 { 1158 IPACMDBG_H("Printing routing rule info for intra-interface communication.\n"); 1159 IPACMDBG_H("Number of IPv4 routing rules is %d, handles:\n", it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]); 1160 for(j = 0; j < it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v4]; j++) 1161 { 1162 IPACMDBG_H("%d\n", it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v4][j]); 1163 } 1164 1165 IPACMDBG_H("Number of IPv6 routing rules is %d, handles:\n", it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]); 1166 for(j = 0; j < it_client->intra_iface_rt_rule_hdl.num_hdl[IPA_IP_v6]; j++) 1167 { 1168 IPACMDBG_H("%d\n", it_client->intra_iface_rt_rule_hdl.rule_hdl[IPA_IP_v6][j]); 1169 } 1170 } 1171 i++; 1172 } 1173 1174 IPACMDBG_H("There are %d peer interfaces in total.\n", m_peer_iface_info.size()); 1175 for(it_peer = m_peer_iface_info.begin(); it_peer != m_peer_iface_info.end(); it_peer++) 1176 { 1177 print_peer_info(&(*it_peer)); 1178 } 1179 1180 if(m_support_intra_iface_offload) 1181 { 1182 IPACMDBG_H("This interface supports intra-interface communication, printing info:\n"); 1183 print_peer_info(&m_intra_interface_info); 1184 } 1185 1186 return; 1187 } 1188 1189 void IPACM_LanToLan_Iface::print_peer_info(peer_iface_info *peer_info) 1190 { 1191 list<flt_rule_info>::iterator it_flt; 1192 list<rt_rule_info>::iterator it_rt; 1193 1194 IPACMDBG_H("Printing peer info for iface %s:\n", peer_info->peer->m_p_iface->dev_name); 1195 1196 IPACMDBG_H("There are %d flt info in total.\n", peer_info->flt_rule.size()); 1197 for(it_flt = peer_info->flt_rule.begin(); it_flt != peer_info->flt_rule.end(); it_flt++) 1198 { 1199 IPACMDBG_H("Flt rule handle for client 0x%08x:\n", it_flt->p_client); 1200 if(m_is_ip_addr_assigned[IPA_IP_v4]) 1201 { 1202 IPACMDBG_H("IPv4 %d\n", it_flt->flt_rule_hdl[IPA_IP_v4]); 1203 } 1204 if(m_is_ip_addr_assigned[IPA_IP_v6]) 1205 { 1206 IPACMDBG_H("IPv6 %d\n", it_flt->flt_rule_hdl[IPA_IP_v6]); 1207 } 1208 } 1209 1210 return; 1211 } 1212 1213 IPACM_Lan* IPACM_LanToLan_Iface::get_iface_pointer() 1214 { 1215 return m_p_iface; 1216 } 1217 1218 bool IPACM_LanToLan_Iface::get_m_is_ip_addr_assigned(ipa_ip_type iptype) 1219 { 1220 IPACMDBG_H("Has IP address been assigned to interface %s for IP type %d? %d\n", 1221 m_p_iface->dev_name, iptype, m_is_ip_addr_assigned[iptype]); 1222 return m_is_ip_addr_assigned[iptype]; 1223 } 1224 1225 void IPACM_LanToLan_Iface::set_m_is_ip_addr_assigned(ipa_ip_type iptype, bool value) 1226 { 1227 IPACMDBG_H("Is IP address of IP type %d assigned to interface %s? %d\n", iptype, 1228 m_p_iface->dev_name, value); 1229 m_is_ip_addr_assigned[iptype] = value; 1230 } 1231 1232 bool IPACM_LanToLan_Iface::get_m_support_inter_iface_offload() 1233 { 1234 IPACMDBG_H("Support inter interface offload on %s? %d\n", m_p_iface->dev_name, 1235 m_support_inter_iface_offload); 1236 return m_support_inter_iface_offload; 1237 } 1238 1239 bool IPACM_LanToLan_Iface::get_m_support_intra_iface_offload() 1240 { 1241 IPACMDBG_H("Support intra interface offload on %s? %d\n", m_p_iface->dev_name, 1242 m_support_intra_iface_offload); 1243 return m_support_intra_iface_offload; 1244 } 1245 1246 void IPACM_LanToLan_Iface::increment_ref_cnt_peer_l2_hdr_type(ipa_hdr_l2_type peer_l2_type) 1247 { 1248 ref_cnt_peer_l2_hdr_type[peer_l2_type]++; 1249 IPACMDBG_H("Now the ref_cnt of peer l2 hdr type %s is %d.\n", ipa_l2_hdr_type[peer_l2_type], 1250 ref_cnt_peer_l2_hdr_type[peer_l2_type]); 1251 1252 return; 1253 } 1254 1255 void IPACM_LanToLan_Iface::decrement_ref_cnt_peer_l2_hdr_type(ipa_hdr_l2_type peer_l2_type) 1256 { 1257 ref_cnt_peer_l2_hdr_type[peer_l2_type]--; 1258 IPACMDBG_H("Now the ref_cnt of peer l2 hdr type %s is %d.\n", ipa_l2_hdr_type[peer_l2_type], 1259 ref_cnt_peer_l2_hdr_type[peer_l2_type]); 1260 1261 return; 1262 } 1263