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