1 /* 2 Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are 6 met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above 10 copyright notice, this list of conditions and the following 11 disclaimer in the documentation and/or other materials provided 12 with the distribution. 13 * Neither the name of The Linux Foundation nor the names of its 14 contributors may be used to endorse or promote products derived 15 from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 /*! 30 @file 31 IPACM_Wan.cpp 32 33 @brief 34 This file implements the WAN iface functionality. 35 36 @Author 37 Skylar Chang 38 39 */ 40 #ifndef IPACM_WAN_H 41 #define IPACM_WAN_H 42 43 #include <stdio.h> 44 #include <IPACM_CmdQueue.h> 45 #include <linux/msm_ipa.h> 46 #include "IPACM_Routing.h" 47 #include "IPACM_Filtering.h" 48 #include <IPACM_Iface.h> 49 #include <IPACM_Defs.h> 50 #include <IPACM_Xml.h> 51 52 #define IPA_NUM_DEFAULT_WAN_FILTER_RULES 3 /*1 for v4, 2 for v6*/ 53 #define IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV4 2 54 55 #ifdef FEATURE_IPA_ANDROID 56 #define IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6 6 57 #else 58 #define IPA_V2_NUM_DEFAULT_WAN_FILTER_RULE_IPV6 3 59 #endif 60 61 #define NETWORK_STATS "%s %lu %lu %lu %lu" 62 #define IPA_NETWORK_STATS_FILE_NAME "/data/misc/ipa/network_stats" 63 64 typedef struct _wan_client_rt_hdl 65 { 66 uint32_t wan_rt_rule_hdl_v4; 67 uint32_t wan_rt_rule_hdl_v6[IPV6_NUM_ADDR]; 68 uint32_t wan_rt_rule_hdl_v6_wan[IPV6_NUM_ADDR]; 69 }wan_client_rt_hdl; 70 71 typedef struct _ipa_wan_client 72 { 73 ipacm_event_data_wlan_ex* p_hdr_info; 74 uint8_t mac[IPA_MAC_ADDR_SIZE]; 75 uint32_t v4_addr; 76 uint32_t v6_addr[IPV6_NUM_ADDR][4]; 77 uint32_t hdr_hdl_v4; 78 uint32_t hdr_hdl_v6; 79 bool route_rule_set_v4; 80 int route_rule_set_v6; 81 bool ipv4_set; 82 int ipv6_set; 83 bool ipv4_header_set; 84 bool ipv6_header_set; 85 bool power_save_set; 86 wan_client_rt_hdl wan_rt_hdl[0]; /* depends on number of tx properties */ 87 }ipa_wan_client; 88 89 /* wan iface */ 90 class IPACM_Wan : public IPACM_Iface 91 { 92 93 public: 94 95 static bool wan_up; 96 static bool wan_up_v6; 97 static uint8_t xlat_mux_id; 98 /* IPACM interface name */ 99 static char wan_up_dev_name[IF_NAME_LEN]; 100 static uint32_t curr_wan_ip; 101 IPACM_Wan(int, ipacm_wan_iface_type, uint8_t *); 102 virtual ~IPACM_Wan(); 103 isWanUP(int ipa_if_num_tether)104 static bool isWanUP(int ipa_if_num_tether) 105 { 106 #ifdef FEATURE_IPA_ANDROID 107 #ifdef FEATURE_IPACM_HAL 108 /*To avoid -Wall -Werror error */ 109 IPACMDBG_H("ipa_if_num_tether: %d\n",ipa_if_num_tether); 110 return wan_up; 111 #else 112 113 uint32_t i; 114 for (i=0; i < ipa_if_num_tether_v4_total;i++) 115 { 116 if (ipa_if_num_tether_v4[i] == ipa_if_num_tether) 117 { 118 IPACMDBG_H("support ipv4 tether_iface(%s)\n", 119 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name); 120 return wan_up; 121 break; 122 } 123 } 124 return false; 125 #endif 126 #else 127 return wan_up; 128 #endif 129 } 130 isWanUP_V6(int ipa_if_num_tether)131 static bool isWanUP_V6(int ipa_if_num_tether) 132 { 133 #ifdef FEATURE_IPA_ANDROID 134 #ifdef FEATURE_IPACM_HAL 135 /*To avoid -Wall -Werror error */ 136 IPACMDBG_H("ipa_if_num_tether: %d\n",ipa_if_num_tether); 137 return wan_up_v6; 138 #else 139 uint32_t i; 140 for (i=0; i < ipa_if_num_tether_v6_total;i++) 141 { 142 if (ipa_if_num_tether_v6[i] == ipa_if_num_tether) 143 { 144 IPACMDBG_H("support ipv6 tether_iface(%s)\n", 145 IPACM_Iface::ipacmcfg->iface_table[ipa_if_num_tether].iface_name); 146 return wan_up_v6; 147 break; 148 } 149 } 150 return false; 151 #endif 152 #else 153 return wan_up_v6; 154 #endif 155 } 156 getWANIP()157 static uint32_t getWANIP() 158 { 159 return curr_wan_ip; 160 } 161 getXlat_Mux_Id()162 static bool getXlat_Mux_Id() 163 { 164 return xlat_mux_id; 165 } 166 167 void event_callback(ipa_cm_event_id event, 168 void *data); 169 170 static struct ipa_flt_rule_add flt_rule_v4[IPA_MAX_FLT_RULE]; 171 static struct ipa_flt_rule_add flt_rule_v6[IPA_MAX_FLT_RULE]; 172 173 static int num_v4_flt_rule; 174 static int num_v6_flt_rule; 175 176 ipacm_wan_iface_type m_is_sta_mode; 177 static bool backhaul_is_sta_mode; 178 static bool is_ext_prop_set; 179 static uint32_t backhaul_ipv6_prefix[2]; 180 181 static bool embms_is_on; 182 static bool backhaul_is_wan_bridge; 183 isWan_Bridge_Mode()184 static bool isWan_Bridge_Mode() 185 { 186 return backhaul_is_wan_bridge; 187 } 188 #ifdef FEATURE_IPA_ANDROID 189 /* IPACM interface id */ 190 static uint32_t ipa_if_num_tether_v4_total; 191 static int ipa_if_num_tether_v4[IPA_MAX_IFACE_ENTRIES]; 192 static uint32_t ipa_if_num_tether_v6_total; 193 static int ipa_if_num_tether_v6[IPA_MAX_IFACE_ENTRIES]; 194 #endif 195 196 private: 197 198 bool is_ipv6_frag_firewall_flt_rule_installed; 199 uint32_t ipv6_frag_firewall_flt_rule_hdl; 200 uint32_t *wan_route_rule_v4_hdl; 201 uint32_t *wan_route_rule_v6_hdl; 202 uint32_t *wan_route_rule_v6_hdl_a5; 203 uint32_t hdr_hdl_sta_v4; 204 uint32_t hdr_hdl_sta_v6; 205 uint32_t firewall_hdl_v4[IPACM_MAX_FIREWALL_ENTRIES]; 206 uint32_t firewall_hdl_v6[IPACM_MAX_FIREWALL_ENTRIES]; 207 uint32_t dft_wan_fl_hdl[IPA_NUM_DEFAULT_WAN_FILTER_RULES]; 208 uint32_t ipv6_dest_flt_rule_hdl[MAX_DEFAULT_v6_ROUTE_RULES]; 209 int num_ipv6_dest_flt_rule; 210 uint32_t ODU_fl_hdl[IPA_NUM_DEFAULT_WAN_FILTER_RULES]; 211 int num_firewall_v4,num_firewall_v6; 212 uint32_t wan_v4_addr; 213 uint32_t wan_v4_addr_gw; 214 uint32_t wan_v6_addr_gw[4]; 215 bool wan_v4_addr_set; 216 bool wan_v4_addr_gw_set; 217 bool wan_v6_addr_gw_set; 218 bool active_v4; 219 bool active_v6; 220 bool header_set_v4; 221 bool header_set_v6; 222 bool header_partial_default_wan_v4; 223 bool header_partial_default_wan_v6; 224 uint8_t ext_router_mac_addr[IPA_MAC_ADDR_SIZE]; 225 uint8_t netdev_mac[IPA_MAC_ADDR_SIZE]; 226 227 static int num_ipv4_modem_pdn; 228 229 static int num_ipv6_modem_pdn; 230 231 int modem_ipv4_pdn_index; 232 233 int modem_ipv6_pdn_index; 234 235 bool is_default_gateway; 236 237 uint32_t ipv6_prefix[2]; 238 239 /* IPACM firewall Configuration file*/ 240 IPACM_firewall_conf_t firewall_config; 241 242 /* STA mode wan-client*/ 243 int wan_client_len; 244 ipa_wan_client *wan_client; 245 int header_name_count; 246 uint32_t num_wan_client; 247 uint8_t invalid_mac[IPA_MAC_ADDR_SIZE]; 248 bool is_xlat; 249 250 /* update network stats for CNE */ 251 int ipa_network_stats_fd; 252 uint32_t hdr_hdl_dummy_v6; 253 uint32_t hdr_proc_hdl_dummy_v6; 254 get_client_memptr(ipa_wan_client * param,int cnt)255 inline ipa_wan_client* get_client_memptr(ipa_wan_client *param, int cnt) 256 { 257 char *ret = ((char *)param) + (wan_client_len * cnt); 258 return (ipa_wan_client *)ret; 259 } 260 get_wan_client_index(uint8_t * mac_addr)261 inline int get_wan_client_index(uint8_t *mac_addr) 262 { 263 int cnt; 264 int num_wan_client_tmp = num_wan_client; 265 266 IPACMDBG_H("Passed MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 267 mac_addr[0], mac_addr[1], mac_addr[2], 268 mac_addr[3], mac_addr[4], mac_addr[5]); 269 270 for(cnt = 0; cnt < num_wan_client_tmp; cnt++) 271 { 272 IPACMDBG_H("stored MAC %02x:%02x:%02x:%02x:%02x:%02x\n", 273 get_client_memptr(wan_client, cnt)->mac[0], 274 get_client_memptr(wan_client, cnt)->mac[1], 275 get_client_memptr(wan_client, cnt)->mac[2], 276 get_client_memptr(wan_client, cnt)->mac[3], 277 get_client_memptr(wan_client, cnt)->mac[4], 278 get_client_memptr(wan_client, cnt)->mac[5]); 279 280 if(memcmp(get_client_memptr(wan_client, cnt)->mac, 281 mac_addr, 282 sizeof(get_client_memptr(wan_client, cnt)->mac)) == 0) 283 { 284 IPACMDBG_H("Matched client index: %d\n", cnt); 285 return cnt; 286 } 287 } 288 289 return IPACM_INVALID_INDEX; 290 } 291 get_wan_client_index_ipv4(uint32_t ipv4_addr)292 inline int get_wan_client_index_ipv4(uint32_t ipv4_addr) 293 { 294 int cnt; 295 int num_wan_client_tmp = num_wan_client; 296 297 IPACMDBG_H("Passed IPv4 %x\n", ipv4_addr); 298 299 for(cnt = 0; cnt < num_wan_client_tmp; cnt++) 300 { 301 if (get_client_memptr(wan_client, cnt)->ipv4_set) 302 { 303 IPACMDBG_H("stored IPv4 %x\n", get_client_memptr(wan_client, cnt)->v4_addr); 304 305 if(ipv4_addr == get_client_memptr(wan_client, cnt)->v4_addr) 306 { 307 IPACMDBG_H("Matched client index: %d\n", cnt); 308 IPACMDBG_H("The MAC is %02x:%02x:%02x:%02x:%02x:%02x\n", 309 get_client_memptr(wan_client, cnt)->mac[0], 310 get_client_memptr(wan_client, cnt)->mac[1], 311 get_client_memptr(wan_client, cnt)->mac[2], 312 get_client_memptr(wan_client, cnt)->mac[3], 313 get_client_memptr(wan_client, cnt)->mac[4], 314 get_client_memptr(wan_client, cnt)->mac[5]); 315 IPACMDBG_H("header set ipv4(%d) ipv6(%d)\n", 316 get_client_memptr(wan_client, cnt)->ipv4_header_set, 317 get_client_memptr(wan_client, cnt)->ipv6_header_set); 318 return cnt; 319 } 320 } 321 } 322 return IPACM_INVALID_INDEX; 323 } 324 get_wan_client_index_ipv6(uint32_t * ipv6_addr)325 inline int get_wan_client_index_ipv6(uint32_t* ipv6_addr) 326 { 327 int cnt, v6_num; 328 int num_wan_client_tmp = num_wan_client; 329 330 IPACMDBG_H("Get ipv6 address 0x%08x.0x%08x.0x%08x.0x%08x\n", ipv6_addr[0], ipv6_addr[1], ipv6_addr[2], ipv6_addr[3]); 331 332 for(cnt = 0; cnt < num_wan_client_tmp; cnt++) 333 { 334 if (get_client_memptr(wan_client, cnt)->ipv6_set) 335 { 336 for(v6_num=0;v6_num < get_client_memptr(wan_client, cnt)->ipv6_set;v6_num++) 337 { 338 339 IPACMDBG_H("stored IPv6 0x%08x.0x%08x.0x%08x.0x%08x\n", get_client_memptr(wan_client, cnt)->v6_addr[v6_num][0], 340 get_client_memptr(wan_client, cnt)->v6_addr[v6_num][1], 341 get_client_memptr(wan_client, cnt)->v6_addr[v6_num][2], 342 get_client_memptr(wan_client, cnt)->v6_addr[v6_num][3]); 343 344 if(ipv6_addr[0] == get_client_memptr(wan_client, cnt)->v6_addr[v6_num][0] && 345 ipv6_addr[1] == get_client_memptr(wan_client, cnt)->v6_addr[v6_num][1] && 346 ipv6_addr[2]== get_client_memptr(wan_client, cnt)->v6_addr[v6_num][2] && 347 ipv6_addr[3] == get_client_memptr(wan_client, cnt)->v6_addr[v6_num][3]) 348 { 349 IPACMDBG_H("Matched client index: %d\n", cnt); 350 IPACMDBG_H("The MAC is %02x:%02x:%02x:%02x:%02x:%02x\n", 351 get_client_memptr(wan_client, cnt)->mac[0], 352 get_client_memptr(wan_client, cnt)->mac[1], 353 get_client_memptr(wan_client, cnt)->mac[2], 354 get_client_memptr(wan_client, cnt)->mac[3], 355 get_client_memptr(wan_client, cnt)->mac[4], 356 get_client_memptr(wan_client, cnt)->mac[5]); 357 IPACMDBG_H("header set ipv4(%d) ipv6(%d)\n", 358 get_client_memptr(wan_client, cnt)->ipv4_header_set, 359 get_client_memptr(wan_client, cnt)->ipv6_header_set); 360 return cnt; 361 } 362 } 363 } 364 } 365 return IPACM_INVALID_INDEX; 366 } 367 delete_wan_rtrules(int clt_indx,ipa_ip_type iptype)368 inline int delete_wan_rtrules(int clt_indx, ipa_ip_type iptype) 369 { 370 uint32_t tx_index; 371 uint32_t rt_hdl; 372 int num_v6; 373 374 if(iptype == IPA_IP_v4) 375 { 376 for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) 377 { 378 if((tx_prop->tx[tx_index].ip == IPA_IP_v4) && (get_client_memptr(wan_client, clt_indx)->route_rule_set_v4==true)) /* for ipv4 */ 379 { 380 IPACMDBG_H("Delete client index %d ipv4 Qos rules for tx:%d \n",clt_indx,tx_index); 381 rt_hdl = get_client_memptr(wan_client, clt_indx)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v4; 382 383 if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v4) == false) 384 { 385 return IPACM_FAILURE; 386 } 387 } 388 } /* end of for loop */ 389 390 /* clean the 4 Qos ipv4 RT rules for client:clt_indx */ 391 if(get_client_memptr(wan_client, clt_indx)->route_rule_set_v4==true) /* for ipv4 */ 392 { 393 get_client_memptr(wan_client, clt_indx)->route_rule_set_v4 = false; 394 } 395 } 396 397 if(iptype == IPA_IP_v6) 398 { 399 for(tx_index = 0; tx_index < iface_query->num_tx_props; tx_index++) 400 { 401 402 if((tx_prop->tx[tx_index].ip == IPA_IP_v6) && (get_client_memptr(wan_client, clt_indx)->route_rule_set_v6 != 0)) /* for ipv6 */ 403 { 404 for(num_v6 =0;num_v6 < get_client_memptr(wan_client, clt_indx)->route_rule_set_v6;num_v6++) 405 { 406 IPACMDBG_H("Delete client index %d ipv6 Qos rules for %d-st ipv6 for tx:%d\n", clt_indx,num_v6,tx_index); 407 rt_hdl = get_client_memptr(wan_client, clt_indx)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6[num_v6]; 408 if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false) 409 { 410 return IPACM_FAILURE; 411 } 412 413 rt_hdl = get_client_memptr(wan_client, clt_indx)->wan_rt_hdl[tx_index].wan_rt_rule_hdl_v6_wan[num_v6]; 414 if(m_routing.DeleteRoutingHdl(rt_hdl, IPA_IP_v6) == false) 415 { 416 return IPACM_FAILURE; 417 } 418 } 419 420 } 421 } /* end of for loop */ 422 423 /* clean the 4 Qos ipv6 RT rules for client:clt_indx */ 424 if(get_client_memptr(wan_client, clt_indx)->route_rule_set_v6 != 0) /* for ipv6 */ 425 { 426 get_client_memptr(wan_client, clt_indx)->route_rule_set_v6 = 0; 427 } 428 } 429 430 return IPACM_SUCCESS; 431 } 432 433 int handle_wan_hdr_init(uint8_t *mac_addr); 434 int handle_wan_client_ipaddr(ipacm_event_data_all *data); 435 int handle_wan_client_route_rule(uint8_t *mac_addr, ipa_ip_type iptype); 436 437 /* handle new_address event */ 438 int handle_addr_evt(ipacm_event_data_addr *data); 439 440 /* wan default route/filter rule configuration */ 441 int handle_route_add_evt(ipa_ip_type iptype); 442 443 /* construct complete STA ethernet header */ 444 int handle_sta_header_add_evt(); 445 446 bool check_dft_firewall_rules_attr_mask(IPACM_firewall_conf_t *firewall_config); 447 448 #ifdef FEATURE_IPA_ANDROID 449 /* wan posting supported tether_iface */ 450 int post_wan_up_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether); 451 452 int post_wan_down_tether_evt(ipa_ip_type iptype, int ipa_if_num_tether); 453 #endif 454 int config_dft_firewall_rules(ipa_ip_type iptype); 455 456 /* configure the initial firewall filter rules */ 457 int config_dft_embms_rules(ipa_ioc_add_flt_rule *pFilteringTable_v4, ipa_ioc_add_flt_rule *pFilteringTable_v6); 458 459 int handle_route_del_evt(ipa_ip_type iptype); 460 461 int del_dft_firewall_rules(ipa_ip_type iptype); 462 463 int handle_down_evt(); 464 465 /*handle wan-iface down event */ 466 int handle_down_evt_ex(); 467 468 /* wan default route/filter rule delete */ 469 int handle_route_del_evt_ex(ipa_ip_type iptype); 470 471 /* configure the initial firewall filter rules */ 472 int config_dft_firewall_rules_ex(struct ipa_flt_rule_add* rules, int rule_offset, 473 ipa_ip_type iptype); 474 475 /* init filtering rule in wan dl filtering table */ 476 int init_fl_rule_ex(ipa_ip_type iptype); 477 478 /* add ICMP and ALG rules in wan dl filtering table */ 479 int add_icmp_alg_rules(struct ipa_flt_rule_add* rules, int rule_offset, ipa_ip_type iptype); 480 481 /* query extended property */ 482 int query_ext_prop(); 483 484 ipa_ioc_query_intf_ext_props *ext_prop; 485 486 int config_wan_firewall_rule(ipa_ip_type iptype); 487 488 int del_wan_firewall_rule(ipa_ip_type iptype); 489 490 int add_dft_filtering_rule(struct ipa_flt_rule_add* rules, int rule_offset, ipa_ip_type iptype); 491 492 int install_wan_filtering_rule(bool is_sw_routing); 493 494 void change_to_network_order(ipa_ip_type iptype, ipa_rule_attrib* attrib); 495 496 bool is_global_ipv6_addr(uint32_t* ipv6_addr); 497 498 void handle_wlan_SCC_MCC_switch(bool, ipa_ip_type); 499 500 void handle_wan_client_SCC_MCC_switch(bool, ipa_ip_type); 501 502 int handle_network_stats_evt(); 503 504 int m_fd_ipa; 505 506 int handle_network_stats_update(ipa_get_apn_data_stats_resp_msg_v01 *data); 507 508 /* construct dummy ethernet header */ 509 int add_dummy_rx_hdr(); 510 }; 511 512 #endif /* IPACM_WAN_H */ 513