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