1 /* 2 Copyright (c) 2013-2016, 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_Config.cpp 32 33 @brief 34 This file implements the IPACM Configuration from XML file 35 36 @Author 37 Skylar Chang 38 39 */ 40 #include <IPACM_Config.h> 41 #include <IPACM_Log.h> 42 #include <IPACM_Iface.h> 43 #include <sys/ioctl.h> 44 #include <fcntl.h> 45 46 IPACM_Config *IPACM_Config::pInstance = NULL; 47 const char *IPACM_Config::DEVICE_NAME = "/dev/ipa"; 48 const char *IPACM_Config::DEVICE_NAME_ODU = "/dev/odu_ipa_bridge"; 49 50 #define __stringify(x...) #x 51 52 const char *ipacm_event_name[] = { 53 __stringify(IPA_CFG_CHANGE_EVENT), /* NULL */ 54 __stringify(IPA_PRIVATE_SUBNET_CHANGE_EVENT), /* ipacm_event_data_fid */ 55 __stringify(IPA_FIREWALL_CHANGE_EVENT), /* NULL */ 56 __stringify(IPA_LINK_UP_EVENT), /* ipacm_event_data_fid */ 57 __stringify(IPA_LINK_DOWN_EVENT), /* ipacm_event_data_fid */ 58 __stringify(IPA_USB_LINK_UP_EVENT), /* ipacm_event_data_fid */ 59 __stringify(IPA_BRIDGE_LINK_UP_EVENT), /* ipacm_event_data_all */ 60 __stringify(IPA_WAN_EMBMS_LINK_UP_EVENT), /* ipacm_event_data_mac */ 61 __stringify(IPA_ADDR_ADD_EVENT), /* ipacm_event_data_addr */ 62 __stringify(IPA_ADDR_DEL_EVENT), /* no use */ 63 __stringify(IPA_ROUTE_ADD_EVENT), /* ipacm_event_data_addr */ 64 __stringify(IPA_ROUTE_DEL_EVENT), /* ipacm_event_data_addr */ 65 __stringify(IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT), /* ipacm_event_data_fid */ 66 __stringify(IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT), /* ipacm_event_data_fid */ 67 __stringify(IPA_WLAN_AP_LINK_UP_EVENT), /* ipacm_event_data_mac */ 68 __stringify(IPA_WLAN_STA_LINK_UP_EVENT), /* ipacm_event_data_mac */ 69 __stringify(IPA_WLAN_LINK_DOWN_EVENT), /* ipacm_event_data_mac */ 70 __stringify(IPA_WLAN_CLIENT_ADD_EVENT), /* ipacm_event_data_mac */ 71 __stringify(IPA_WLAN_CLIENT_ADD_EVENT_EX), /* ipacm_event_data_wlan_ex */ 72 __stringify(IPA_WLAN_CLIENT_DEL_EVENT), /* ipacm_event_data_mac */ 73 __stringify(IPA_WLAN_CLIENT_POWER_SAVE_EVENT), /* ipacm_event_data_mac */ 74 __stringify(IPA_WLAN_CLIENT_RECOVER_EVENT), /* ipacm_event_data_mac */ 75 __stringify(IPA_NEW_NEIGH_EVENT), /* ipacm_event_data_all */ 76 __stringify(IPA_DEL_NEIGH_EVENT), /* ipacm_event_data_all */ 77 __stringify(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT), /* ipacm_event_data_all */ 78 __stringify(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT), /* ipacm_event_data_all */ 79 __stringify(IPA_SW_ROUTING_ENABLE), /* NULL */ 80 __stringify(IPA_SW_ROUTING_DISABLE), /* NULL */ 81 __stringify(IPA_PROCESS_CT_MESSAGE), /* ipacm_ct_evt_data */ 82 __stringify(IPA_PROCESS_CT_MESSAGE_V6), /* ipacm_ct_evt_data */ 83 __stringify(IPA_LAN_TO_LAN_NEW_CONNECTION), /* ipacm_event_connection */ 84 __stringify(IPA_LAN_TO_LAN_DEL_CONNECTION), /* ipacm_event_connection */ 85 __stringify(IPA_WLAN_SWITCH_TO_SCC), /* No Data */ 86 __stringify(IPA_WLAN_SWITCH_TO_MCC), /* No Data */ 87 __stringify(IPA_CRADLE_WAN_MODE_SWITCH), /* ipacm_event_cradle_wan_mode */ 88 __stringify(IPA_WAN_XLAT_CONNECT_EVENT), /* ipacm_event_data_fid */ 89 __stringify(IPA_TETHERING_STATS_UPDATE_EVENT), /* ipacm_event_data_fid */ 90 __stringify(IPA_NETWORK_STATS_UPDATE_EVENT), /* ipacm_event_data_fid */ 91 __stringify(IPA_DOWNSTREAM_ADD), /* ipacm_event_ipahal_stream */ 92 __stringify(IPA_DOWNSTREAM_DEL), /* ipacm_event_ipahal_stream */ 93 __stringify(IPA_EXTERNAL_EVENT_MAX), 94 __stringify(IPA_HANDLE_WAN_UP), /* ipacm_event_iface_up */ 95 __stringify(IPA_HANDLE_WAN_DOWN), /* ipacm_event_iface_up */ 96 __stringify(IPA_HANDLE_WAN_UP_V6), /* NULL */ 97 __stringify(IPA_HANDLE_WAN_DOWN_V6), /* NULL */ 98 __stringify(IPA_HANDLE_WAN_UP_TETHER), /* ipacm_event_iface_up_tehter */ 99 __stringify(IPA_HANDLE_WAN_DOWN_TETHER), /* ipacm_event_iface_up_tehter */ 100 __stringify(IPA_HANDLE_WAN_UP_V6_TETHER), /* ipacm_event_iface_up_tehter */ 101 __stringify(IPA_HANDLE_WAN_DOWN_V6_TETHER), /* ipacm_event_iface_up_tehter */ 102 __stringify(IPA_HANDLE_WLAN_UP), /* ipacm_event_iface_up */ 103 __stringify(IPA_HANDLE_LAN_UP), /* ipacm_event_iface_up */ 104 __stringify(IPA_ETH_BRIDGE_IFACE_UP), /* ipacm_event_eth_bridge*/ 105 __stringify(IPA_ETH_BRIDGE_IFACE_DOWN), /* ipacm_event_eth_bridge*/ 106 __stringify(IPA_ETH_BRIDGE_CLIENT_ADD), /* ipacm_event_eth_bridge*/ 107 __stringify(IPA_ETH_BRIDGE_CLIENT_DEL), /* ipacm_event_eth_bridge*/ 108 __stringify(IPA_ETH_BRIDGE_WLAN_SCC_MCC_SWITCH), /* ipacm_event_eth_bridge*/ 109 __stringify(IPA_LAN_DELETE_SELF), /* ipacm_event_data_fid */ 110 __stringify(IPACM_EVENT_MAX), 111 }; 112 113 IPACM_Config::IPACM_Config() 114 { 115 iface_table = NULL; 116 alg_table = NULL; 117 pNatIfaces = NULL; 118 memset(&ipa_client_rm_map_tbl, 0, sizeof(ipa_client_rm_map_tbl)); 119 memset(&ipa_rm_tbl, 0, sizeof(ipa_rm_tbl)); 120 ipa_rm_a2_check=0; 121 ipacm_odu_enable = false; 122 ipacm_odu_router_mode = false; 123 ipa_num_wlan_guest_ap = 0; 124 125 ipa_num_ipa_interfaces = 0; 126 ipa_num_private_subnet = 0; 127 ipa_num_alg_ports = 0; 128 ipa_nat_max_entries = 0; 129 ipa_nat_iface_entries = 0; 130 ipa_sw_rt_enable = false; 131 ipa_bridge_enable = false; 132 isMCC_Mode = false; 133 ipa_max_valid_rm_entry = 0; 134 135 memset(&rt_tbl_default_v4, 0, sizeof(rt_tbl_default_v4)); 136 memset(&rt_tbl_lan_v4, 0, sizeof(rt_tbl_lan_v4)); 137 memset(&rt_tbl_wan_v4, 0, sizeof(rt_tbl_wan_v4)); 138 memset(&rt_tbl_v6, 0, sizeof(rt_tbl_v6)); 139 memset(&rt_tbl_wan_v6, 0, sizeof(rt_tbl_wan_v6)); 140 memset(&rt_tbl_wan_dl, 0, sizeof(rt_tbl_wan_dl)); 141 memset(&rt_tbl_odu_v4, 0, sizeof(rt_tbl_odu_v4)); 142 memset(&rt_tbl_odu_v6, 0, sizeof(rt_tbl_odu_v6)); 143 144 memset(&ext_prop_v4, 0, sizeof(ext_prop_v4)); 145 memset(&ext_prop_v6, 0, sizeof(ext_prop_v6)); 146 147 qmap_id = ~0; 148 149 memset(flt_rule_count_v4, 0, (IPA_CLIENT_CONS - IPA_CLIENT_PROD)*sizeof(int)); 150 memset(flt_rule_count_v6, 0, (IPA_CLIENT_CONS - IPA_CLIENT_PROD)*sizeof(int)); 151 memset(bridge_mac, 0, IPA_MAC_ADDR_SIZE*sizeof(uint8_t)); 152 153 IPACMDBG_H(" create IPACM_Config constructor\n"); 154 return; 155 } 156 157 int IPACM_Config::Init(void) 158 { 159 /* Read IPACM Config file */ 160 char IPACM_config_file[IPA_MAX_FILE_LEN]; 161 IPACM_conf_t *cfg; 162 cfg = (IPACM_conf_t *)malloc(sizeof(IPACM_conf_t)); 163 if(cfg == NULL) 164 { 165 IPACMERR("Unable to allocate cfg memory.\n"); 166 return IPACM_FAILURE; 167 } 168 uint32_t subnet_addr; 169 uint32_t subnet_mask; 170 int i, ret = IPACM_SUCCESS; 171 struct in_addr in_addr_print; 172 173 m_fd = open(DEVICE_NAME, O_RDWR); 174 if (0 > m_fd) 175 { 176 IPACMERR("Failed opening %s.\n", DEVICE_NAME); 177 } 178 #ifdef FEATURE_IPACM_HAL 179 strncpy(IPACM_config_file, "/vendor/etc/IPACM_cfg.xml", sizeof(IPACM_config_file)); 180 #else 181 strncpy(IPACM_config_file, "/etc/IPACM_cfg.xml", sizeof(IPACM_config_file)); 182 #endif 183 184 IPACMDBG_H("\n IPACM XML file is %s \n", IPACM_config_file); 185 if (IPACM_SUCCESS == ipacm_read_cfg_xml(IPACM_config_file, cfg)) 186 { 187 IPACMDBG_H("\n IPACM XML read OK \n"); 188 } 189 else 190 { 191 IPACMERR("\n IPACM XML read failed \n"); 192 ret = IPACM_FAILURE; 193 goto fail; 194 } 195 196 /* Construct IPACM Iface table */ 197 ipa_num_ipa_interfaces = cfg->iface_config.num_iface_entries; 198 if (iface_table != NULL) 199 { 200 free(iface_table); 201 iface_table = NULL; 202 IPACMDBG_H("RESET IPACM_Config::iface_table\n"); 203 } 204 iface_table = (ipa_ifi_dev_name_t *)calloc(ipa_num_ipa_interfaces, 205 sizeof(ipa_ifi_dev_name_t)); 206 if(iface_table == NULL) 207 { 208 IPACMERR("Unable to allocate iface_table memory.\n"); 209 ret = IPACM_FAILURE; 210 goto fail; 211 } 212 213 for (i = 0; i < cfg->iface_config.num_iface_entries; i++) 214 { 215 strncpy(iface_table[i].iface_name, cfg->iface_config.iface_entries[i].iface_name, sizeof(iface_table[i].iface_name)); 216 iface_table[i].if_cat = cfg->iface_config.iface_entries[i].if_cat; 217 iface_table[i].if_mode = cfg->iface_config.iface_entries[i].if_mode; 218 iface_table[i].wlan_mode = cfg->iface_config.iface_entries[i].wlan_mode; 219 IPACMDBG_H("IPACM_Config::iface_table[%d] = %s, cat=%d, mode=%d wlan-mode=%d \n", i, iface_table[i].iface_name, 220 iface_table[i].if_cat, iface_table[i].if_mode, iface_table[i].wlan_mode); 221 /* copy bridge interface name to ipacmcfg */ 222 if( iface_table[i].if_cat == VIRTUAL_IF) 223 { 224 strlcpy(ipa_virtual_iface_name, iface_table[i].iface_name, sizeof(ipa_virtual_iface_name)); 225 IPACMDBG_H("ipa_virtual_iface_name(%s) \n", ipa_virtual_iface_name); 226 } 227 } 228 229 /* Construct IPACM Private_Subnet table */ 230 memset(&private_subnet_table, 0, sizeof(private_subnet_table)); 231 ipa_num_private_subnet = cfg->private_subnet_config.num_subnet_entries; 232 233 for (i = 0; i < cfg->private_subnet_config.num_subnet_entries; i++) 234 { 235 memcpy(&private_subnet_table[i].subnet_addr, 236 &cfg->private_subnet_config.private_subnet_entries[i].subnet_addr, 237 sizeof(cfg->private_subnet_config.private_subnet_entries[i].subnet_addr)); 238 239 memcpy(&private_subnet_table[i].subnet_mask, 240 &cfg->private_subnet_config.private_subnet_entries[i].subnet_mask, 241 sizeof(cfg->private_subnet_config.private_subnet_entries[i].subnet_mask)); 242 243 subnet_addr = htonl(private_subnet_table[i].subnet_addr); 244 memcpy(&in_addr_print,&subnet_addr,sizeof(in_addr_print)); 245 IPACMDBG_H("%dst::private_subnet_table= %s \n ", i, 246 inet_ntoa(in_addr_print)); 247 248 subnet_mask = htonl(private_subnet_table[i].subnet_mask); 249 memcpy(&in_addr_print,&subnet_mask,sizeof(in_addr_print)); 250 IPACMDBG_H("%dst::private_subnet_table= %s \n ", i, 251 inet_ntoa(in_addr_print)); 252 } 253 254 /* Construct IPACM ALG table */ 255 ipa_num_alg_ports = cfg->alg_config.num_alg_entries; 256 if (alg_table != NULL) 257 { 258 free(alg_table); 259 alg_table = NULL; 260 IPACMDBG_H("RESET IPACM_Config::alg_table \n"); 261 } 262 alg_table = (ipacm_alg *)calloc(ipa_num_alg_ports, 263 sizeof(ipacm_alg)); 264 if(alg_table == NULL) 265 { 266 IPACMERR("Unable to allocate alg_table memory.\n"); 267 ret = IPACM_FAILURE; 268 free(iface_table); 269 goto fail;; 270 } 271 for (i = 0; i < cfg->alg_config.num_alg_entries; i++) 272 { 273 alg_table[i].protocol = cfg->alg_config.alg_entries[i].protocol; 274 alg_table[i].port = cfg->alg_config.alg_entries[i].port; 275 IPACMDBG_H("IPACM_Config::ipacm_alg[%d] = %d, port=%d\n", i, alg_table[i].protocol, alg_table[i].port); 276 } 277 278 ipa_nat_max_entries = cfg->nat_max_entries; 279 IPACMDBG_H("Nat Maximum Entries %d\n", ipa_nat_max_entries); 280 281 /* Find ODU is either router mode or bridge mode*/ 282 ipacm_odu_enable = cfg->odu_enable; 283 ipacm_odu_router_mode = cfg->router_mode_enable; 284 ipacm_odu_embms_enable = cfg->odu_embms_enable; 285 IPACMDBG_H("ipacm_odu_enable %d\n", ipacm_odu_enable); 286 IPACMDBG_H("ipacm_odu_mode %d\n", ipacm_odu_router_mode); 287 IPACMDBG_H("ipacm_odu_embms_enable %d\n", ipacm_odu_embms_enable); 288 289 ipacm_ip_passthrough_mode = cfg->ip_passthrough_mode; 290 IPACMDBG_H("ipacm_ip_passthrough_mode %d. \n", ipacm_ip_passthrough_mode); 291 292 ipa_num_wlan_guest_ap = cfg->num_wlan_guest_ap; 293 IPACMDBG_H("ipa_num_wlan_guest_ap %d\n",ipa_num_wlan_guest_ap); 294 295 /* Allocate more non-nat entries if the monitored iface dun have Tx/Rx properties */ 296 if (pNatIfaces != NULL) 297 { 298 free(pNatIfaces); 299 pNatIfaces = NULL; 300 IPACMDBG_H("RESET IPACM_Config::pNatIfaces \n"); 301 } 302 ipa_nat_iface_entries = 0; 303 pNatIfaces = (NatIfaces *)calloc(ipa_num_ipa_interfaces, sizeof(NatIfaces)); 304 if (pNatIfaces == NULL) 305 { 306 IPACMERR("unable to allocate nat ifaces\n"); 307 ret = IPACM_FAILURE; 308 free(iface_table); 309 free(alg_table); 310 goto fail; 311 } 312 313 /* Construct the routing table ictol name in iface static member*/ 314 rt_tbl_default_v4.ip = IPA_IP_v4; 315 strncpy(rt_tbl_default_v4.name, V4_DEFAULT_ROUTE_TABLE_NAME, sizeof(rt_tbl_default_v4.name)); 316 317 rt_tbl_lan_v4.ip = IPA_IP_v4; 318 strncpy(rt_tbl_lan_v4.name, V4_LAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_lan_v4.name)); 319 320 rt_tbl_wan_v4.ip = IPA_IP_v4; 321 strncpy(rt_tbl_wan_v4.name, V4_WAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_v4.name)); 322 323 rt_tbl_v6.ip = IPA_IP_v6; 324 strncpy(rt_tbl_v6.name, V6_COMMON_ROUTE_TABLE_NAME, sizeof(rt_tbl_v6.name)); 325 326 rt_tbl_wan_v6.ip = IPA_IP_v6; 327 strncpy(rt_tbl_wan_v6.name, V6_WAN_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_v6.name)); 328 329 rt_tbl_odu_v4.ip = IPA_IP_v4; 330 strncpy(rt_tbl_odu_v4.name, V4_ODU_ROUTE_TABLE_NAME, sizeof(rt_tbl_odu_v4.name)); 331 332 rt_tbl_odu_v6.ip = IPA_IP_v6; 333 strncpy(rt_tbl_odu_v6.name, V6_ODU_ROUTE_TABLE_NAME, sizeof(rt_tbl_odu_v6.name)); 334 335 rt_tbl_wan_dl.ip = IPA_IP_MAX; 336 strncpy(rt_tbl_wan_dl.name, WAN_DL_ROUTE_TABLE_NAME, sizeof(rt_tbl_wan_dl.name)); 337 338 /* Construct IPACM ipa_client map to rm_resource table */ 339 ipa_client_rm_map_tbl[IPA_CLIENT_WLAN1_PROD]= IPA_RM_RESOURCE_WLAN_PROD; 340 ipa_client_rm_map_tbl[IPA_CLIENT_USB_PROD]= IPA_RM_RESOURCE_USB_PROD; 341 ipa_client_rm_map_tbl[IPA_CLIENT_A5_WLAN_AMPDU_PROD]= IPA_RM_RESOURCE_HSIC_PROD; 342 ipa_client_rm_map_tbl[IPA_CLIENT_A2_EMBEDDED_PROD]= IPA_RM_RESOURCE_Q6_PROD; 343 ipa_client_rm_map_tbl[IPA_CLIENT_A2_TETHERED_PROD]= IPA_RM_RESOURCE_Q6_PROD; 344 ipa_client_rm_map_tbl[IPA_CLIENT_APPS_LAN_WAN_PROD]= IPA_RM_RESOURCE_Q6_PROD; 345 ipa_client_rm_map_tbl[IPA_CLIENT_WLAN1_CONS]= IPA_RM_RESOURCE_WLAN_CONS; 346 ipa_client_rm_map_tbl[IPA_CLIENT_WLAN2_CONS]= IPA_RM_RESOURCE_WLAN_CONS; 347 ipa_client_rm_map_tbl[IPA_CLIENT_WLAN3_CONS]= IPA_RM_RESOURCE_WLAN_CONS; 348 ipa_client_rm_map_tbl[IPA_CLIENT_WLAN4_CONS]= IPA_RM_RESOURCE_WLAN_CONS; 349 ipa_client_rm_map_tbl[IPA_CLIENT_USB_CONS]= IPA_RM_RESOURCE_USB_CONS; 350 ipa_client_rm_map_tbl[IPA_CLIENT_A2_EMBEDDED_CONS]= IPA_RM_RESOURCE_Q6_CONS; 351 ipa_client_rm_map_tbl[IPA_CLIENT_A2_TETHERED_CONS]= IPA_RM_RESOURCE_Q6_CONS; 352 ipa_client_rm_map_tbl[IPA_CLIENT_APPS_WAN_CONS]= IPA_RM_RESOURCE_Q6_CONS; 353 ipa_client_rm_map_tbl[IPA_CLIENT_ODU_PROD]= IPA_RM_RESOURCE_ODU_ADAPT_PROD; 354 ipa_client_rm_map_tbl[IPA_CLIENT_ODU_EMB_CONS]= IPA_RM_RESOURCE_ODU_ADAPT_CONS; 355 ipa_client_rm_map_tbl[IPA_CLIENT_ODU_TETH_CONS]= IPA_RM_RESOURCE_ODU_ADAPT_CONS; 356 357 /* Create the entries which IPACM wants to add dependencies on */ 358 ipa_rm_tbl[0].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD; 359 ipa_rm_tbl[0].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS; 360 ipa_rm_tbl[0].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD; 361 ipa_rm_tbl[0].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS; 362 363 ipa_rm_tbl[1].producer_rm1 = IPA_RM_RESOURCE_USB_PROD; 364 ipa_rm_tbl[1].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS; 365 ipa_rm_tbl[1].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD; 366 ipa_rm_tbl[1].consumer_rm2 = IPA_RM_RESOURCE_USB_CONS; 367 368 ipa_rm_tbl[2].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD; 369 ipa_rm_tbl[2].consumer_rm1 = IPA_RM_RESOURCE_USB_CONS; 370 ipa_rm_tbl[2].producer_rm2 = IPA_RM_RESOURCE_USB_PROD; 371 ipa_rm_tbl[2].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS; 372 373 ipa_rm_tbl[3].producer_rm1 = IPA_RM_RESOURCE_ODU_ADAPT_PROD; 374 ipa_rm_tbl[3].consumer_rm1 = IPA_RM_RESOURCE_Q6_CONS; 375 ipa_rm_tbl[3].producer_rm2 = IPA_RM_RESOURCE_Q6_PROD; 376 ipa_rm_tbl[3].consumer_rm2 = IPA_RM_RESOURCE_ODU_ADAPT_CONS; 377 378 ipa_rm_tbl[4].producer_rm1 = IPA_RM_RESOURCE_WLAN_PROD; 379 ipa_rm_tbl[4].consumer_rm1 = IPA_RM_RESOURCE_ODU_ADAPT_CONS; 380 ipa_rm_tbl[4].producer_rm2 = IPA_RM_RESOURCE_ODU_ADAPT_PROD; 381 ipa_rm_tbl[4].consumer_rm2 = IPA_RM_RESOURCE_WLAN_CONS; 382 383 ipa_rm_tbl[5].producer_rm1 = IPA_RM_RESOURCE_ODU_ADAPT_PROD; 384 ipa_rm_tbl[5].consumer_rm1 = IPA_RM_RESOURCE_USB_CONS; 385 ipa_rm_tbl[5].producer_rm2 = IPA_RM_RESOURCE_USB_PROD; 386 ipa_rm_tbl[5].consumer_rm2 = IPA_RM_RESOURCE_ODU_ADAPT_CONS; 387 ipa_max_valid_rm_entry = 6; /* max is IPA_MAX_RM_ENTRY (6)*/ 388 389 IPACMDBG_H(" depend MAP-0 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_Q6_CONS); 390 IPACMDBG_H(" depend MAP-1 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_USB_PROD, IPA_RM_RESOURCE_Q6_CONS); 391 IPACMDBG_H(" depend MAP-2 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_USB_CONS); 392 IPACMDBG_H(" depend MAP-3 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_ODU_ADAPT_PROD, IPA_RM_RESOURCE_Q6_CONS); 393 IPACMDBG_H(" depend MAP-4 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_WLAN_PROD, IPA_RM_RESOURCE_ODU_ADAPT_CONS); 394 IPACMDBG_H(" depend MAP-5 rm index %d to rm index: %d \n", IPA_RM_RESOURCE_ODU_ADAPT_PROD, IPA_RM_RESOURCE_USB_CONS); 395 396 fail: 397 if (cfg != NULL) 398 { 399 free(cfg); 400 cfg = NULL; 401 } 402 403 return ret; 404 } 405 406 IPACM_Config* IPACM_Config::GetInstance() 407 { 408 int res = IPACM_SUCCESS; 409 410 if (pInstance == NULL) 411 { 412 pInstance = new IPACM_Config(); 413 414 res = pInstance->Init(); 415 if (res != IPACM_SUCCESS) 416 { 417 delete pInstance; 418 IPACMERR("unable to initialize config instance\n"); 419 return NULL; 420 } 421 } 422 423 return pInstance; 424 } 425 426 int IPACM_Config::GetAlgPorts(int nPorts, ipacm_alg *pAlgPorts) 427 { 428 if (nPorts <= 0 || pAlgPorts == NULL) 429 { 430 IPACMERR("Invalid input\n"); 431 return -1; 432 } 433 434 for (int cnt = 0; cnt < nPorts; cnt++) 435 { 436 pAlgPorts[cnt].protocol = alg_table[cnt].protocol; 437 pAlgPorts[cnt].port = alg_table[cnt].port; 438 } 439 440 return 0; 441 } 442 443 int IPACM_Config::GetNatIfaces(int nIfaces, NatIfaces *pIfaces) 444 { 445 if (nIfaces <= 0 || pIfaces == NULL) 446 { 447 IPACMERR("Invalid input\n"); 448 return -1; 449 } 450 451 for (int cnt=0; cnt<nIfaces; cnt++) 452 { 453 memcpy(pIfaces[cnt].iface_name, 454 pNatIfaces[cnt].iface_name, 455 sizeof(pIfaces[cnt].iface_name)); 456 } 457 458 return 0; 459 } 460 461 462 int IPACM_Config::AddNatIfaces(char *dev_name) 463 { 464 int i; 465 /* Check if this iface already in NAT-iface*/ 466 for(i = 0; i < ipa_nat_iface_entries; i++) 467 { 468 if(strncmp(dev_name, 469 pNatIfaces[i].iface_name, 470 sizeof(pNatIfaces[i].iface_name)) == 0) 471 { 472 IPACMDBG("Interface (%s) is add to nat iface already\n", dev_name); 473 return 0; 474 } 475 } 476 477 IPACMDBG_H("Add iface %s to NAT-ifaces, origin it has %d nat ifaces\n", 478 dev_name, ipa_nat_iface_entries); 479 ipa_nat_iface_entries++; 480 481 if (ipa_nat_iface_entries < ipa_num_ipa_interfaces) 482 { 483 strlcpy(pNatIfaces[ipa_nat_iface_entries - 1].iface_name, 484 dev_name, IPA_IFACE_NAME_LEN); 485 486 IPACMDBG_H("Add Nat IfaceName: %s ,update nat-ifaces number: %d\n", 487 pNatIfaces[ipa_nat_iface_entries - 1].iface_name, 488 ipa_nat_iface_entries); 489 } 490 491 return 0; 492 } 493 494 int IPACM_Config::DelNatIfaces(char *dev_name) 495 { 496 int i = 0; 497 IPACMDBG_H("Del iface %s from NAT-ifaces, origin it has %d nat ifaces\n", 498 dev_name, ipa_nat_iface_entries); 499 500 for (i = 0; i < ipa_nat_iface_entries; i++) 501 { 502 if (strcmp(dev_name, pNatIfaces[i].iface_name) == 0) 503 { 504 IPACMDBG_H("Found Nat IfaceName: %s with nat-ifaces number: %d\n", 505 pNatIfaces[i].iface_name, ipa_nat_iface_entries); 506 507 /* Reset the matched entry */ 508 memset(pNatIfaces[i].iface_name, 0, IPA_IFACE_NAME_LEN); 509 510 for (; i < ipa_nat_iface_entries - 1; i++) 511 { 512 memcpy(pNatIfaces[i].iface_name, 513 pNatIfaces[i + 1].iface_name, IPA_IFACE_NAME_LEN); 514 515 /* Reset the copied entry */ 516 memset(pNatIfaces[i + 1].iface_name, 0, IPA_IFACE_NAME_LEN); 517 } 518 ipa_nat_iface_entries--; 519 IPACMDBG_H("Update nat-ifaces number: %d\n", ipa_nat_iface_entries); 520 return 0; 521 } 522 } 523 524 IPACMDBG_H("Can't find Nat IfaceName: %s with total nat-ifaces number: %d\n", 525 dev_name, ipa_nat_iface_entries); 526 return 0; 527 } 528 529 int IPACM_Config::CheckNatIfaces(const char *dev_name) 530 { 531 int i = 0; 532 IPACMDBG_H("Check iface %s from NAT-ifaces, currently it has %d nat ifaces\n", 533 dev_name, ipa_nat_iface_entries); 534 535 for (i = 0; i < ipa_nat_iface_entries; i++) 536 { 537 if (strcmp(dev_name, pNatIfaces[i].iface_name) == 0) 538 { 539 IPACMDBG_H("Find Nat IfaceName: %s ,previous nat-ifaces number: %d\n", 540 pNatIfaces[i].iface_name, ipa_nat_iface_entries); 541 return 0; 542 } 543 } 544 IPACMDBG_H("Can't find Nat IfaceName: %s with total nat-ifaces number: %d\n", 545 dev_name, ipa_nat_iface_entries); 546 return -1; 547 } 548 549 /* for IPACM resource manager dependency usage 550 add either Tx or Rx ipa_rm_resource_name and 551 also indicate that endpoint property if valid */ 552 void IPACM_Config::AddRmDepend(ipa_rm_resource_name rm1,bool rx_bypass_ipa) 553 { 554 int retval = 0; 555 struct ipa_ioc_rm_dependency dep; 556 557 IPACMDBG_H(" Got rm add-depend index : %d \n", rm1); 558 /* ipa_rm_a2_check: IPA_RM_RESOURCE_Q6_CONS*/ 559 if(rm1 == IPA_RM_RESOURCE_Q6_CONS) 560 { 561 ipa_rm_a2_check+=1; 562 IPACMDBG_H("got %d times default RT routing from A2 \n", ipa_rm_a2_check); 563 } 564 565 for(int i=0;i<ipa_max_valid_rm_entry;i++) 566 { 567 if(rm1 == ipa_rm_tbl[i].producer_rm1) 568 { 569 ipa_rm_tbl[i].producer1_up = true; 570 /* entry1's producer actually dun have registered Rx-property */ 571 ipa_rm_tbl[i].rx_bypass_ipa = rx_bypass_ipa; 572 IPACMDBG_H("Matched RM_table entry: %d's producer_rm1 with non_rx_prop: %d \n", i,ipa_rm_tbl[i].rx_bypass_ipa); 573 574 if(ipa_rm_tbl[i].consumer1_up == true && ipa_rm_tbl[i].rm_set == false) 575 { 576 IPACMDBG_H("SETUP RM_table entry %d's bi-direction dependency \n", i); 577 /* add bi-directional dependency*/ 578 if(ipa_rm_tbl[i].rx_bypass_ipa) 579 { 580 IPACMDBG_H("Skip ADD entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1); 581 } 582 else 583 { 584 memset(&dep, 0, sizeof(dep)); 585 dep.resource_name = ipa_rm_tbl[i].producer_rm1; 586 dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1; 587 retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep); 588 IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name); 589 if (retval) 590 { 591 IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval); 592 } 593 } 594 memset(&dep, 0, sizeof(dep)); 595 dep.resource_name = ipa_rm_tbl[i].producer_rm2; 596 dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2; 597 retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep); 598 IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name); 599 if (retval) 600 { 601 IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval); 602 } 603 ipa_rm_tbl[i].rm_set = true; 604 } 605 else 606 { 607 IPACMDBG_H("Not SETUP RM_table entry %d: prod_up:%d, cons_up:%d, rm_set: %d \n", i,ipa_rm_tbl[i].producer1_up, ipa_rm_tbl[i].consumer1_up, ipa_rm_tbl[i].rm_set); 608 } 609 } 610 611 if(rm1 == ipa_rm_tbl[i].consumer_rm1) 612 { 613 ipa_rm_tbl[i].consumer1_up = true; 614 IPACMDBG_H("Matched RM_table entry: %d's consumer_rm1 \n", i); 615 616 if(ipa_rm_tbl[i].producer1_up == true && ipa_rm_tbl[i].rm_set == false) 617 { 618 IPACMDBG_H("SETUP RM_table entry %d's bi-direction dependency \n", i); 619 /* add bi-directional dependency*/ 620 if(ipa_rm_tbl[i].rx_bypass_ipa) 621 { 622 IPACMDBG_H("Skip ADD entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1); 623 } 624 else 625 { 626 memset(&dep, 0, sizeof(dep)); 627 dep.resource_name = ipa_rm_tbl[i].producer_rm1; 628 dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1; 629 retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep); 630 IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name); 631 if (retval) 632 { 633 IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval); 634 } 635 } 636 637 memset(&dep, 0, sizeof(dep)); 638 dep.resource_name = ipa_rm_tbl[i].producer_rm2; 639 dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2; 640 retval = ioctl(m_fd, IPA_IOC_RM_ADD_DEPENDENCY, &dep); 641 IPACMDBG_H("ADD entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name); 642 if (retval) 643 { 644 IPACMERR("Failed adding dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval); 645 } 646 ipa_rm_tbl[i].rm_set = true; 647 } 648 else 649 { 650 IPACMDBG_H("Not SETUP RM_table entry %d: prod_up:%d, cons_up:%d, rm_set: %d \n", i,ipa_rm_tbl[i].producer1_up, ipa_rm_tbl[i].consumer1_up, ipa_rm_tbl[i].rm_set); 651 } 652 } 653 } 654 return ; 655 } 656 657 /* for IPACM resource manager dependency usage 658 delete either Tx or Rx ipa_rm_resource_name */ 659 660 void IPACM_Config::DelRmDepend(ipa_rm_resource_name rm1) 661 { 662 int retval = 0; 663 struct ipa_ioc_rm_dependency dep; 664 665 IPACMDBG_H(" Got rm del-depend index : %d \n", rm1); 666 /* ipa_rm_a2_check: IPA_RM_RESOURCE_Q6_CONS*/ 667 if(rm1 == IPA_RM_RESOURCE_Q6_CONS) 668 { 669 ipa_rm_a2_check-=1; 670 IPACMDBG_H("Left %d times default RT routing from A2 \n", ipa_rm_a2_check); 671 } 672 673 for(int i=0;i<ipa_max_valid_rm_entry;i++) 674 { 675 676 if(rm1 == ipa_rm_tbl[i].producer_rm1) 677 { 678 if(ipa_rm_tbl[i].rm_set == true) 679 { 680 IPACMDBG_H("Matched RM_table entry: %d's producer_rm1 and dependency is up \n", i); 681 ipa_rm_tbl[i].rm_set = false; 682 683 /* delete bi-directional dependency*/ 684 if(ipa_rm_tbl[i].rx_bypass_ipa) 685 { 686 IPACMDBG_H("Skip DEL entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1); 687 } 688 else 689 { 690 memset(&dep, 0, sizeof(dep)); 691 dep.resource_name = ipa_rm_tbl[i].producer_rm1; 692 dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1; 693 retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep); 694 IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name); 695 if (retval) 696 { 697 IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval); 698 } 699 } 700 memset(&dep, 0, sizeof(dep)); 701 dep.resource_name = ipa_rm_tbl[i].producer_rm2; 702 dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2; 703 retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep); 704 IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name); 705 if (retval) 706 { 707 IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval); 708 } 709 } 710 ipa_rm_tbl[i].producer1_up = false; 711 ipa_rm_tbl[i].rx_bypass_ipa = false; 712 } 713 if(rm1 == ipa_rm_tbl[i].consumer_rm1) 714 { 715 /* ipa_rm_a2_check: IPA_RM_RESOURCE_!6_CONS*/ 716 if(ipa_rm_tbl[i].consumer_rm1 == IPA_RM_RESOURCE_Q6_CONS && ipa_rm_a2_check == 1) 717 { 718 IPACMDBG_H(" still have %d default RT routing from A2 \n", ipa_rm_a2_check); 719 continue; 720 } 721 722 if(ipa_rm_tbl[i].rm_set == true) 723 { 724 IPACMDBG_H("Matched RM_table entry: %d's consumer_rm1 and dependency is up \n", i); 725 ipa_rm_tbl[i].rm_set = false; 726 /* delete bi-directional dependency*/ 727 if(ipa_rm_tbl[i].rx_bypass_ipa) 728 { 729 IPACMDBG_H("Skip DEL entry %d's dependency between WLAN-Pro: %d, Con: %d \n", i, ipa_rm_tbl[i].producer_rm1,ipa_rm_tbl[i].consumer_rm1); 730 } 731 else 732 { 733 memset(&dep, 0, sizeof(dep)); 734 dep.resource_name = ipa_rm_tbl[i].producer_rm1; 735 dep.depends_on_name = ipa_rm_tbl[i].consumer_rm1; 736 retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep); 737 IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name); 738 if (retval) 739 { 740 IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval); 741 } 742 } 743 744 memset(&dep, 0, sizeof(dep)); 745 dep.resource_name = ipa_rm_tbl[i].producer_rm2; 746 dep.depends_on_name = ipa_rm_tbl[i].consumer_rm2; 747 retval = ioctl(m_fd, IPA_IOC_RM_DEL_DEPENDENCY, &dep); 748 IPACMDBG_H("Delete entry %d's dependency between Pro: %d, Con: %d \n", i,dep.resource_name,dep.depends_on_name); 749 if (retval) 750 { 751 IPACMERR("Failed deleting dependecny for RM_table entry %d's bi-direction dependency (error:%d) \n", i,retval); 752 } 753 } 754 ipa_rm_tbl[i].consumer1_up = false; 755 } 756 } 757 return ; 758 } 759 760 int IPACM_Config::SetExtProp(ipa_ioc_query_intf_ext_props *prop) 761 { 762 int i, num; 763 764 if(prop == NULL || prop->num_ext_props <= 0) 765 { 766 IPACMERR("There is no extended property!\n"); 767 return IPACM_FAILURE; 768 } 769 770 num = prop->num_ext_props; 771 for(i=0; i<num; i++) 772 { 773 if(prop->ext[i].ip == IPA_IP_v4) 774 { 775 if(ext_prop_v4.num_ext_props >= MAX_NUM_EXT_PROPS) 776 { 777 IPACMERR("IPv4 extended property table is full!\n"); 778 continue; 779 } 780 memcpy(&ext_prop_v4.prop[ext_prop_v4.num_ext_props], &prop->ext[i], sizeof(struct ipa_ioc_ext_intf_prop)); 781 ext_prop_v4.num_ext_props++; 782 } 783 else if(prop->ext[i].ip == IPA_IP_v6) 784 { 785 if(ext_prop_v6.num_ext_props >= MAX_NUM_EXT_PROPS) 786 { 787 IPACMERR("IPv6 extended property table is full!\n"); 788 continue; 789 } 790 memcpy(&ext_prop_v6.prop[ext_prop_v6.num_ext_props], &prop->ext[i], sizeof(struct ipa_ioc_ext_intf_prop)); 791 ext_prop_v6.num_ext_props++; 792 } 793 else 794 { 795 IPACMERR("The IP type is not expected!\n"); 796 return IPACM_FAILURE; 797 } 798 } 799 800 IPACMDBG_H("Set extended property succeeded.\n"); 801 802 return IPACM_SUCCESS; 803 } 804 805 ipacm_ext_prop* IPACM_Config::GetExtProp(ipa_ip_type ip_type) 806 { 807 if(ip_type == IPA_IP_v4) 808 return &ext_prop_v4; 809 else if(ip_type == IPA_IP_v6) 810 return &ext_prop_v6; 811 else 812 { 813 IPACMERR("Failed to get extended property: the IP version is neither IPv4 nor IPv6!\n"); 814 return NULL; 815 } 816 } 817 818 int IPACM_Config::DelExtProp(ipa_ip_type ip_type) 819 { 820 if(ip_type != IPA_IP_v6) 821 { 822 memset(&ext_prop_v4, 0, sizeof(ext_prop_v4)); 823 } 824 825 if(ip_type != IPA_IP_v4) 826 { 827 memset(&ext_prop_v6, 0, sizeof(ext_prop_v6)); 828 } 829 830 return IPACM_SUCCESS; 831 } 832 833 const char* IPACM_Config::getEventName(ipa_cm_event_id event_id) 834 { 835 if(event_id >= sizeof(ipacm_event_name)/sizeof(ipacm_event_name[0])) 836 { 837 IPACMERR("Event name array is not consistent with event array!\n"); 838 return NULL; 839 } 840 841 return ipacm_event_name[event_id]; 842 } 843