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 ::android::sp<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 #ifdef IPA_MTU_EVENT_MAX
274 ipacm_event_mtu_info *mtu_event = NULL;
275 ipa_mtu_info *mtu_info;
276 #endif
277
278 param = NULL;
279 fd = open(IPA_DRIVER, O_RDWR);
280 if (fd < 0)
281 {
282 IPACMERR("Failed opening %s.\n", IPA_DRIVER);
283 return NULL;
284 }
285
286 while (1)
287 {
288 IPACMDBG_H("Waiting for nofications from IPA driver \n");
289 memset(buffer, 0, sizeof(buffer));
290 memset(&evt_data, 0, sizeof(evt_data));
291 memset(&new_neigh_evt, 0, sizeof(ipacm_cmd_q_data));
292 new_neigh_data = NULL;
293 data = NULL;
294 data_fid = NULL;
295 data_tethering_stats = NULL;
296 data_network_stats = NULL;
297
298 length = read(fd, buffer, IPA_DRIVER_WLAN_BUF_LEN);
299 if (length < 0)
300 {
301 PERROR("didn't read IPA_driver correctly");
302 continue;
303 }
304
305 memcpy(&event_hdr, buffer,sizeof(struct ipa_msg_meta));
306 IPACMDBG_H("Message type: %d\n", event_hdr.msg_type);
307 IPACMDBG_H("Event header length received: %d\n",event_hdr.msg_len);
308
309 /* Insert WLAN_DRIVER_EVENT to command queue */
310 switch (event_hdr.msg_type)
311 {
312
313 case SW_ROUTING_ENABLE:
314 IPACMDBG_H("Received SW_ROUTING_ENABLE\n");
315 evt_data.event = IPA_SW_ROUTING_ENABLE;
316 IPACMDBG_H("Not supported anymore\n");
317 continue;
318
319 case SW_ROUTING_DISABLE:
320 IPACMDBG_H("Received SW_ROUTING_DISABLE\n");
321 evt_data.event = IPA_SW_ROUTING_DISABLE;
322 IPACMDBG_H("Not supported anymore\n");
323 continue;
324
325 case WLAN_AP_CONNECT:
326 event_wlan = (struct ipa_wlan_msg *) (buffer + sizeof(struct ipa_msg_meta));
327 IPACMDBG_H("Received WLAN_AP_CONNECT name: %s\n",event_wlan->name);
328 IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
329 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
330 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
331 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
332 if(data_fid == NULL)
333 {
334 IPACMERR("unable to allocate memory for event_wlan data_fid\n");
335 return NULL;
336 }
337 ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
338 evt_data.event = IPA_WLAN_AP_LINK_UP_EVENT;
339 evt_data.evt_data = data_fid;
340 break;
341
342 case WLAN_AP_DISCONNECT:
343 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
344 IPACMDBG_H("Received WLAN_AP_DISCONNECT name: %s\n",event_wlan->name);
345 IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
346 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
347 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
348 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
349 if(data_fid == NULL)
350 {
351 IPACMERR("unable to allocate memory for event_wlan data_fid\n");
352 return NULL;
353 }
354 ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
355 evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
356 evt_data.evt_data = data_fid;
357 break;
358 case WLAN_STA_CONNECT:
359 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
360 IPACMDBG_H("Received WLAN_STA_CONNECT name: %s\n",event_wlan->name);
361 IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
362 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
363 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
364 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
365 if(data == NULL)
366 {
367 IPACMERR("unable to allocate memory for event_wlan data_fid\n");
368 return NULL;
369 }
370 memcpy(data->mac_addr,
371 event_wlan->mac_addr,
372 sizeof(event_wlan->mac_addr));
373 ipa_get_if_index(event_wlan->name, &(data->if_index));
374 evt_data.event = IPA_WLAN_STA_LINK_UP_EVENT;
375 evt_data.evt_data = data;
376 break;
377
378 case WLAN_STA_DISCONNECT:
379 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
380 IPACMDBG_H("Received WLAN_STA_DISCONNECT name: %s\n",event_wlan->name);
381 IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
382 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
383 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
384 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
385 if(data_fid == NULL)
386 {
387 IPACMERR("unable to allocate memory for event_wlan data_fid\n");
388 return NULL;
389 }
390 ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
391 evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
392 evt_data.evt_data = data_fid;
393 break;
394
395 case WLAN_CLIENT_CONNECT:
396 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
397 IPACMDBG_H("Received WLAN_CLIENT_CONNECT\n");
398 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
399 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
400 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
401 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
402 if (data == NULL)
403 {
404 IPACMERR("unable to allocate memory for event_wlan data\n");
405 return NULL;
406 }
407 memcpy(data->mac_addr,
408 event_wlan->mac_addr,
409 sizeof(event_wlan->mac_addr));
410 ipa_get_if_index(event_wlan->name, &(data->if_index));
411 evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT;
412 evt_data.evt_data = data;
413 break;
414 #ifdef WIGIG_CLIENT_CONNECT
415 case WIGIG_CLIENT_CONNECT:
416 event_wigig = (struct ipa_wigig_msg *)(buffer + sizeof(struct ipa_msg_meta));
417 IPACMDBG_H("Received WIGIG_CLIENT_CONNECT\n");
418 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x, ep %d\n",
419 event_wigig->client_mac_addr[0], event_wigig->client_mac_addr[1], event_wigig->client_mac_addr[2],
420 event_wigig->client_mac_addr[3], event_wigig->client_mac_addr[4], event_wigig->client_mac_addr[5],
421 event_wigig->u.ipa_client);
422
423 data_wigig = (ipacm_event_data_mac_ep *)malloc(sizeof(ipacm_event_data_mac_ep));
424 if(data_wigig == NULL)
425 {
426 IPACMERR("unable to allocate memory for event_wigig data\n");
427 return NULL;
428 }
429 memcpy(data_wigig->mac_addr,
430 event_wigig->client_mac_addr,
431 sizeof(data_wigig->mac_addr));
432 ipa_get_if_index(event_wigig->name, &(data_wigig->if_index));
433 data_wigig->client = event_wigig->u.ipa_client;
434 evt_data.event = IPA_WIGIG_CLIENT_ADD_EVENT;
435 evt_data.evt_data = data_wigig;
436 break;
437 #endif
438 case WLAN_CLIENT_CONNECT_EX:
439 IPACMDBG_H("Received WLAN_CLIENT_CONNECT_EX\n");
440
441 memcpy(&event_ex_o, buffer + sizeof(struct ipa_msg_meta),sizeof(struct ipa_wlan_msg_ex));
442 if(event_ex_o.num_of_attribs > IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS)
443 {
444 IPACMERR("buffer size overflow\n");
445 return NULL;
446 }
447 length = sizeof(ipa_wlan_msg_ex)+ event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val);
448 IPACMDBG_H("num_of_attribs %d, length %d\n", event_ex_o.num_of_attribs, length);
449 event_ex = (ipa_wlan_msg_ex *)malloc(length);
450 if(event_ex == NULL )
451 {
452 IPACMERR("Unable to allocate memory\n");
453 return NULL;
454 }
455 memcpy(event_ex, buffer + sizeof(struct ipa_msg_meta), length);
456 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));
457 if (data_ex == NULL)
458 {
459 IPACMERR("unable to allocate memory for event data\n");
460 return NULL;
461 }
462 data_ex->num_of_attribs = event_ex->num_of_attribs;
463
464 memcpy(data_ex->attribs,
465 event_ex->attribs,
466 event_ex->num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val));
467
468 ipa_get_if_index(event_ex->name, &(data_ex->if_index));
469 evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT_EX;
470 evt_data.evt_data = data_ex;
471
472 /* Construct new_neighbor msg with netdev device internally */
473 new_neigh_data = (ipacm_event_data_all*)malloc(sizeof(ipacm_event_data_all));
474 if(new_neigh_data == NULL)
475 {
476 IPACMERR("Failed to allocate memory.\n");
477 return NULL;
478 }
479 memset(new_neigh_data, 0, sizeof(ipacm_event_data_all));
480 new_neigh_data->iptype = IPA_IP_v6;
481 for(cnt = 0; cnt < event_ex->num_of_attribs; cnt++)
482 {
483 if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
484 {
485 memcpy(new_neigh_data->mac_addr, event_ex->attribs[cnt].u.mac_addr, sizeof(new_neigh_data->mac_addr));
486 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
487 event_ex->attribs[cnt].u.mac_addr[0], event_ex->attribs[cnt].u.mac_addr[1], event_ex->attribs[cnt].u.mac_addr[2],
488 event_ex->attribs[cnt].u.mac_addr[3], event_ex->attribs[cnt].u.mac_addr[4], event_ex->attribs[cnt].u.mac_addr[5]);
489 }
490 else if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
491 {
492 IPACMDBG_H("Wlan client id %d\n",event_ex->attribs[cnt].u.sta_id);
493 }
494 else
495 {
496 IPACMDBG_H("Wlan message has unexpected type!\n");
497 }
498 }
499 new_neigh_data->if_index = data_ex->if_index;
500 new_neigh_evt.evt_data = (void*)new_neigh_data;
501 new_neigh_evt.event = IPA_NEW_NEIGH_EVENT;
502 free(event_ex);
503 break;
504
505 case WLAN_CLIENT_DISCONNECT:
506 IPACMDBG_H("Received WLAN_CLIENT_DISCONNECT\n");
507 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
508 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
509 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
510 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
511 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
512 if (data == NULL)
513 {
514 IPACMERR("unable to allocate memory for event_wlan data\n");
515 return NULL;
516 }
517 memcpy(data->mac_addr,
518 event_wlan->mac_addr,
519 sizeof(event_wlan->mac_addr));
520 ipa_get_if_index(event_wlan->name, &(data->if_index));
521 evt_data.event = IPA_WLAN_CLIENT_DEL_EVENT;
522 evt_data.evt_data = data;
523 break;
524
525 case WLAN_CLIENT_POWER_SAVE_MODE:
526 IPACMDBG_H("Received WLAN_CLIENT_POWER_SAVE_MODE\n");
527 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
528 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
529 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
530 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
531 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
532 if (data == NULL)
533 {
534 IPACMERR("unable to allocate memory for event_wlan data\n");
535 return NULL;
536 }
537 memcpy(data->mac_addr,
538 event_wlan->mac_addr,
539 sizeof(event_wlan->mac_addr));
540 ipa_get_if_index(event_wlan->name, &(data->if_index));
541 evt_data.event = IPA_WLAN_CLIENT_POWER_SAVE_EVENT;
542 evt_data.evt_data = data;
543 break;
544
545 case WLAN_CLIENT_NORMAL_MODE:
546 IPACMDBG_H("Received WLAN_CLIENT_NORMAL_MODE\n");
547 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
548 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
549 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
550 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
551 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
552 if (data == NULL)
553 {
554 IPACMERR("unable to allocate memory for event_wlan data\n");
555 return NULL;
556 }
557 memcpy(data->mac_addr,
558 event_wlan->mac_addr,
559 sizeof(event_wlan->mac_addr));
560 ipa_get_if_index(event_wlan->name, &(data->if_index));
561 evt_data.evt_data = data;
562 evt_data.event = IPA_WLAN_CLIENT_RECOVER_EVENT;
563 break;
564
565 case ECM_CONNECT:
566 memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
567 IPACMDBG_H("Received ECM_CONNECT name: %s\n",event_ecm.name);
568 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
569 if(data_fid == NULL)
570 {
571 IPACMERR("unable to allocate memory for event_ecm data_fid\n");
572 return NULL;
573 }
574 data_fid->if_index = event_ecm.ifindex;
575 evt_data.event = IPA_USB_LINK_UP_EVENT;
576 evt_data.evt_data = data_fid;
577 break;
578
579 case ECM_DISCONNECT:
580 memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
581 IPACMDBG_H("Received ECM_DISCONNECT name: %s\n",event_ecm.name);
582 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
583 if(data_fid == NULL)
584 {
585 IPACMERR("unable to allocate memory for event_ecm data_fid\n");
586 return NULL;
587 }
588 data_fid->if_index = event_ecm.ifindex;
589 evt_data.event = IPA_LINK_DOWN_EVENT;
590 evt_data.evt_data = data_fid;
591 break;
592 /* Add for 8994 Android case */
593 case WAN_UPSTREAM_ROUTE_ADD:
594 memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
595 IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
596 data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
597 if(data_iptype == NULL)
598 {
599 IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
600 return NULL;
601 }
602 ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
603 ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
604 data_iptype->iptype = event_wan.ip;
605 #ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
606 data_iptype->ipv4_addr_gw = event_wan.ipv4_addr_gw;
607 data_iptype->ipv6_addr_gw[0] = event_wan.ipv6_addr_gw[0];
608 data_iptype->ipv6_addr_gw[1] = event_wan.ipv6_addr_gw[1];
609 data_iptype->ipv6_addr_gw[2] = event_wan.ipv6_addr_gw[2];
610 data_iptype->ipv6_addr_gw[3] = event_wan.ipv6_addr_gw[3];
611 IPACMDBG_H("default gw ipv4 (%x)\n", data_iptype->ipv4_addr_gw);
612 IPACMDBG_H("IPV6 gateway: %08x:%08x:%08x:%08x \n",
613 data_iptype->ipv6_addr_gw[0], data_iptype->ipv6_addr_gw[1], data_iptype->ipv6_addr_gw[2], data_iptype->ipv6_addr_gw[3]);
614 #endif
615 IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) tether_fid(%d) ip-type(%d)\n", data_iptype->if_index,
616 data_iptype->if_index_tether, data_iptype->iptype);
617 evt_data.event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
618 evt_data.evt_data = data_iptype;
619 break;
620 case WAN_UPSTREAM_ROUTE_DEL:
621 memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
622 IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
623 data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
624 if(data_iptype == NULL)
625 {
626 IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
627 return NULL;
628 }
629 ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
630 ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
631 data_iptype->iptype = event_wan.ip;
632 IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL: fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->iptype);
633 evt_data.event = IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT;
634 evt_data.evt_data = data_iptype;
635 break;
636 /* End of adding for 8994 Android case */
637
638 /* Add for embms case */
639 case WAN_EMBMS_CONNECT:
640 memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
641 IPACMDBG("Received WAN_EMBMS_CONNECT name: %s\n",event_wan.upstream_ifname);
642 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
643 if(data_fid == NULL)
644 {
645 IPACMERR("unable to allocate memory for event data_fid\n");
646 return NULL;
647 }
648 ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
649 evt_data.event = IPA_WAN_EMBMS_LINK_UP_EVENT;
650 evt_data.evt_data = data_fid;
651 break;
652
653 case WLAN_SWITCH_TO_SCC:
654 IPACMDBG_H("Received WLAN_SWITCH_TO_SCC\n");
655 [[fallthrough]];
656 case WLAN_WDI_ENABLE:
657 IPACMDBG_H("Received WLAN_WDI_ENABLE\n");
658 if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
659 {
660 IPACM_Iface::ipacmcfg->isMCC_Mode = false;
661 evt_data.event = IPA_WLAN_SWITCH_TO_SCC;
662 break;
663 }
664 continue;
665 case WLAN_SWITCH_TO_MCC:
666 IPACMDBG_H("Received WLAN_SWITCH_TO_MCC\n");
667 [[fallthrough]];
668 case WLAN_WDI_DISABLE:
669 IPACMDBG_H("Received WLAN_WDI_DISABLE\n");
670 if (IPACM_Iface::ipacmcfg->isMCC_Mode == false)
671 {
672 IPACM_Iface::ipacmcfg->isMCC_Mode = true;
673 evt_data.event = IPA_WLAN_SWITCH_TO_MCC;
674 break;
675 }
676 continue;
677
678 case WAN_XLAT_CONNECT:
679 memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta),
680 sizeof(struct ipa_wan_msg));
681 IPACMDBG_H("Received WAN_XLAT_CONNECT name: %s\n",
682 event_wan.upstream_ifname);
683
684 /* post IPA_LINK_UP_EVENT event
685 * may be WAN interface is not up
686 */
687 data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
688 if(data_fid == NULL)
689 {
690 IPACMERR("unable to allocate memory for xlat event\n");
691 return NULL;
692 }
693 ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
694 evt_data.event = IPA_LINK_UP_EVENT;
695 evt_data.evt_data = data_fid;
696 IPACMDBG_H("Posting IPA_LINK_UP_EVENT event:%d\n", evt_data.event);
697 IPACM_EvtDispatcher::PostEvt(&evt_data);
698
699 /* post IPA_WAN_XLAT_CONNECT_EVENT event */
700 memset(&evt_data, 0, sizeof(evt_data));
701 data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
702 if(data_fid == NULL)
703 {
704 IPACMERR("unable to allocate memory for xlat event\n");
705 return NULL;
706 }
707 ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
708 evt_data.event = IPA_WAN_XLAT_CONNECT_EVENT;
709 evt_data.evt_data = data_fid;
710 IPACMDBG_H("Posting IPA_WAN_XLAT_CONNECT_EVENT event:%d\n", evt_data.event);
711 break;
712
713 case IPA_TETHERING_STATS_UPDATE_STATS:
714 memcpy(&event_data_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_data_stats_resp_msg_v01));
715 data_tethering_stats = (ipa_get_data_stats_resp_msg_v01 *)malloc(sizeof(struct ipa_get_data_stats_resp_msg_v01));
716 if(data_tethering_stats == NULL)
717 {
718 IPACMERR("unable to allocate memory for event data_tethering_stats\n");
719 return NULL;
720 }
721 memcpy(data_tethering_stats,
722 &event_data_stats,
723 sizeof(struct ipa_get_data_stats_resp_msg_v01));
724 IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data_tethering_stats->ipa_stats_type);
725 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);
726 evt_data.event = IPA_TETHERING_STATS_UPDATE_EVENT;
727 evt_data.evt_data = data_tethering_stats;
728 break;
729
730 case IPA_TETHERING_STATS_UPDATE_NETWORK_STATS:
731 memcpy(&event_network_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
732 data_network_stats = (ipa_get_apn_data_stats_resp_msg_v01 *)malloc(sizeof(ipa_get_apn_data_stats_resp_msg_v01));
733 if(data_network_stats == NULL)
734 {
735 IPACMERR("unable to allocate memory for event data_network_stats\n");
736 return NULL;
737 }
738 memcpy(data_network_stats,
739 &event_network_stats,
740 sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
741 IPACMDBG("Received %d apn network stats \n", data_network_stats->apn_data_stats_list_len);
742 evt_data.event = IPA_NETWORK_STATS_UPDATE_EVENT;
743 evt_data.evt_data = data_network_stats;
744 break;
745
746 #ifdef FEATURE_IPACM_HAL
747 case IPA_QUOTA_REACH:
748 IPACMDBG_H("Received IPA_QUOTA_REACH\n");
749 OffloadMng = IPACM_OffloadManager::GetInstance();
750 if (OffloadMng->elrInstance == NULL) {
751 IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
752 } else {
753 IPACMERR("calling OffloadMng->elrInstance->onLimitReached \n");
754 OffloadMng->elrInstance->onLimitReached();
755 }
756 continue;
757 case IPA_SSR_BEFORE_SHUTDOWN:
758 IPACMDBG_H("Received IPA_SSR_BEFORE_SHUTDOWN\n");
759 IPACM_Wan::clearExtProp();
760 OffloadMng = IPACM_OffloadManager::GetInstance();
761 if (OffloadMng->elrInstance == NULL) {
762 IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
763 } else {
764 IPACMERR("calling OffloadMng->elrInstance->onOffloadStopped \n");
765 OffloadMng->elrInstance->onOffloadStopped(IpaEventRelay::ERROR);
766 }
767 /* Starting from Hastings, WLAN is not restarted as part of Modem SSR.
768 * No need to reset NAT Iface.
769 */
770 #ifdef IPA_HW_v4_9
771 if (IPACM_Iface::ipacmcfg->GetIPAVer() != IPA_HW_v4_9)
772 #endif
773 {
774 /* WA to clean up wlan instances during SSR */
775 evt_data.event = IPA_SSR_NOTICE;
776 evt_data.evt_data = NULL;
777 break;
778 }
779 continue;
780 case IPA_SSR_AFTER_POWERUP:
781 IPACMDBG_H("Received IPA_SSR_AFTER_POWERUP\n");
782 OffloadMng = IPACM_OffloadManager::GetInstance();
783 if (OffloadMng->elrInstance == NULL) {
784 IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
785 } else {
786 IPACMERR("calling OffloadMng->elrInstance->onOffloadSupportAvailable \n");
787 OffloadMng->elrInstance->onOffloadSupportAvailable();
788 }
789 continue;
790 #ifdef IPA_WLAN_FW_SSR_EVENT_MAX
791 case WLAN_FWR_SSR_BEFORE_SHUTDOWN:
792 IPACMDBG_H("Received WLAN_FWR_SSR_BEFORE_SHUTDOWN\n");
793 evt_data.event = IPA_WLAN_FWR_SSR_BEFORE_SHUTDOWN_NOTICE;
794 evt_data.evt_data = NULL;
795 break;
796 #endif
797 #endif
798 #ifdef FEATURE_L2TP
799 case ADD_VLAN_IFACE:
800 vlan_info = (ipa_ioc_vlan_iface_info *)malloc(sizeof(*vlan_info));
801 if(vlan_info == NULL)
802 {
803 IPACMERR("Failed to allocate memory.\n");
804 return NULL;
805 }
806 memcpy(vlan_info, buffer + sizeof(struct ipa_msg_meta), sizeof(*vlan_info));
807 evt_data.event = IPA_ADD_VLAN_IFACE;
808 evt_data.evt_data = vlan_info;
809 break;
810
811 case DEL_VLAN_IFACE:
812 vlan_info = (ipa_ioc_vlan_iface_info *)malloc(sizeof(*vlan_info));
813 if(vlan_info == NULL)
814 {
815 IPACMERR("Failed to allocate memory.\n");
816 return NULL;
817 }
818 memcpy(vlan_info, buffer + sizeof(struct ipa_msg_meta), sizeof(*vlan_info));
819 evt_data.event = IPA_DEL_VLAN_IFACE;
820 evt_data.evt_data = vlan_info;
821 break;
822
823 case ADD_L2TP_VLAN_MAPPING:
824 mapping = (ipa_ioc_l2tp_vlan_mapping_info *)malloc(sizeof(*mapping));
825 if(mapping == NULL)
826 {
827 IPACMERR("Failed to allocate memory.\n");
828 return NULL;
829 }
830 memcpy(mapping, buffer + sizeof(struct ipa_msg_meta), sizeof(*mapping));
831 evt_data.event = IPA_ADD_L2TP_VLAN_MAPPING;
832 evt_data.evt_data = mapping;
833 break;
834
835 case DEL_L2TP_VLAN_MAPPING:
836 mapping = (ipa_ioc_l2tp_vlan_mapping_info *)malloc(sizeof(*mapping));
837 if(mapping == NULL)
838 {
839 IPACMERR("Failed to allocate memory.\n");
840 return NULL;
841 }
842 memcpy(mapping, buffer + sizeof(struct ipa_msg_meta), sizeof(*mapping));
843 evt_data.event = IPA_DEL_L2TP_VLAN_MAPPING;
844 evt_data.evt_data = mapping;
845 break;
846 #endif
847 #ifdef IPA_RT_SUPPORT_COAL
848 case IPA_COALESCE_ENABLE:
849 memcpy(&coalesce_info, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_coalesce_info));
850 IPACMDBG_H("Received IPA_COALESCE_ENABLE qmap-id:%d tcp:%d, udp%d\n",
851 coalesce_info.qmap_id, coalesce_info.tcp_enable, coalesce_info.udp_enable);
852 if (coalesce_info.qmap_id >=IPA_MAX_NUM_SW_PDNS)
853 {
854 IPACMERR("qmap_id (%d) beyond the Max range (%d), abort\n",
855 coalesce_info.qmap_id, IPA_MAX_NUM_SW_PDNS);
856 return NULL;
857 }
858 IPACM_Wan::coalesce_config(coalesce_info.qmap_id, coalesce_info.tcp_enable, coalesce_info.udp_enable);
859 /* Notify all LTE instance to do RSC configuration */
860 evt_data.event = IPA_COALESCE_NOTICE;
861 evt_data.evt_data = NULL;
862 break;
863
864 case IPA_COALESCE_DISABLE:
865 memcpy(&coalesce_info, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_coalesce_info));
866 IPACMDBG_H("Received IPA_COALESCE_DISABLE qmap-id:%d tcp:%d, udp%d\n",
867 coalesce_info.qmap_id, coalesce_info.tcp_enable, coalesce_info.udp_enable);
868 if (coalesce_info.qmap_id >=IPA_MAX_NUM_SW_PDNS)
869 {
870 IPACMERR("qmap_id (%d) beyond the Max range (%d), abort\n",
871 coalesce_info.qmap_id, IPA_MAX_NUM_SW_PDNS);
872 return NULL;
873 }
874 IPACM_Wan::coalesce_config(coalesce_info.qmap_id, false, false);
875 /* Notify all LTE instance to do RSC configuration */
876 evt_data.event = IPA_COALESCE_NOTICE;
877 evt_data.evt_data = NULL;
878 break;
879 #endif
880
881 #ifdef IPA_MTU_EVENT_MAX
882 case IPA_SET_MTU:
883 mtu_event = (ipacm_event_mtu_info *)malloc(sizeof(*mtu_event));
884 if(mtu_event == NULL)
885 {
886 IPACMERR("Failed to allocate memory.\n");
887 return NULL;
888 }
889 mtu_info = &(mtu_event->mtu_info);
890 memcpy(mtu_info, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_mtu_info));
891 IPACMDBG_H("Received IPA_SET_MTU if_name %s ip_type %d mtu_v4 %d mtu_v6 %d\n",
892 mtu_info->if_name, mtu_info->ip_type, mtu_info->mtu_v4, mtu_info->mtu_v6);
893 if (mtu_info->ip_type > IPA_IP_MAX)
894 {
895 IPACMERR("ip_type (%d) beyond the Max range (%d), abort\n",
896 mtu_info->ip_type, IPA_IP_MAX);
897 return NULL;
898 }
899
900 ipa_get_if_index(mtu_info->if_name, &(mtu_event->if_index));
901
902 evt_data.event = IPA_MTU_SET;
903 evt_data.evt_data = mtu_event;
904 break;
905 #endif
906
907 default:
908 IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type);
909 continue;
910
911 }
912 /* finish command queue */
913 IPACMDBG_H("Posting event:%d\n", evt_data.event);
914 IPACM_EvtDispatcher::PostEvt(&evt_data);
915 /* push new_neighbor with netdev device internally */
916 if(new_neigh_data != NULL)
917 {
918 IPACMDBG_H("Internally post event IPA_NEW_NEIGH_EVENT\n");
919 IPACM_EvtDispatcher::PostEvt(&new_neigh_evt);
920 }
921 }
922
923 (void)close(fd);
924 return NULL;
925 }
926
IPACM_Sig_Handler(int sig)927 void IPACM_Sig_Handler(int sig)
928 {
929 ipacm_cmd_q_data evt_data;
930
931 printf("Received Signal: %d\n", sig);
932 memset(&evt_data, 0, sizeof(evt_data));
933
934 switch(sig)
935 {
936 case SIGUSR1:
937 IPACMDBG_H("Received SW_ROUTING_ENABLE request \n");
938 evt_data.event = IPA_SW_ROUTING_ENABLE;
939 IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = true;
940 break;
941
942 case SIGUSR2:
943 IPACMDBG_H("Received SW_ROUTING_DISABLE request \n");
944 evt_data.event = IPA_SW_ROUTING_DISABLE;
945 IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = false;
946 break;
947 }
948 /* finish command queue */
949 IPACMDBG_H("Posting event:%d\n", evt_data.event);
950 IPACM_EvtDispatcher::PostEvt(&evt_data);
951 return;
952 }
953
RegisterForSignals(void)954 void RegisterForSignals(void)
955 {
956
957 signal(SIGUSR1, IPACM_Sig_Handler);
958 signal(SIGUSR2, IPACM_Sig_Handler);
959 }
960
961
main(int argc,char ** argv)962 int main(int argc, char **argv)
963 {
964 int ret;
965 pthread_t netlink_thread = 0, monitor_thread = 0, ipa_driver_thread = 0;
966 pthread_t cmd_queue_thread = 0;
967
968 /* check if ipacm is already running or not */
969 ipa_is_ipacm_running();
970
971 IPACMDBG_H("In main()\n");
972 (void)argc;
973 (void)argv;
974
975 #ifdef FEATURE_IPACM_RESTART
976 IPACMDBG_H("RESET IPA-HW rules\n");
977 ipa_reset();
978 #endif
979
980 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
981 IPACMDBG_H("Configure IPA-HW index-counter\n");
982 ipa_reset_hw_index_counter();
983 #endif
984
985 neigh = new IPACM_Neighbor();
986 ifacemgr = new IPACM_IfaceManager();
987 #ifdef FEATURE_IPACM_HAL
988 OffloadMng = IPACM_OffloadManager::GetInstance();
989 hal = HAL::makeIPAHAL(1, OffloadMng);
990 IPACMDBG_H(" START IPACM_OffloadManager and link to android framework\n");
991 #endif
992
993 if (IPACM_Iface::ipacmcfg->isEthBridgingSupported())
994 {
995 IPACM_LanToLan* lan2lan = IPACM_LanToLan::get_instance();
996 IPACMDBG_H("Staring IPACM_LanToLan instance %p\n", lan2lan);
997 }
998 CtList = new IPACM_ConntrackListener();
999
1000 IPACMDBG_H("Staring IPA main\n");
1001 IPACMDBG_H("ipa_cmdq_successful\n");
1002
1003 /* reset coalesce settings */
1004 IPACM_Wan::coalesce_config_reset();
1005
1006 RegisterForSignals();
1007
1008 if (IPACM_SUCCESS == cmd_queue_thread)
1009 {
1010 ret = pthread_create(&cmd_queue_thread, NULL, MessageQueue::Process, NULL);
1011 if (IPACM_SUCCESS != ret)
1012 {
1013 IPACMERR("unable to command queue thread\n");
1014 return ret;
1015 }
1016 IPACMDBG_H("created command queue thread\n");
1017 if(pthread_setname_np(cmd_queue_thread, "cmd queue process") != 0)
1018 {
1019 IPACMERR("unable to set thread name\n");
1020 }
1021 }
1022
1023 if (IPACM_SUCCESS == netlink_thread)
1024 {
1025 ret = pthread_create(&netlink_thread, NULL, netlink_start, NULL);
1026 if (IPACM_SUCCESS != ret)
1027 {
1028 IPACMERR("unable to create netlink thread\n");
1029 return ret;
1030 }
1031 IPACMDBG_H("created netlink thread\n");
1032 if(pthread_setname_np(netlink_thread, "netlink socket") != 0)
1033 {
1034 IPACMERR("unable to set thread name\n");
1035 }
1036 }
1037
1038 /* Enable Firewall support only on MDM targets */
1039 #ifndef FEATURE_IPA_ANDROID
1040 if (IPACM_SUCCESS == monitor_thread)
1041 {
1042 ret = pthread_create(&monitor_thread, NULL, firewall_monitor, NULL);
1043 if (IPACM_SUCCESS != ret)
1044 {
1045 IPACMERR("unable to create monitor thread\n");
1046 return ret;
1047 }
1048 IPACMDBG_H("created firewall monitor thread\n");
1049 if(pthread_setname_np(monitor_thread, "firewall cfg process") != 0)
1050 {
1051 IPACMERR("unable to set thread name\n");
1052 }
1053 }
1054 #endif
1055
1056 if (IPACM_SUCCESS == ipa_driver_thread)
1057 {
1058 ret = pthread_create(&ipa_driver_thread, NULL, ipa_driver_msg_notifier, NULL);
1059 if (IPACM_SUCCESS != ret)
1060 {
1061 IPACMERR("unable to create ipa_driver_wlan thread\n");
1062 return ret;
1063 }
1064 IPACMDBG_H("created ipa_driver_wlan thread\n");
1065 if(pthread_setname_np(ipa_driver_thread, "ipa driver ntfy") != 0)
1066 {
1067 IPACMERR("unable to set thread name\n");
1068 }
1069 }
1070
1071 pthread_join(cmd_queue_thread, NULL);
1072 pthread_join(netlink_thread, NULL);
1073 pthread_join(monitor_thread, NULL);
1074 pthread_join(ipa_driver_thread, NULL);
1075 return IPACM_SUCCESS;
1076 }
1077
1078 /*===========================================================================
1079 FUNCTION ipa_is_ipacm_running
1080 ===========================================================================*/
1081 /*!
1082 @brief
1083 Determine whether there's already an IPACM process running, if so, terminate
1084 the current one
1085
1086 @return
1087 None
1088
1089 @note
1090
1091 - Dependencies
1092 - None
1093
1094 - Side Effects
1095 - None
1096 */
1097 /*=========================================================================*/
1098
ipa_is_ipacm_running(void)1099 void ipa_is_ipacm_running(void) {
1100
1101 int fd;
1102 struct flock lock;
1103 int retval;
1104
1105 fd = open(IPACM_PID_FILE, O_RDWR | O_CREAT, 0600);
1106 if ( fd <= 0 )
1107 {
1108 IPACMERR("Failed to open %s, error is %d - %s\n",
1109 IPACM_PID_FILE, errno, strerror(errno));
1110 exit(0);
1111 }
1112
1113 /*
1114 * Getting an exclusive Write lock on the file, if it fails,
1115 * it means that another instance of IPACM is running and it
1116 * got the lock before us.
1117 */
1118 memset(&lock, 0, sizeof(lock));
1119 lock.l_type = F_WRLCK;
1120 retval = fcntl(fd, F_SETLK, &lock);
1121
1122 if (retval != 0)
1123 {
1124 retval = fcntl(fd, F_GETLK, &lock);
1125 if (retval == 0)
1126 {
1127 IPACMERR("Unable to get lock on file %s (my PID %d), PID %d already has it\n",
1128 IPACM_PID_FILE, getpid(), lock.l_pid);
1129 close(fd);
1130 exit(0);
1131 }
1132 }
1133 else
1134 {
1135 IPACMERR("PID %d is IPACM main process\n", getpid());
1136 }
1137
1138 return;
1139 }
1140
1141 /*===========================================================================
1142 FUNCTION ipa_get_if_index
1143 ===========================================================================*/
1144 /*!
1145 @brief
1146 get ipa interface index by given the interface name
1147
1148 @return
1149 IPACM_SUCCESS or IPA_FALUIRE
1150
1151 @note
1152
1153 - Dependencies
1154 - None
1155
1156 - Side Effects
1157 - None
1158 */
1159 /*=========================================================================*/
ipa_get_if_index(char * if_name,int * if_index)1160 int ipa_get_if_index
1161 (
1162 char *if_name,
1163 int *if_index
1164 )
1165 {
1166 int fd;
1167 struct ifreq ifr;
1168
1169 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1170 {
1171 PERROR("get interface index socket create failed");
1172 return IPACM_FAILURE;
1173 }
1174
1175 memset(&ifr, 0, sizeof(struct ifreq));
1176
1177 (void)strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
1178
1179 if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
1180 {
1181 IPACMERR("call_ioctl_on_dev: ioctl failed: can't find device %s",if_name);
1182 *if_index = -1;
1183 close(fd);
1184 return IPACM_FAILURE;
1185 }
1186
1187 *if_index = ifr.ifr_ifindex;
1188 close(fd);
1189 return IPACM_SUCCESS;
1190 }
1191
1192 #ifdef FEATURE_IPACM_RESTART
ipa_reset()1193 int ipa_reset()
1194 {
1195 int fd = -1;
1196
1197 if ((fd = open(IPA_DEVICE_NAME, O_RDWR)) < 0) {
1198 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
1199 return IPACM_FAILURE;
1200 }
1201
1202 if (ioctl(fd, IPA_IOC_CLEANUP) < 0) {
1203 IPACMERR("IOCTL IPA_IOC_CLEANUP call failed: %s \n", strerror(errno));
1204 close(fd);
1205 return IPACM_FAILURE;
1206 }
1207
1208 IPACMDBG_H("send IPA_IOC_CLEANUP \n");
1209 close(fd);
1210 return IPACM_SUCCESS;
1211 }
1212 #endif
1213
1214 #ifdef IPA_IOCTL_SET_FNR_COUNTER_INFO
ipa_reset_hw_index_counter()1215 int ipa_reset_hw_index_counter()
1216 {
1217 int fd = -1;
1218 struct ipa_ioc_flt_rt_counter_alloc fnr_counters;
1219 struct ipa_ioc_fnr_index_info fnr_info;
1220
1221 if ((fd = open(IPA_DEVICE_NAME, O_RDWR)) < 0) {
1222 IPACMERR("Failed opening %s.\n", IPA_DEVICE_NAME);
1223 return IPACM_FAILURE;
1224 }
1225
1226 memset(&fnr_counters, 0, sizeof(fnr_counters));
1227 fnr_counters.hw_counter.num_counters = 4;
1228 fnr_counters.hw_counter.allow_less = false;
1229 fnr_counters.sw_counter.num_counters = 4;
1230 fnr_counters.sw_counter.allow_less = false;
1231 IPACMDBG_H("Allocating %d hw counters and %d sw counters\n",
1232 fnr_counters.hw_counter.num_counters, fnr_counters.sw_counter.num_counters);
1233
1234 if (ioctl(fd, IPA_IOC_FNR_COUNTER_ALLOC, &fnr_counters) < 0) {
1235 IPACMERR("IPA_IOC_FNR_COUNTER_ALLOC call failed: %s \n", strerror(errno));
1236 close(fd);
1237 return IPACM_FAILURE;
1238 }
1239
1240 IPACMDBG_H("hw-counter start offset %d, sw-counter start offset %d\n",
1241 fnr_counters.hw_counter.start_id, fnr_counters.sw_counter.start_id);
1242 IPACM_Iface::ipacmcfg->hw_fnr_stats_support = true;
1243 IPACM_Iface::ipacmcfg->hw_counter_offset = fnr_counters.hw_counter.start_id;
1244 IPACM_Iface::ipacmcfg->sw_counter_offset = fnr_counters.sw_counter.start_id;
1245
1246 /* set FNR counter info */
1247 memset(&fnr_info, 0, sizeof(fnr_info));
1248 fnr_info.hw_counter_offset = fnr_counters.hw_counter.start_id;
1249 fnr_info.sw_counter_offset = fnr_counters.sw_counter.start_id;
1250
1251 if (ioctl(fd, IPA_IOC_SET_FNR_COUNTER_INFO, &fnr_info) < 0) {
1252 IPACMERR("IPA_IOC_SET_FNR_COUNTER_INFO call failed: %s \n", strerror(errno));
1253 close(fd);
1254 return IPACM_FAILURE;
1255 }
1256
1257 close(fd);
1258 return IPACM_SUCCESS;
1259 }
1260 #endif
1261