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