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