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