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