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_Main.cpp
32
33 @brief
34 This file implements the IPAM functionality.
35
36 @Author
37 Skylar Chang
38
39 */
40 /******************************************************************************
41
42 IPCM_MAIN.C
43
44 ******************************************************************************/
45
46 #include <sys/socket.h>
47 #include <signal.h>
48 #include <fcntl.h>
49 #include <pthread.h>
50 #include <sys/ioctl.h>
51 #include <linux/if.h>
52 #include <linux/netlink.h>
53 #include <linux/rtnetlink.h>
54 #include <fcntl.h>
55 #include <sys/inotify.h>
56 #include <stdlib.h>
57 #include <signal.h>
58 #include "linux/ipa_qmi_service_v01.h"
59
60 #include "IPACM_CmdQueue.h"
61 #include "IPACM_EvtDispatcher.h"
62 #include "IPACM_Defs.h"
63 #include "IPACM_Neighbor.h"
64 #include "IPACM_IfaceManager.h"
65 #include "IPACM_Log.h"
66 #include "IPACM_Wan.h"
67
68 #include "IPACM_ConntrackListener.h"
69 #include "IPACM_ConntrackClient.h"
70 #include "IPACM_Netlink.h"
71
72 #ifdef FEATURE_IPACM_HAL
73 #include "IPACM_OffloadManager.h"
74 #include <HAL.h>
75 #endif
76
77 #include "IPACM_LanToLan.h"
78
79 #define IPA_DRIVER "/dev/ipa"
80
81 #define IPACM_FIREWALL_FILE_NAME "mobileap_firewall.xml"
82 #define IPACM_CFG_FILE_NAME "IPACM_cfg.xml"
83 #ifdef FEATURE_IPA_ANDROID
84 #define IPACM_PID_FILE "/data/vendor/ipa/ipacm.pid"
85 #define IPACM_DIR_NAME "/data"
86 #else/* defined(FEATURE_IPA_ANDROID) */
87 #define IPACM_PID_FILE "/etc/ipacm.pid"
88 #define IPACM_DIR_NAME "/etc"
89 #endif /* defined(NOT FEATURE_IPA_ANDROID)*/
90 #define IPACM_NAME "ipacm"
91
92 #define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
93 #define INOTIFY_BUF_LEN (INOTIFY_EVENT_SIZE + 2*sizeof(IPACM_FIREWALL_FILE_NAME))
94
95 #define IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS 3
96 #define IPA_DRIVER_WLAN_EVENT_SIZE (sizeof(struct ipa_wlan_msg_ex)+ IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS*sizeof(ipa_wlan_hdr_attrib_val))
97 #define IPA_DRIVER_PIPE_STATS_EVENT_SIZE (sizeof(struct ipa_get_data_stats_resp_msg_v01))
98 #define IPA_DRIVER_WLAN_META_MSG (sizeof(struct ipa_msg_meta))
99 #define IPA_DRIVER_WLAN_BUF_LEN (IPA_DRIVER_PIPE_STATS_EVENT_SIZE + IPA_DRIVER_WLAN_META_MSG)
100
101 uint32_t ipacm_event_stats[IPACM_EVENT_MAX];
102 bool ipacm_logging = true;
103
104 void ipa_is_ipacm_running(void);
105 int ipa_get_if_index(char *if_name, int *if_index);
106
107 IPACM_Neighbor *neigh;
108 IPACM_IfaceManager *ifacemgr;
109
110 #ifdef FEATURE_IPACM_RESTART
111 int ipa_reset();
112 /* support ipacm restart */
113 int ipa_query_wlan_client();
114 #endif
115
116
117 /* support ipa-hw-index-counters */
118 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
119 int ipa_reset_hw_index_counter();
120 #endif
121
122 #ifdef FEATURE_IPACM_HAL
123 IPACM_OffloadManager* OffloadMng;
124 HAL *hal;
125 #endif
126
127 /* start netlink socket monitor*/
netlink_start(void * param)128 void* netlink_start(void *param)
129 {
130 param = NULL;
131 ipa_nl_sk_fd_set_info_t sk_fdset;
132 int ret_val = 0;
133 memset(&sk_fdset, 0, sizeof(ipa_nl_sk_fd_set_info_t));
134 IPACMDBG_H("netlink starter memset sk_fdset succeeds\n");
135 ret_val = ipa_nl_listener_init(NETLINK_ROUTE, (RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_LINK |
136 RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NEIGH |
137 RTNLGRP_IPV6_PREFIX),
138 &sk_fdset, ipa_nl_recv_msg);
139
140 if (ret_val != IPACM_SUCCESS)
141 {
142 IPACMERR("Failed to initialize IPA netlink event listener\n");
143 return NULL;
144 }
145
146 return NULL;
147 }
148
149 /* start firewall-rule monitor*/
firewall_monitor(void * param)150 void* firewall_monitor(void *param)
151 {
152 int length;
153 int wd;
154 char buffer[INOTIFY_BUF_LEN];
155 int inotify_fd;
156 ipacm_cmd_q_data evt_data;
157 uint32_t mask = IN_MODIFY | IN_MOVE;
158
159 param = NULL;
160 inotify_fd = inotify_init();
161 if (inotify_fd < 0)
162 {
163 PERROR("inotify_init");
164 }
165
166 IPACMDBG_H("Waiting for nofications in dir %s with mask: 0x%x\n", IPACM_DIR_NAME, mask);
167
168 wd = inotify_add_watch(inotify_fd,
169 IPACM_DIR_NAME,
170 mask);
171
172 while (1)
173 {
174 length = read(inotify_fd, buffer, INOTIFY_BUF_LEN);
175 if (length < 0)
176 {
177 IPACMERR("inotify read() error return length: %d and mask: 0x%x\n", length, mask);
178 continue;
179 }
180
181 struct inotify_event* event;
182 event = (struct inotify_event*)malloc(length);
183 if(event == NULL)
184 {
185 IPACMERR("Failed to allocate memory.\n");
186 return NULL;
187 }
188 memset(event, 0, length);
189 memcpy(event, buffer, length);
190
191 if (event->len > 0)
192 {
193 if ( (event->mask & IN_MODIFY) || (event->mask & IN_MOVE))
194 {
195 if (event->mask & IN_ISDIR)
196 {
197 IPACMDBG_H("The directory %s was 0x%x\n", event->name, event->mask);
198 }
199 else if (!strncmp(event->name, IPACM_FIREWALL_FILE_NAME, event->len)) // firewall_rule change
200 {
201 IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask);
202 IPACMDBG_H("The interested file %s .\n", IPACM_FIREWALL_FILE_NAME);
203
204 evt_data.event = IPA_FIREWALL_CHANGE_EVENT;
205 evt_data.evt_data = NULL;
206
207 /* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */
208 IPACM_EvtDispatcher::PostEvt(&evt_data);
209 }
210 else if (!strncmp(event->name, IPACM_CFG_FILE_NAME, event->len)) // IPACM_configuration change
211 {
212 IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask);
213 IPACMDBG_H("The interested file %s .\n", IPACM_CFG_FILE_NAME);
214
215 evt_data.event = IPA_CFG_CHANGE_EVENT;
216 evt_data.evt_data = NULL;
217
218 /* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */
219 IPACM_EvtDispatcher::PostEvt(&evt_data);
220 }
221 }
222 IPACMDBG_H("Received monitoring event %s.\n", event->name);
223 }
224 free(event);
225 }
226
227 (void)inotify_rm_watch(inotify_fd, wd);
228 (void)close(inotify_fd);
229 return NULL;
230 }
231
232
233 /* start IPACM wan-driver notifier */
ipa_driver_msg_notifier(void * param)234 void* ipa_driver_msg_notifier(void *param)
235 {
236 int length, fd, cnt;
237 char buffer[IPA_DRIVER_WLAN_BUF_LEN];
238 struct ipa_msg_meta event_hdr;
239 struct ipa_ecm_msg event_ecm;
240 struct ipa_wan_msg event_wan;
241 struct ipa_wlan_msg_ex event_ex_o;
242 struct ipa_wlan_msg *event_wlan = NULL;
243 struct ipa_wlan_msg_ex *event_ex = NULL;
244 #ifdef WIGIG_CLIENT_CONNECT
245 struct ipa_wigig_msg *event_wigig = NULL;
246 #endif
247 struct ipa_get_data_stats_resp_msg_v01 event_data_stats;
248 struct ipa_get_apn_data_stats_resp_msg_v01 event_network_stats;
249 #ifdef IPA_RT_SUPPORT_COAL
250 struct ipa_coalesce_info coalesce_info;
251 #endif
252
253 #ifdef FEATURE_IPACM_HAL
254 IPACM_OffloadManager* OffloadMng;
255 #endif
256
257 ipacm_cmd_q_data evt_data;
258 ipacm_event_data_mac *data = NULL;
259 #ifdef WIGIG_CLIENT_CONNECT
260 ipacm_event_data_mac_ep *data_wigig = NULL;
261 #endif
262 ipacm_event_data_fid *data_fid = NULL;
263 ipacm_event_data_iptype *data_iptype = NULL;
264 ipacm_event_data_wlan_ex *data_ex;
265 ipa_get_data_stats_resp_msg_v01 *data_tethering_stats = NULL;
266 ipa_get_apn_data_stats_resp_msg_v01 *data_network_stats = NULL;
267 #ifdef FEATURE_L2TP
268 ipa_ioc_vlan_iface_info *vlan_info = NULL;
269 ipa_ioc_l2tp_vlan_mapping_info *mapping = NULL;
270 #endif
271 ipacm_cmd_q_data new_neigh_evt;
272 ipacm_event_data_all* new_neigh_data;
273
274 param = NULL;
275 fd = open(IPA_DRIVER, O_RDWR);
276 if (fd < 0)
277 {
278 IPACMERR("Failed opening %s.\n", IPA_DRIVER);
279 return NULL;
280 }
281
282 while (1)
283 {
284 IPACMDBG_H("Waiting for nofications from IPA driver \n");
285 memset(buffer, 0, sizeof(buffer));
286 memset(&evt_data, 0, sizeof(evt_data));
287 memset(&new_neigh_evt, 0, sizeof(ipacm_cmd_q_data));
288 new_neigh_data = NULL;
289 data = NULL;
290 data_fid = NULL;
291 data_tethering_stats = NULL;
292 data_network_stats = NULL;
293
294 length = read(fd, buffer, IPA_DRIVER_WLAN_BUF_LEN);
295 if (length < 0)
296 {
297 PERROR("didn't read IPA_driver correctly");
298 continue;
299 }
300
301 memcpy(&event_hdr, buffer,sizeof(struct ipa_msg_meta));
302 IPACMDBG_H("Message type: %d\n", event_hdr.msg_type);
303 IPACMDBG_H("Event header length received: %d\n",event_hdr.msg_len);
304
305 /* Insert WLAN_DRIVER_EVENT to command queue */
306 switch (event_hdr.msg_type)
307 {
308
309 case SW_ROUTING_ENABLE:
310 IPACMDBG_H("Received SW_ROUTING_ENABLE\n");
311 evt_data.event = IPA_SW_ROUTING_ENABLE;
312 IPACMDBG_H("Not supported anymore\n");
313 continue;
314
315 case SW_ROUTING_DISABLE:
316 IPACMDBG_H("Received SW_ROUTING_DISABLE\n");
317 evt_data.event = IPA_SW_ROUTING_DISABLE;
318 IPACMDBG_H("Not supported anymore\n");
319 continue;
320
321 case WLAN_AP_CONNECT:
322 event_wlan = (struct ipa_wlan_msg *) (buffer + sizeof(struct ipa_msg_meta));
323 IPACMDBG_H("Received WLAN_AP_CONNECT name: %s\n",event_wlan->name);
324 IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
325 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
326 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
327 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
328 if(data_fid == NULL)
329 {
330 IPACMERR("unable to allocate memory for event_wlan data_fid\n");
331 return NULL;
332 }
333 ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
334 evt_data.event = IPA_WLAN_AP_LINK_UP_EVENT;
335 evt_data.evt_data = data_fid;
336 break;
337
338 case WLAN_AP_DISCONNECT:
339 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
340 IPACMDBG_H("Received WLAN_AP_DISCONNECT name: %s\n",event_wlan->name);
341 IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
342 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
343 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
344 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
345 if(data_fid == NULL)
346 {
347 IPACMERR("unable to allocate memory for event_wlan data_fid\n");
348 return NULL;
349 }
350 ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
351 evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
352 evt_data.evt_data = data_fid;
353 break;
354 case WLAN_STA_CONNECT:
355 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
356 IPACMDBG_H("Received WLAN_STA_CONNECT name: %s\n",event_wlan->name);
357 IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
358 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
359 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
360 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
361 if(data == NULL)
362 {
363 IPACMERR("unable to allocate memory for event_wlan data_fid\n");
364 return NULL;
365 }
366 memcpy(data->mac_addr,
367 event_wlan->mac_addr,
368 sizeof(event_wlan->mac_addr));
369 ipa_get_if_index(event_wlan->name, &(data->if_index));
370 evt_data.event = IPA_WLAN_STA_LINK_UP_EVENT;
371 evt_data.evt_data = data;
372 break;
373
374 case WLAN_STA_DISCONNECT:
375 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
376 IPACMDBG_H("Received WLAN_STA_DISCONNECT name: %s\n",event_wlan->name);
377 IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
378 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
379 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
380 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
381 if(data_fid == NULL)
382 {
383 IPACMERR("unable to allocate memory for event_wlan data_fid\n");
384 return NULL;
385 }
386 ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
387 evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
388 evt_data.evt_data = data_fid;
389 break;
390
391 case WLAN_CLIENT_CONNECT:
392 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
393 IPACMDBG_H("Received WLAN_CLIENT_CONNECT\n");
394 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
395 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
396 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
397 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
398 if (data == NULL)
399 {
400 IPACMERR("unable to allocate memory for event_wlan data\n");
401 return NULL;
402 }
403 memcpy(data->mac_addr,
404 event_wlan->mac_addr,
405 sizeof(event_wlan->mac_addr));
406 ipa_get_if_index(event_wlan->name, &(data->if_index));
407 evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT;
408 evt_data.evt_data = data;
409 break;
410 #ifdef WIGIG_CLIENT_CONNECT
411 case WIGIG_CLIENT_CONNECT:
412 event_wigig = (struct ipa_wigig_msg *)(buffer + sizeof(struct ipa_msg_meta));
413 IPACMDBG_H("Received WIGIG_CLIENT_CONNECT\n");
414 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x, ep %d\n",
415 event_wigig->client_mac_addr[0], event_wigig->client_mac_addr[1], event_wigig->client_mac_addr[2],
416 event_wigig->client_mac_addr[3], event_wigig->client_mac_addr[4], event_wigig->client_mac_addr[5],
417 event_wigig->u.ipa_client);
418
419 data_wigig = (ipacm_event_data_mac_ep *)malloc(sizeof(ipacm_event_data_mac_ep));
420 if(data_wigig == NULL)
421 {
422 IPACMERR("unable to allocate memory for event_wigig data\n");
423 return NULL;
424 }
425 memcpy(data_wigig->mac_addr,
426 event_wigig->client_mac_addr,
427 sizeof(data_wigig->mac_addr));
428 ipa_get_if_index(event_wigig->name, &(data_wigig->if_index));
429 data_wigig->client = event_wigig->u.ipa_client;
430 evt_data.event = IPA_WIGIG_CLIENT_ADD_EVENT;
431 evt_data.evt_data = data_wigig;
432 break;
433 #endif
434 case WLAN_CLIENT_CONNECT_EX:
435 IPACMDBG_H("Received WLAN_CLIENT_CONNECT_EX\n");
436
437 memcpy(&event_ex_o, buffer + sizeof(struct ipa_msg_meta),sizeof(struct ipa_wlan_msg_ex));
438 if(event_ex_o.num_of_attribs > IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS)
439 {
440 IPACMERR("buffer size overflow\n");
441 return NULL;
442 }
443 length = sizeof(ipa_wlan_msg_ex)+ event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val);
444 IPACMDBG_H("num_of_attribs %d, length %d\n", event_ex_o.num_of_attribs, length);
445 event_ex = (ipa_wlan_msg_ex *)malloc(length);
446 if(event_ex == NULL )
447 {
448 IPACMERR("Unable to allocate memory\n");
449 return NULL;
450 }
451 memcpy(event_ex, buffer + sizeof(struct ipa_msg_meta), length);
452 data_ex = (ipacm_event_data_wlan_ex *)malloc(sizeof(ipacm_event_data_wlan_ex) + event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val));
453 if (data_ex == NULL)
454 {
455 IPACMERR("unable to allocate memory for event data\n");
456 return NULL;
457 }
458 data_ex->num_of_attribs = event_ex->num_of_attribs;
459
460 memcpy(data_ex->attribs,
461 event_ex->attribs,
462 event_ex->num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val));
463
464 ipa_get_if_index(event_ex->name, &(data_ex->if_index));
465 evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT_EX;
466 evt_data.evt_data = data_ex;
467
468 /* Construct new_neighbor msg with netdev device internally */
469 new_neigh_data = (ipacm_event_data_all*)malloc(sizeof(ipacm_event_data_all));
470 if(new_neigh_data == NULL)
471 {
472 IPACMERR("Failed to allocate memory.\n");
473 return NULL;
474 }
475 memset(new_neigh_data, 0, sizeof(ipacm_event_data_all));
476 new_neigh_data->iptype = IPA_IP_v6;
477 for(cnt = 0; cnt < event_ex->num_of_attribs; cnt++)
478 {
479 if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
480 {
481 memcpy(new_neigh_data->mac_addr, event_ex->attribs[cnt].u.mac_addr, sizeof(new_neigh_data->mac_addr));
482 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
483 event_ex->attribs[cnt].u.mac_addr[0], event_ex->attribs[cnt].u.mac_addr[1], event_ex->attribs[cnt].u.mac_addr[2],
484 event_ex->attribs[cnt].u.mac_addr[3], event_ex->attribs[cnt].u.mac_addr[4], event_ex->attribs[cnt].u.mac_addr[5]);
485 }
486 else if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
487 {
488 IPACMDBG_H("Wlan client id %d\n",event_ex->attribs[cnt].u.sta_id);
489 }
490 else
491 {
492 IPACMDBG_H("Wlan message has unexpected type!\n");
493 }
494 }
495 new_neigh_data->if_index = data_ex->if_index;
496 new_neigh_evt.evt_data = (void*)new_neigh_data;
497 new_neigh_evt.event = IPA_NEW_NEIGH_EVENT;
498 free(event_ex);
499 break;
500
501 case WLAN_CLIENT_DISCONNECT:
502 IPACMDBG_H("Received WLAN_CLIENT_DISCONNECT\n");
503 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
504 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
505 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
506 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
507 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
508 if (data == NULL)
509 {
510 IPACMERR("unable to allocate memory for event_wlan data\n");
511 return NULL;
512 }
513 memcpy(data->mac_addr,
514 event_wlan->mac_addr,
515 sizeof(event_wlan->mac_addr));
516 ipa_get_if_index(event_wlan->name, &(data->if_index));
517 evt_data.event = IPA_WLAN_CLIENT_DEL_EVENT;
518 evt_data.evt_data = data;
519 break;
520
521 case WLAN_CLIENT_POWER_SAVE_MODE:
522 IPACMDBG_H("Received WLAN_CLIENT_POWER_SAVE_MODE\n");
523 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
524 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
525 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
526 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
527 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
528 if (data == NULL)
529 {
530 IPACMERR("unable to allocate memory for event_wlan data\n");
531 return NULL;
532 }
533 memcpy(data->mac_addr,
534 event_wlan->mac_addr,
535 sizeof(event_wlan->mac_addr));
536 ipa_get_if_index(event_wlan->name, &(data->if_index));
537 evt_data.event = IPA_WLAN_CLIENT_POWER_SAVE_EVENT;
538 evt_data.evt_data = data;
539 break;
540
541 case WLAN_CLIENT_NORMAL_MODE:
542 IPACMDBG_H("Received WLAN_CLIENT_NORMAL_MODE\n");
543 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
544 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
545 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
546 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
547 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
548 if (data == NULL)
549 {
550 IPACMERR("unable to allocate memory for event_wlan data\n");
551 return NULL;
552 }
553 memcpy(data->mac_addr,
554 event_wlan->mac_addr,
555 sizeof(event_wlan->mac_addr));
556 ipa_get_if_index(event_wlan->name, &(data->if_index));
557 evt_data.evt_data = data;
558 evt_data.event = IPA_WLAN_CLIENT_RECOVER_EVENT;
559 break;
560
561 case ECM_CONNECT:
562 memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
563 IPACMDBG_H("Received ECM_CONNECT name: %s\n",event_ecm.name);
564 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
565 if(data_fid == NULL)
566 {
567 IPACMERR("unable to allocate memory for event_ecm data_fid\n");
568 return NULL;
569 }
570 data_fid->if_index = event_ecm.ifindex;
571 evt_data.event = IPA_USB_LINK_UP_EVENT;
572 evt_data.evt_data = data_fid;
573 break;
574
575 case ECM_DISCONNECT:
576 memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
577 IPACMDBG_H("Received ECM_DISCONNECT name: %s\n",event_ecm.name);
578 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
579 if(data_fid == NULL)
580 {
581 IPACMERR("unable to allocate memory for event_ecm data_fid\n");
582 return NULL;
583 }
584 data_fid->if_index = event_ecm.ifindex;
585 evt_data.event = IPA_LINK_DOWN_EVENT;
586 evt_data.evt_data = data_fid;
587 break;
588 /* Add for 8994 Android case */
589 case WAN_UPSTREAM_ROUTE_ADD:
590 memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
591 IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
592 data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
593 if(data_iptype == NULL)
594 {
595 IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
596 return NULL;
597 }
598 ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
599 ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
600 data_iptype->iptype = event_wan.ip;
601 #ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
602 data_iptype->ipv4_addr_gw = event_wan.ipv4_addr_gw;
603 data_iptype->ipv6_addr_gw[0] = event_wan.ipv6_addr_gw[0];
604 data_iptype->ipv6_addr_gw[1] = event_wan.ipv6_addr_gw[1];
605 data_iptype->ipv6_addr_gw[2] = event_wan.ipv6_addr_gw[2];
606 data_iptype->ipv6_addr_gw[3] = event_wan.ipv6_addr_gw[3];
607 IPACMDBG_H("default gw ipv4 (%x)\n", data_iptype->ipv4_addr_gw);
608 IPACMDBG_H("IPV6 gateway: %08x:%08x:%08x:%08x \n",
609 data_iptype->ipv6_addr_gw[0], data_iptype->ipv6_addr_gw[1], data_iptype->ipv6_addr_gw[2], data_iptype->ipv6_addr_gw[3]);
610 #endif
611 IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) tether_fid(%d) ip-type(%d)\n", data_iptype->if_index,
612 data_iptype->if_index_tether, data_iptype->iptype);
613 evt_data.event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
614 evt_data.evt_data = data_iptype;
615 break;
616 case WAN_UPSTREAM_ROUTE_DEL:
617 memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
618 IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
619 data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
620 if(data_iptype == NULL)
621 {
622 IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
623 return NULL;
624 }
625 ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
626 ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
627 data_iptype->iptype = event_wan.ip;
628 IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL: fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->iptype);
629 evt_data.event = IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT;
630 evt_data.evt_data = data_iptype;
631 break;
632 /* End of adding for 8994 Android case */
633
634 /* Add for embms case */
635 case WAN_EMBMS_CONNECT:
636 memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
637 IPACMDBG("Received WAN_EMBMS_CONNECT name: %s\n",event_wan.upstream_ifname);
638 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
639 if(data_fid == NULL)
640 {
641 IPACMERR("unable to allocate memory for event data_fid\n");
642 return NULL;
643 }
644 ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
645 evt_data.event = IPA_WAN_EMBMS_LINK_UP_EVENT;
646 evt_data.evt_data = data_fid;
647 break;
648
649 case WLAN_SWITCH_TO_SCC:
650 IPACMDBG_H("Received WLAN_SWITCH_TO_SCC\n");
651 [[fallthrough]];
652 case WLAN_WDI_ENABLE:
653 IPACMDBG_H("Received WLAN_WDI_ENABLE\n");
654 if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
655 {
656 IPACM_Iface::ipacmcfg->isMCC_Mode = false;
657 evt_data.event = IPA_WLAN_SWITCH_TO_SCC;
658 break;
659 }
660 continue;
661 case WLAN_SWITCH_TO_MCC:
662 IPACMDBG_H("Received WLAN_SWITCH_TO_MCC\n");
663 [[fallthrough]];
664 case WLAN_WDI_DISABLE:
665 IPACMDBG_H("Received WLAN_WDI_DISABLE\n");
666 if (IPACM_Iface::ipacmcfg->isMCC_Mode == false)
667 {
668 IPACM_Iface::ipacmcfg->isMCC_Mode = true;
669 evt_data.event = IPA_WLAN_SWITCH_TO_MCC;
670 break;
671 }
672 continue;
673
674 case WAN_XLAT_CONNECT:
675 memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta),
676 sizeof(struct ipa_wan_msg));
677 IPACMDBG_H("Received WAN_XLAT_CONNECT name: %s\n",
678 event_wan.upstream_ifname);
679
680 /* post IPA_LINK_UP_EVENT event
681 * may be WAN interface is not up
682 */
683 data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
684 if(data_fid == NULL)
685 {
686 IPACMERR("unable to allocate memory for xlat event\n");
687 return NULL;
688 }
689 ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
690 evt_data.event = IPA_LINK_UP_EVENT;
691 evt_data.evt_data = data_fid;
692 IPACMDBG_H("Posting IPA_LINK_UP_EVENT event:%d\n", evt_data.event);
693 IPACM_EvtDispatcher::PostEvt(&evt_data);
694
695 /* post IPA_WAN_XLAT_CONNECT_EVENT event */
696 memset(&evt_data, 0, sizeof(evt_data));
697 data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
698 if(data_fid == NULL)
699 {
700 IPACMERR("unable to allocate memory for xlat event\n");
701 return NULL;
702 }
703 ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
704 evt_data.event = IPA_WAN_XLAT_CONNECT_EVENT;
705 evt_data.evt_data = data_fid;
706 IPACMDBG_H("Posting IPA_WAN_XLAT_CONNECT_EVENT event:%d\n", evt_data.event);
707 break;
708
709 case IPA_TETHERING_STATS_UPDATE_STATS:
710 memcpy(&event_data_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_data_stats_resp_msg_v01));
711 data_tethering_stats = (ipa_get_data_stats_resp_msg_v01 *)malloc(sizeof(struct ipa_get_data_stats_resp_msg_v01));
712 if(data_tethering_stats == NULL)
713 {
714 IPACMERR("unable to allocate memory for event data_tethering_stats\n");
715 return NULL;
716 }
717 memcpy(data_tethering_stats,
718 &event_data_stats,
719 sizeof(struct ipa_get_data_stats_resp_msg_v01));
720 IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data_tethering_stats->ipa_stats_type);
721 IPACMDBG("Received %d UL, %d DL pipe stats\n",data_tethering_stats->ul_src_pipe_stats_list_len, data_tethering_stats->dl_dst_pipe_stats_list_len);
722 evt_data.event = IPA_TETHERING_STATS_UPDATE_EVENT;
723 evt_data.evt_data = data_tethering_stats;
724 break;
725
726 case IPA_TETHERING_STATS_UPDATE_NETWORK_STATS:
727 memcpy(&event_network_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
728 data_network_stats = (ipa_get_apn_data_stats_resp_msg_v01 *)malloc(sizeof(ipa_get_apn_data_stats_resp_msg_v01));
729 if(data_network_stats == NULL)
730 {
731 IPACMERR("unable to allocate memory for event data_network_stats\n");
732 return NULL;
733 }
734 memcpy(data_network_stats,
735 &event_network_stats,
736 sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
737 IPACMDBG("Received %d apn network stats \n", data_network_stats->apn_data_stats_list_len);
738 evt_data.event = IPA_NETWORK_STATS_UPDATE_EVENT;
739 evt_data.evt_data = data_network_stats;
740 break;
741
742 #ifdef FEATURE_IPACM_HAL
743 case IPA_QUOTA_REACH:
744 IPACMDBG_H("Received IPA_QUOTA_REACH\n");
745 OffloadMng = IPACM_OffloadManager::GetInstance();
746 if (OffloadMng->elrInstance == NULL) {
747 IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
748 } else {
749 IPACMERR("calling OffloadMng->elrInstance->onLimitReached \n");
750 OffloadMng->elrInstance->onLimitReached();
751 }
752 continue;
753 case IPA_SSR_BEFORE_SHUTDOWN:
754 IPACMDBG_H("Received IPA_SSR_BEFORE_SHUTDOWN\n");
755 IPACM_Wan::clearExtProp();
756 OffloadMng = IPACM_OffloadManager::GetInstance();
757 if (OffloadMng->elrInstance == NULL) {
758 IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
759 } else {
760 IPACMERR("calling OffloadMng->elrInstance->onOffloadStopped \n");
761 OffloadMng->elrInstance->onOffloadStopped(IpaEventRelay::ERROR);
762 }
763 /* WA to clean up wlan instances during SSR */
764 evt_data.event = IPA_SSR_NOTICE;
765 evt_data.evt_data = NULL;
766 break;
767 case IPA_SSR_AFTER_POWERUP:
768 IPACMDBG_H("Received IPA_SSR_AFTER_POWERUP\n");
769 OffloadMng = IPACM_OffloadManager::GetInstance();
770 if (OffloadMng->elrInstance == NULL) {
771 IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
772 } else {
773 IPACMERR("calling OffloadMng->elrInstance->onOffloadSupportAvailable \n");
774 OffloadMng->elrInstance->onOffloadSupportAvailable();
775 }
776 continue;
777 #ifdef IPA_WLAN_FW_SSR_EVENT_MAX
778 case WLAN_FWR_SSR_BEFORE_SHUTDOWN:
779 IPACMDBG_H("Received WLAN_FWR_SSR_BEFORE_SHUTDOWN\n");
780 evt_data.event = IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE;
781 evt_data.evt_data = NULL;
782 break;
783 #endif
784 #endif
785 #ifdef FEATURE_L2TP
786 case ADD_VLAN_IFACE:
787 vlan_info = (ipa_ioc_vlan_iface_info *)malloc(sizeof(*vlan_info));
788 if(vlan_info == NULL)
789 {
790 IPACMERR("Failed to allocate memory.\n");
791 return NULL;
792 }
793 memcpy(vlan_info, buffer + sizeof(struct ipa_msg_meta), sizeof(*vlan_info));
794 evt_data.event = IPA_ADD_VLAN_IFACE;
795 evt_data.evt_data = vlan_info;
796 break;
797
798 case DEL_VLAN_IFACE:
799 vlan_info = (ipa_ioc_vlan_iface_info *)malloc(sizeof(*vlan_info));
800 if(vlan_info == NULL)
801 {
802 IPACMERR("Failed to allocate memory.\n");
803 return NULL;
804 }
805 memcpy(vlan_info, buffer + sizeof(struct ipa_msg_meta), sizeof(*vlan_info));
806 evt_data.event = IPA_DEL_VLAN_IFACE;
807 evt_data.evt_data = vlan_info;
808 break;
809
810 case ADD_L2TP_VLAN_MAPPING:
811 mapping = (ipa_ioc_l2tp_vlan_mapping_info *)malloc(sizeof(*mapping));
812 if(mapping == NULL)
813 {
814 IPACMERR("Failed to allocate memory.\n");
815 return NULL;
816 }
817 memcpy(mapping, buffer + sizeof(struct ipa_msg_meta), sizeof(*mapping));
818 evt_data.event = IPA_ADD_L2TP_VLAN_MAPPING;
819 evt_data.evt_data = mapping;
820 break;
821
822 case DEL_L2TP_VLAN_MAPPING:
823 mapping = (ipa_ioc_l2tp_vlan_mapping_info *)malloc(sizeof(*mapping));
824 if(mapping == NULL)
825 {
826 IPACMERR("Failed to allocate memory.\n");
827 return NULL;
828 }
829 memcpy(mapping, buffer + sizeof(struct ipa_msg_meta), sizeof(*mapping));
830 evt_data.event = IPA_DEL_L2TP_VLAN_MAPPING;
831 evt_data.evt_data = mapping;
832 break;
833 #endif
834 #ifdef IPA_RT_SUPPORT_COAL
835 case IPA_COALESCE_ENABLE:
836 memcpy(&coalesce_info, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_coalesce_info));
837 IPACMDBG_H("Received IPA_COALESCE_ENABLE qmap-id:%d tcp:%d, udp%d\n",
838 coalesce_info.qmap_id, coalesce_info.tcp_enable, coalesce_info.udp_enable);
839 if (coalesce_info.qmap_id >=IPA_MAX_NUM_SW_PDNS)
840 {
841 IPACMERR("qmap_id (%d) beyond the Max range (%d), abort\n",
842 coalesce_info.qmap_id, IPA_MAX_NUM_SW_PDNS);
843 return NULL;
844 }
845 IPACM_Wan::coalesce_config(coalesce_info.qmap_id, coalesce_info.tcp_enable, coalesce_info.udp_enable);
846 /* Notify all LTE instance to do RSC configuration */
847 evt_data.event = IPA_COALESCE_NOTICE;
848 evt_data.evt_data = NULL;
849 break;
850
851 case IPA_COALESCE_DISABLE:
852 memcpy(&coalesce_info, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_coalesce_info));
853 IPACMDBG_H("Received IPA_COALESCE_DISABLE qmap-id:%d tcp:%d, udp%d\n",
854 coalesce_info.qmap_id, coalesce_info.tcp_enable, coalesce_info.udp_enable);
855 if (coalesce_info.qmap_id >=IPA_MAX_NUM_SW_PDNS)
856 {
857 IPACMERR("qmap_id (%d) beyond the Max range (%d), abort\n",
858 coalesce_info.qmap_id, IPA_MAX_NUM_SW_PDNS);
859 return NULL;
860 }
861 IPACM_Wan::coalesce_config(coalesce_info.qmap_id, false, false);
862 /* Notify all LTE instance to do RSC configuration */
863 evt_data.event = IPA_COALESCE_NOTICE;
864 evt_data.evt_data = NULL;
865 break;
866 #endif
867
868 default:
869 IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type);
870 continue;
871
872 }
873 /* finish command queue */
874 IPACMDBG_H("Posting event:%d\n", evt_data.event);
875 IPACM_EvtDispatcher::PostEvt(&evt_data);
876 /* push new_neighbor with netdev device internally */
877 if(new_neigh_data != NULL)
878 {
879 IPACMDBG_H("Internally post event IPA_NEW_NEIGH_EVENT\n");
880 IPACM_EvtDispatcher::PostEvt(&new_neigh_evt);
881 }
882 }
883
884 (void)close(fd);
885 return NULL;
886 }
887
IPACM_Sig_Handler(int sig)888 void IPACM_Sig_Handler(int sig)
889 {
890 ipacm_cmd_q_data evt_data;
891
892 printf("Received Signal: %d\n", sig);
893 memset(&evt_data, 0, sizeof(evt_data));
894
895 switch(sig)
896 {
897 case SIGUSR1:
898 IPACMDBG_H("Received SW_ROUTING_ENABLE request \n");
899 evt_data.event = IPA_SW_ROUTING_ENABLE;
900 IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = true;
901 break;
902
903 case SIGUSR2:
904 IPACMDBG_H("Received SW_ROUTING_DISABLE request \n");
905 evt_data.event = IPA_SW_ROUTING_DISABLE;
906 IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = false;
907 break;
908 }
909 /* finish command queue */
910 IPACMDBG_H("Posting event:%d\n", evt_data.event);
911 IPACM_EvtDispatcher::PostEvt(&evt_data);
912 return;
913 }
914
RegisterForSignals(void)915 void RegisterForSignals(void)
916 {
917
918 signal(SIGUSR1, IPACM_Sig_Handler);
919 signal(SIGUSR2, IPACM_Sig_Handler);
920 }
921
922
main(int argc,char ** argv)923 int main(int argc, char **argv)
924 {
925 int ret;
926 pthread_t netlink_thread = 0, monitor_thread = 0, ipa_driver_thread = 0;
927 pthread_t cmd_queue_thread = 0;
928
929 /* check if ipacm is already running or not */
930 ipa_is_ipacm_running();
931
932 IPACMDBG_H("In main()\n");
933 (void)argc;
934 (void)argv;
935
936 #ifdef FEATURE_IPACM_RESTART
937 IPACMDBG_H("RESET IPA-HW rules\n");
938 ipa_reset();
939 #endif
940
941 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
942 IPACMDBG_H("Configure IPA-HW index-counter\n");
943 ipa_reset_hw_index_counter();
944 #endif
945
946 neigh = new IPACM_Neighbor();
947 ifacemgr = new IPACM_IfaceManager();
948 #ifdef FEATURE_IPACM_HAL
949 OffloadMng = IPACM_OffloadManager::GetInstance();
950 hal = HAL::makeIPAHAL(1, OffloadMng);
951 IPACMDBG_H(" START IPACM_OffloadManager and link to android framework\n");
952 #endif
953
954 if (IPACM_Iface::ipacmcfg->isEthBridgingSupported())
955 {
956 IPACM_LanToLan* lan2lan = IPACM_LanToLan::get_instance();
957 IPACMDBG_H("Staring IPACM_LanToLan instance %p\n", lan2lan);
958 }
959 CtList = new IPACM_ConntrackListener();
960
961 IPACMDBG_H("Staring IPA main\n");
962 IPACMDBG_H("ipa_cmdq_successful\n");
963
964 /* reset coalesce settings */
965 IPACM_Wan::coalesce_config_reset();
966
967 RegisterForSignals();
968
969 if (IPACM_SUCCESS == cmd_queue_thread)
970 {
971 ret = pthread_create(&cmd_queue_thread, NULL, MessageQueue::Process, NULL);
972 if (IPACM_SUCCESS != ret)
973 {
974 IPACMERR("unable to command queue thread\n");
975 return ret;
976 }
977 IPACMDBG_H("created command queue thread\n");
978 if(pthread_setname_np(cmd_queue_thread, "cmd queue process") != 0)
979 {
980 IPACMERR("unable to set thread name\n");
981 }
982 }
983
984 if (IPACM_SUCCESS == netlink_thread)
985 {
986 ret = pthread_create(&netlink_thread, NULL, netlink_start, NULL);
987 if (IPACM_SUCCESS != ret)
988 {
989 IPACMERR("unable to create netlink thread\n");
990 return ret;
991 }
992 IPACMDBG_H("created netlink thread\n");
993 if(pthread_setname_np(netlink_thread, "netlink socket") != 0)
994 {
995 IPACMERR("unable to set thread name\n");
996 }
997 }
998
999 /* Enable Firewall support only on MDM targets */
1000 #ifndef FEATURE_IPA_ANDROID
1001 if (IPACM_SUCCESS == monitor_thread)
1002 {
1003 ret = pthread_create(&monitor_thread, NULL, firewall_monitor, NULL);
1004 if (IPACM_SUCCESS != ret)
1005 {
1006 IPACMERR("unable to create monitor thread\n");
1007 return ret;
1008 }
1009 IPACMDBG_H("created firewall monitor thread\n");
1010 if(pthread_setname_np(monitor_thread, "firewall cfg process") != 0)
1011 {
1012 IPACMERR("unable to set thread name\n");
1013 }
1014 }
1015 #endif
1016
1017 if (IPACM_SUCCESS == ipa_driver_thread)
1018 {
1019 ret = pthread_create(&ipa_driver_thread, NULL, ipa_driver_msg_notifier, NULL);
1020 if (IPACM_SUCCESS != ret)
1021 {
1022 IPACMERR("unable to create ipa_driver_wlan thread\n");
1023 return ret;
1024 }
1025 IPACMDBG_H("created ipa_driver_wlan thread\n");
1026 if(pthread_setname_np(ipa_driver_thread, "ipa driver ntfy") != 0)
1027 {
1028 IPACMERR("unable to set thread name\n");
1029 }
1030 }
1031
1032 pthread_join(cmd_queue_thread, NULL);
1033 pthread_join(netlink_thread, NULL);
1034 pthread_join(monitor_thread, NULL);
1035 pthread_join(ipa_driver_thread, NULL);
1036 return IPACM_SUCCESS;
1037 }
1038
1039 /*===========================================================================
1040 FUNCTION ipa_is_ipacm_running
1041 ===========================================================================*/
1042 /*!
1043 @brief
1044 Determine whether there's already an IPACM process running, if so, terminate
1045 the current one
1046
1047 @return
1048 None
1049
1050 @note
1051
1052 - Dependencies
1053 - None
1054
1055 - Side Effects
1056 - None
1057 */
1058 /*=========================================================================*/
1059
ipa_is_ipacm_running(void)1060 void ipa_is_ipacm_running(void) {
1061
1062 int fd;
1063 struct flock lock;
1064 int retval;
1065
1066 fd = open(IPACM_PID_FILE, O_RDWR | O_CREAT, 0600);
1067 if ( fd <= 0 )
1068 {
1069 IPACMERR("Failed to open %s, error is %d - %s\n",
1070 IPACM_PID_FILE, errno, strerror(errno));
1071 exit(0);
1072 }
1073
1074 /*
1075 * Getting an exclusive Write lock on the file, if it fails,
1076 * it means that another instance of IPACM is running and it
1077 * got the lock before us.
1078 */
1079 memset(&lock, 0, sizeof(lock));
1080 lock.l_type = F_WRLCK;
1081 retval = fcntl(fd, F_SETLK, &lock);
1082
1083 if (retval != 0)
1084 {
1085 retval = fcntl(fd, F_GETLK, &lock);
1086 if (retval == 0)
1087 {
1088 IPACMERR("Unable to get lock on file %s (my PID %d), PID %d already has it\n",
1089 IPACM_PID_FILE, getpid(), lock.l_pid);
1090 close(fd);
1091 exit(0);
1092 }
1093 }
1094 else
1095 {
1096 IPACMERR("PID %d is IPACM main process\n", getpid());
1097 }
1098
1099 return;
1100 }
1101
1102 /*===========================================================================
1103 FUNCTION ipa_get_if_index
1104 ===========================================================================*/
1105 /*!
1106 @brief
1107 get ipa interface index by given the interface name
1108
1109 @return
1110 IPACM_SUCCESS or IPA_FALUIRE
1111
1112 @note
1113
1114 - Dependencies
1115 - None
1116
1117 - Side Effects
1118 - None
1119 */
1120 /*=========================================================================*/
ipa_get_if_index(char * if_name,int * if_index)1121 int ipa_get_if_index
1122 (
1123 char *if_name,
1124 int *if_index
1125 )
1126 {
1127 int fd;
1128 struct ifreq ifr;
1129
1130 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1131 {
1132 PERROR("get interface index socket create failed");
1133 return IPACM_FAILURE;
1134 }
1135
1136 memset(&ifr, 0, sizeof(struct ifreq));
1137
1138 (void)strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
1139
1140 if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
1141 {
1142 IPACMERR("call_ioctl_on_dev: ioctl failed: can't find device %s",if_name);
1143 *if_index = -1;
1144 close(fd);
1145 return IPACM_FAILURE;
1146 }
1147
1148 *if_index = ifr.ifr_ifindex;
1149 close(fd);
1150 return IPACM_SUCCESS;
1151 }
1152
1153 #ifdef FEATURE_IPACM_RESTART
ipa_reset()1154 int ipa_reset()
1155 {
1156 int fd = -1;
1157
1158 if ((fd = open(IPA_DEVICE_NAME, O_RDWR)) < 0) {
1159 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
1160 return IPACM_FAILURE;
1161 }
1162
1163 if (ioctl(fd, IPA_IOC_CLEANUP) < 0) {
1164 IPACMERR("IOCTL IPA_IOC_CLEANUP call failed: %s \n", strerror(errno));
1165 close(fd);
1166 return IPACM_FAILURE;
1167 }
1168
1169 IPACMDBG_H("send IPA_IOC_CLEANUP \n");
1170 close(fd);
1171 return IPACM_SUCCESS;
1172 }
1173 #endif
1174
1175 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
ipa_reset_hw_index_counter()1176 int ipa_reset_hw_index_counter()
1177 {
1178 int fd = -1;
1179 struct ipa_ioc_flt_rt_counter_alloc fnr_counters;
1180 struct ipa_ioc_fnr_index_info fnr_info;
1181
1182 if ((fd = open(IPA_DEVICE_NAME, O_RDWR)) < 0) {
1183 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
1184 return IPACM_FAILURE;
1185 }
1186
1187 memset(&fnr_counters, 0, sizeof(fnr_counters));
1188 fnr_counters.hw_counter.num_counters = 4;
1189 fnr_counters.hw_counter.allow_less = false;
1190 fnr_counters.sw_counter.num_counters = 4;
1191 fnr_counters.sw_counter.allow_less = false;
1192 IPACMDBG_H("Allocating %d hw counters and %d sw counters\n",
1193 fnr_counters.hw_counter.num_counters, fnr_counters.sw_counter.num_counters);
1194
1195 if (ioctl(fd, IPA_IOC_FNR_COUNTER_ALLOC, &fnr_counters) < 0) {
1196 IPACMERR("IPA_IOC_FNR_COUNTER_ALLOC call failed: %s \n", strerror(errno));
1197 close(fd);
1198 return IPACM_FAILURE;
1199 }
1200
1201 IPACMDBG_H("hw-counter start offset %d, sw-counter start offset %d\n",
1202 fnr_counters.hw_counter.start_id, fnr_counters.sw_counter.start_id);
1203 IPACM_Iface::ipacmcfg->hw_fnr_stats_support = true;
1204 IPACM_Iface::ipacmcfg->hw_counter_offset = fnr_counters.hw_counter.start_id;
1205 IPACM_Iface::ipacmcfg->sw_counter_offset = fnr_counters.sw_counter.start_id;
1206
1207 /* set FNR counter info */
1208 memset(&fnr_info, 0, sizeof(fnr_info));
1209 fnr_info.hw_counter_offset = fnr_counters.hw_counter.start_id;
1210 fnr_info.sw_counter_offset = fnr_counters.sw_counter.start_id;
1211
1212 if (ioctl(fd, IPA_IOC_SET_FNR_COUNTER_INFO, &fnr_info) < 0) {
1213 IPACMERR("IPA_IOC_SET_FNR_COUNTER_INFO call failed: %s \n", strerror(errno));
1214 close(fd);
1215 return IPACM_FAILURE;
1216 }
1217
1218 close(fd);
1219 return IPACM_SUCCESS;
1220 }
1221 #endif
1222