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