Home | History | Annotate | Download | only in src
      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