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_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
67 #include "IPACM_ConntrackListener.h"
68 #include "IPACM_ConntrackClient.h"
69 #include "IPACM_Netlink.h"
70
71 #ifdef FEATURE_IPACM_HAL
72 #include "IPACM_OffloadManager.h"
73 #include <HAL.h>
74 #endif
75
76 /* not defined(FEATURE_IPA_ANDROID)*/
77 #ifndef FEATURE_IPA_ANDROID
78 #include "IPACM_LanToLan.h"
79 #endif
80
81 #define IPA_DRIVER "/dev/ipa"
82
83 #define IPACM_FIREWALL_FILE_NAME "mobileap_firewall.xml"
84 #define IPACM_CFG_FILE_NAME "IPACM_cfg.xml"
85 #ifdef FEATURE_IPA_ANDROID
86 #define IPACM_PID_FILE "/data/vendor/ipa/ipacm.pid"
87 #define IPACM_DIR_NAME "/data"
88 #else/* defined(FEATURE_IPA_ANDROID) */
89 #define IPACM_PID_FILE "/etc/ipacm.pid"
90 #define IPACM_DIR_NAME "/etc"
91 #endif /* defined(NOT FEATURE_IPA_ANDROID)*/
92 #define IPACM_NAME "ipacm"
93
94 #define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
95 #define INOTIFY_BUF_LEN (INOTIFY_EVENT_SIZE + 2*sizeof(IPACM_FIREWALL_FILE_NAME))
96
97 #define IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS 3
98 #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))
99 #define IPA_DRIVER_PIPE_STATS_EVENT_SIZE (sizeof(struct ipa_get_data_stats_resp_msg_v01))
100 #define IPA_DRIVER_WLAN_META_MSG (sizeof(struct ipa_msg_meta))
101 #define IPA_DRIVER_WLAN_BUF_LEN (IPA_DRIVER_PIPE_STATS_EVENT_SIZE + IPA_DRIVER_WLAN_META_MSG)
102
103 uint32_t ipacm_event_stats[IPACM_EVENT_MAX];
104 bool ipacm_logging = true;
105
106 void ipa_is_ipacm_running(void);
107 int ipa_get_if_index(char *if_name, int *if_index);
108
109 IPACM_Neighbor *neigh;
110 IPACM_IfaceManager *ifacemgr;
111 #ifdef FEATURE_IPACM_HAL
112 IPACM_OffloadManager* OffloadMng;
113 HAL *hal;
114 #endif
115
116 /* start netlink socket monitor*/
netlink_start(void * param)117 void* netlink_start(void *param)
118 {
119 param = NULL;
120 ipa_nl_sk_fd_set_info_t sk_fdset;
121 int ret_val = 0;
122 memset(&sk_fdset, 0, sizeof(ipa_nl_sk_fd_set_info_t));
123 IPACMDBG_H("netlink starter memset sk_fdset succeeds\n");
124 ret_val = ipa_nl_listener_init(NETLINK_ROUTE, (RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_LINK |
125 RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_NEIGH |
126 RTNLGRP_IPV6_PREFIX),
127 &sk_fdset, ipa_nl_recv_msg);
128
129 if (ret_val != IPACM_SUCCESS)
130 {
131 IPACMERR("Failed to initialize IPA netlink event listener\n");
132 return NULL;
133 }
134
135 return NULL;
136 }
137
138 /* start firewall-rule monitor*/
firewall_monitor(void * param)139 void* firewall_monitor(void *param)
140 {
141 int length;
142 int wd;
143 char buffer[INOTIFY_BUF_LEN];
144 int inotify_fd;
145 ipacm_cmd_q_data evt_data;
146 uint32_t mask = IN_MODIFY | IN_MOVE;
147
148 param = NULL;
149 inotify_fd = inotify_init();
150 if (inotify_fd < 0)
151 {
152 PERROR("inotify_init");
153 }
154
155 IPACMDBG_H("Waiting for nofications in dir %s with mask: 0x%x\n", IPACM_DIR_NAME, mask);
156
157 wd = inotify_add_watch(inotify_fd,
158 IPACM_DIR_NAME,
159 mask);
160
161 while (1)
162 {
163 length = read(inotify_fd, buffer, INOTIFY_BUF_LEN);
164 if (length < 0)
165 {
166 IPACMERR("inotify read() error return length: %d and mask: 0x%x\n", length, mask);
167 continue;
168 }
169
170 struct inotify_event* event;
171 event = (struct inotify_event*)malloc(length);
172 if(event == NULL)
173 {
174 IPACMERR("Failed to allocate memory.\n");
175 return NULL;
176 }
177 memset(event, 0, length);
178 memcpy(event, buffer, length);
179
180 if (event->len > 0)
181 {
182 if ( (event->mask & IN_MODIFY) || (event->mask & IN_MOVE))
183 {
184 if (event->mask & IN_ISDIR)
185 {
186 IPACMDBG_H("The directory %s was 0x%x\n", event->name, event->mask);
187 }
188 else if (!strncmp(event->name, IPACM_FIREWALL_FILE_NAME, event->len)) // firewall_rule change
189 {
190 IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask);
191 IPACMDBG_H("The interested file %s .\n", IPACM_FIREWALL_FILE_NAME);
192
193 evt_data.event = IPA_FIREWALL_CHANGE_EVENT;
194 evt_data.evt_data = NULL;
195
196 /* Insert IPA_FIREWALL_CHANGE_EVENT to command queue */
197 IPACM_EvtDispatcher::PostEvt(&evt_data);
198 }
199 else if (!strncmp(event->name, IPACM_CFG_FILE_NAME, event->len)) // IPACM_configuration change
200 {
201 IPACMDBG_H("File \"%s\" was 0x%x\n", event->name, event->mask);
202 IPACMDBG_H("The interested file %s .\n", IPACM_CFG_FILE_NAME);
203
204 evt_data.event = IPA_CFG_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 }
211 IPACMDBG_H("Received monitoring event %s.\n", event->name);
212 }
213 free(event);
214 }
215
216 (void)inotify_rm_watch(inotify_fd, wd);
217 (void)close(inotify_fd);
218 return NULL;
219 }
220
221
222 /* start IPACM wan-driver notifier */
ipa_driver_msg_notifier(void * param)223 void* ipa_driver_msg_notifier(void *param)
224 {
225 int length, fd, cnt;
226 char buffer[IPA_DRIVER_WLAN_BUF_LEN];
227 struct ipa_msg_meta event_hdr;
228 struct ipa_ecm_msg event_ecm;
229 struct ipa_wan_msg event_wan;
230 struct ipa_wlan_msg_ex event_ex_o;
231 struct ipa_wlan_msg *event_wlan=NULL;
232 struct ipa_wlan_msg_ex *event_ex= NULL;
233 struct ipa_get_data_stats_resp_msg_v01 event_data_stats;
234 struct ipa_get_apn_data_stats_resp_msg_v01 event_network_stats;
235 IPACM_OffloadManager* OffloadMng;
236
237 ipacm_cmd_q_data evt_data;
238 ipacm_event_data_mac *data = NULL;
239 ipacm_event_data_fid *data_fid = NULL;
240 ipacm_event_data_iptype *data_iptype = NULL;
241 ipacm_event_data_wlan_ex *data_ex;
242 ipa_get_data_stats_resp_msg_v01 *data_tethering_stats = NULL;
243 ipa_get_apn_data_stats_resp_msg_v01 *data_network_stats = NULL;
244
245 ipacm_cmd_q_data new_neigh_evt;
246 ipacm_event_data_all* new_neigh_data;
247
248 param = NULL;
249 fd = open(IPA_DRIVER, O_RDWR);
250 if (fd < 0)
251 {
252 IPACMERR("Failed opening %s.\n", IPA_DRIVER);
253 return NULL;
254 }
255
256 while (1)
257 {
258 IPACMDBG_H("Waiting for nofications from IPA driver \n");
259 memset(buffer, 0, sizeof(buffer));
260 memset(&evt_data, 0, sizeof(evt_data));
261 memset(&new_neigh_evt, 0, sizeof(ipacm_cmd_q_data));
262 new_neigh_data = NULL;
263 data = NULL;
264 data_fid = NULL;
265 data_tethering_stats = NULL;
266 data_network_stats = NULL;
267
268 length = read(fd, buffer, IPA_DRIVER_WLAN_BUF_LEN);
269 if (length < 0)
270 {
271 PERROR("didn't read IPA_driver correctly");
272 continue;
273 }
274
275 memcpy(&event_hdr, buffer,sizeof(struct ipa_msg_meta));
276 IPACMDBG_H("Message type: %d\n", event_hdr.msg_type);
277 IPACMDBG_H("Event header length received: %d\n",event_hdr.msg_len);
278
279 /* Insert WLAN_DRIVER_EVENT to command queue */
280 switch (event_hdr.msg_type)
281 {
282
283 case SW_ROUTING_ENABLE:
284 IPACMDBG_H("Received SW_ROUTING_ENABLE\n");
285 evt_data.event = IPA_SW_ROUTING_ENABLE;
286 IPACMDBG_H("Not supported anymore\n");
287 continue;
288
289 case SW_ROUTING_DISABLE:
290 IPACMDBG_H("Received SW_ROUTING_DISABLE\n");
291 evt_data.event = IPA_SW_ROUTING_DISABLE;
292 IPACMDBG_H("Not supported anymore\n");
293 continue;
294
295 case WLAN_AP_CONNECT:
296 event_wlan = (struct ipa_wlan_msg *) (buffer + sizeof(struct ipa_msg_meta));
297 IPACMDBG_H("Received WLAN_AP_CONNECT name: %s\n",event_wlan->name);
298 IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
299 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
300 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
301 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
302 if(data_fid == NULL)
303 {
304 IPACMERR("unable to allocate memory for event_wlan data_fid\n");
305 return NULL;
306 }
307 ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
308 evt_data.event = IPA_WLAN_AP_LINK_UP_EVENT;
309 evt_data.evt_data = data_fid;
310 break;
311
312 case WLAN_AP_DISCONNECT:
313 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
314 IPACMDBG_H("Received WLAN_AP_DISCONNECT name: %s\n",event_wlan->name);
315 IPACMDBG_H("AP Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
316 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
317 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
318 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
319 if(data_fid == NULL)
320 {
321 IPACMERR("unable to allocate memory for event_wlan data_fid\n");
322 return NULL;
323 }
324 ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
325 evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
326 evt_data.evt_data = data_fid;
327 break;
328 case WLAN_STA_CONNECT:
329 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
330 IPACMDBG_H("Received WLAN_STA_CONNECT name: %s\n",event_wlan->name);
331 IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
332 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
333 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
334 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
335 if(data == NULL)
336 {
337 IPACMERR("unable to allocate memory for event_wlan data_fid\n");
338 return NULL;
339 }
340 memcpy(data->mac_addr,
341 event_wlan->mac_addr,
342 sizeof(event_wlan->mac_addr));
343 ipa_get_if_index(event_wlan->name, &(data->if_index));
344 evt_data.event = IPA_WLAN_STA_LINK_UP_EVENT;
345 evt_data.evt_data = data;
346 break;
347
348 case WLAN_STA_DISCONNECT:
349 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
350 IPACMDBG_H("Received WLAN_STA_DISCONNECT name: %s\n",event_wlan->name);
351 IPACMDBG_H("STA Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
352 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
353 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
354 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
355 if(data_fid == NULL)
356 {
357 IPACMERR("unable to allocate memory for event_wlan data_fid\n");
358 return NULL;
359 }
360 ipa_get_if_index(event_wlan->name, &(data_fid->if_index));
361 evt_data.event = IPA_WLAN_LINK_DOWN_EVENT;
362 evt_data.evt_data = data_fid;
363 break;
364
365 case WLAN_CLIENT_CONNECT:
366 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
367 IPACMDBG_H("Received WLAN_CLIENT_CONNECT\n");
368 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
369 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
370 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
371 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
372 if (data == NULL)
373 {
374 IPACMERR("unable to allocate memory for event_wlan data\n");
375 return NULL;
376 }
377 memcpy(data->mac_addr,
378 event_wlan->mac_addr,
379 sizeof(event_wlan->mac_addr));
380 ipa_get_if_index(event_wlan->name, &(data->if_index));
381 evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT;
382 evt_data.evt_data = data;
383 break;
384
385 case WLAN_CLIENT_CONNECT_EX:
386 IPACMDBG_H("Received WLAN_CLIENT_CONNECT_EX\n");
387
388 memcpy(&event_ex_o, buffer + sizeof(struct ipa_msg_meta),sizeof(struct ipa_wlan_msg_ex));
389 if(event_ex_o.num_of_attribs > IPA_DRIVER_WLAN_EVENT_MAX_OF_ATTRIBS)
390 {
391 IPACMERR("buffer size overflow\n");
392 return NULL;
393 }
394 length = sizeof(ipa_wlan_msg_ex)+ event_ex_o.num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val);
395 IPACMDBG_H("num_of_attribs %d, length %d\n", event_ex_o.num_of_attribs, length);
396 event_ex = (ipa_wlan_msg_ex *)malloc(length);
397 if(event_ex == NULL )
398 {
399 IPACMERR("Unable to allocate memory\n");
400 return NULL;
401 }
402 memcpy(event_ex, buffer + sizeof(struct ipa_msg_meta), length);
403 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));
404 if (data_ex == NULL)
405 {
406 IPACMERR("unable to allocate memory for event data\n");
407 return NULL;
408 }
409 data_ex->num_of_attribs = event_ex->num_of_attribs;
410
411 memcpy(data_ex->attribs,
412 event_ex->attribs,
413 event_ex->num_of_attribs * sizeof(ipa_wlan_hdr_attrib_val));
414
415 ipa_get_if_index(event_ex->name, &(data_ex->if_index));
416 evt_data.event = IPA_WLAN_CLIENT_ADD_EVENT_EX;
417 evt_data.evt_data = data_ex;
418
419 /* Construct new_neighbor msg with netdev device internally */
420 new_neigh_data = (ipacm_event_data_all*)malloc(sizeof(ipacm_event_data_all));
421 if(new_neigh_data == NULL)
422 {
423 IPACMERR("Failed to allocate memory.\n");
424 return NULL;
425 }
426 memset(new_neigh_data, 0, sizeof(ipacm_event_data_all));
427 new_neigh_data->iptype = IPA_IP_v6;
428 for(cnt = 0; cnt < event_ex->num_of_attribs; cnt++)
429 {
430 if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_MAC_ADDR)
431 {
432 memcpy(new_neigh_data->mac_addr, event_ex->attribs[cnt].u.mac_addr, sizeof(new_neigh_data->mac_addr));
433 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
434 event_ex->attribs[cnt].u.mac_addr[0], event_ex->attribs[cnt].u.mac_addr[1], event_ex->attribs[cnt].u.mac_addr[2],
435 event_ex->attribs[cnt].u.mac_addr[3], event_ex->attribs[cnt].u.mac_addr[4], event_ex->attribs[cnt].u.mac_addr[5]);
436 }
437 else if(event_ex->attribs[cnt].attrib_type == WLAN_HDR_ATTRIB_STA_ID)
438 {
439 IPACMDBG_H("Wlan client id %d\n",event_ex->attribs[cnt].u.sta_id);
440 }
441 else
442 {
443 IPACMDBG_H("Wlan message has unexpected type!\n");
444 }
445 }
446 new_neigh_data->if_index = data_ex->if_index;
447 new_neigh_evt.evt_data = (void*)new_neigh_data;
448 new_neigh_evt.event = IPA_NEW_NEIGH_EVENT;
449 free(event_ex);
450 break;
451
452 case WLAN_CLIENT_DISCONNECT:
453 IPACMDBG_H("Received WLAN_CLIENT_DISCONNECT\n");
454 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
455 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
456 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
457 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
458 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
459 if (data == NULL)
460 {
461 IPACMERR("unable to allocate memory for event_wlan data\n");
462 return NULL;
463 }
464 memcpy(data->mac_addr,
465 event_wlan->mac_addr,
466 sizeof(event_wlan->mac_addr));
467 ipa_get_if_index(event_wlan->name, &(data->if_index));
468 evt_data.event = IPA_WLAN_CLIENT_DEL_EVENT;
469 evt_data.evt_data = data;
470 break;
471
472 case WLAN_CLIENT_POWER_SAVE_MODE:
473 IPACMDBG_H("Received WLAN_CLIENT_POWER_SAVE_MODE\n");
474 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
475 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
476 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
477 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
478 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
479 if (data == NULL)
480 {
481 IPACMERR("unable to allocate memory for event_wlan data\n");
482 return NULL;
483 }
484 memcpy(data->mac_addr,
485 event_wlan->mac_addr,
486 sizeof(event_wlan->mac_addr));
487 ipa_get_if_index(event_wlan->name, &(data->if_index));
488 evt_data.event = IPA_WLAN_CLIENT_POWER_SAVE_EVENT;
489 evt_data.evt_data = data;
490 break;
491
492 case WLAN_CLIENT_NORMAL_MODE:
493 IPACMDBG_H("Received WLAN_CLIENT_NORMAL_MODE\n");
494 event_wlan = (struct ipa_wlan_msg *)(buffer + sizeof(struct ipa_msg_meta));
495 IPACMDBG_H("Mac Address %02x:%02x:%02x:%02x:%02x:%02x\n",
496 event_wlan->mac_addr[0], event_wlan->mac_addr[1], event_wlan->mac_addr[2],
497 event_wlan->mac_addr[3], event_wlan->mac_addr[4], event_wlan->mac_addr[5]);
498 data = (ipacm_event_data_mac *)malloc(sizeof(ipacm_event_data_mac));
499 if (data == NULL)
500 {
501 IPACMERR("unable to allocate memory for event_wlan data\n");
502 return NULL;
503 }
504 memcpy(data->mac_addr,
505 event_wlan->mac_addr,
506 sizeof(event_wlan->mac_addr));
507 ipa_get_if_index(event_wlan->name, &(data->if_index));
508 evt_data.evt_data = data;
509 evt_data.event = IPA_WLAN_CLIENT_RECOVER_EVENT;
510 break;
511
512 case ECM_CONNECT:
513 memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
514 IPACMDBG_H("Received ECM_CONNECT name: %s\n",event_ecm.name);
515 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
516 if(data_fid == NULL)
517 {
518 IPACMERR("unable to allocate memory for event_ecm data_fid\n");
519 return NULL;
520 }
521 data_fid->if_index = event_ecm.ifindex;
522 evt_data.event = IPA_USB_LINK_UP_EVENT;
523 evt_data.evt_data = data_fid;
524 break;
525
526 case ECM_DISCONNECT:
527 memcpy(&event_ecm, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_ecm_msg));
528 IPACMDBG_H("Received ECM_DISCONNECT name: %s\n",event_ecm.name);
529 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
530 if(data_fid == NULL)
531 {
532 IPACMERR("unable to allocate memory for event_ecm data_fid\n");
533 return NULL;
534 }
535 data_fid->if_index = event_ecm.ifindex;
536 evt_data.event = IPA_LINK_DOWN_EVENT;
537 evt_data.evt_data = data_fid;
538 break;
539 /* Add for 8994 Android case */
540 case WAN_UPSTREAM_ROUTE_ADD:
541 memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
542 IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
543 data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
544 if(data_iptype == NULL)
545 {
546 IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
547 return NULL;
548 }
549 ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
550 ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
551 data_iptype->iptype = event_wan.ip;
552 #ifdef IPA_WAN_MSG_IPv6_ADDR_GW_LEN
553 data_iptype->ipv4_addr_gw = event_wan.ipv4_addr_gw;
554 data_iptype->ipv6_addr_gw[0] = event_wan.ipv6_addr_gw[0];
555 data_iptype->ipv6_addr_gw[1] = event_wan.ipv6_addr_gw[1];
556 data_iptype->ipv6_addr_gw[2] = event_wan.ipv6_addr_gw[2];
557 data_iptype->ipv6_addr_gw[3] = event_wan.ipv6_addr_gw[3];
558 IPACMDBG_H("default gw ipv4 (%x)\n", data_iptype->ipv4_addr_gw);
559 IPACMDBG_H("IPV6 gateway: %08x:%08x:%08x:%08x \n",
560 data_iptype->ipv6_addr_gw[0], data_iptype->ipv6_addr_gw[1], data_iptype->ipv6_addr_gw[2], data_iptype->ipv6_addr_gw[3]);
561 #endif
562 IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_ADD: fid(%d) tether_fid(%d) ip-type(%d)\n", data_iptype->if_index,
563 data_iptype->if_index_tether, data_iptype->iptype);
564 evt_data.event = IPA_WAN_UPSTREAM_ROUTE_ADD_EVENT;
565 evt_data.evt_data = data_iptype;
566 break;
567 case WAN_UPSTREAM_ROUTE_DEL:
568 memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
569 IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL name: %s, tethered name: %s\n", event_wan.upstream_ifname, event_wan.tethered_ifname);
570 data_iptype = (ipacm_event_data_iptype *)malloc(sizeof(ipacm_event_data_iptype));
571 if(data_iptype == NULL)
572 {
573 IPACMERR("unable to allocate memory for event_ecm data_iptype\n");
574 return NULL;
575 }
576 ipa_get_if_index(event_wan.upstream_ifname, &(data_iptype->if_index));
577 ipa_get_if_index(event_wan.tethered_ifname, &(data_iptype->if_index_tether));
578 data_iptype->iptype = event_wan.ip;
579 IPACMDBG_H("Received WAN_UPSTREAM_ROUTE_DEL: fid(%d) ip-type(%d)\n", data_iptype->if_index, data_iptype->iptype);
580 evt_data.event = IPA_WAN_UPSTREAM_ROUTE_DEL_EVENT;
581 evt_data.evt_data = data_iptype;
582 break;
583 /* End of adding for 8994 Android case */
584
585 /* Add for embms case */
586 case WAN_EMBMS_CONNECT:
587 memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_wan_msg));
588 IPACMDBG("Received WAN_EMBMS_CONNECT name: %s\n",event_wan.upstream_ifname);
589 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
590 if(data_fid == NULL)
591 {
592 IPACMERR("unable to allocate memory for event data_fid\n");
593 return NULL;
594 }
595 ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
596 evt_data.event = IPA_WAN_EMBMS_LINK_UP_EVENT;
597 evt_data.evt_data = data_fid;
598 break;
599
600 case WLAN_SWITCH_TO_SCC:
601 IPACMDBG_H("Received WLAN_SWITCH_TO_SCC\n");
602 case WLAN_WDI_ENABLE:
603 IPACMDBG_H("Received WLAN_WDI_ENABLE\n");
604 if (IPACM_Iface::ipacmcfg->isMCC_Mode == true)
605 {
606 IPACM_Iface::ipacmcfg->isMCC_Mode = false;
607 evt_data.event = IPA_WLAN_SWITCH_TO_SCC;
608 break;
609 }
610 continue;
611 case WLAN_SWITCH_TO_MCC:
612 IPACMDBG_H("Received WLAN_SWITCH_TO_MCC\n");
613 case WLAN_WDI_DISABLE:
614 IPACMDBG_H("Received WLAN_WDI_DISABLE\n");
615 if (IPACM_Iface::ipacmcfg->isMCC_Mode == false)
616 {
617 IPACM_Iface::ipacmcfg->isMCC_Mode = true;
618 evt_data.event = IPA_WLAN_SWITCH_TO_MCC;
619 break;
620 }
621 continue;
622
623 case WAN_XLAT_CONNECT:
624 memcpy(&event_wan, buffer + sizeof(struct ipa_msg_meta),
625 sizeof(struct ipa_wan_msg));
626 IPACMDBG_H("Received WAN_XLAT_CONNECT name: %s\n",
627 event_wan.upstream_ifname);
628
629 /* post IPA_LINK_UP_EVENT event
630 * may be WAN interface is not up
631 */
632 data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
633 if(data_fid == NULL)
634 {
635 IPACMERR("unable to allocate memory for xlat event\n");
636 return NULL;
637 }
638 ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
639 evt_data.event = IPA_LINK_UP_EVENT;
640 evt_data.evt_data = data_fid;
641 IPACMDBG_H("Posting IPA_LINK_UP_EVENT event:%d\n", evt_data.event);
642 IPACM_EvtDispatcher::PostEvt(&evt_data);
643
644 /* post IPA_WAN_XLAT_CONNECT_EVENT event */
645 memset(&evt_data, 0, sizeof(evt_data));
646 data_fid = (ipacm_event_data_fid *)calloc(1, sizeof(ipacm_event_data_fid));
647 if(data_fid == NULL)
648 {
649 IPACMERR("unable to allocate memory for xlat event\n");
650 return NULL;
651 }
652 ipa_get_if_index(event_wan.upstream_ifname, &(data_fid->if_index));
653 evt_data.event = IPA_WAN_XLAT_CONNECT_EVENT;
654 evt_data.evt_data = data_fid;
655 IPACMDBG_H("Posting IPA_WAN_XLAT_CONNECT_EVENT event:%d\n", evt_data.event);
656 break;
657
658 case IPA_TETHERING_STATS_UPDATE_STATS:
659 memcpy(&event_data_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_data_stats_resp_msg_v01));
660 data_tethering_stats = (ipa_get_data_stats_resp_msg_v01 *)malloc(sizeof(struct ipa_get_data_stats_resp_msg_v01));
661 if(data_tethering_stats == NULL)
662 {
663 IPACMERR("unable to allocate memory for event data_tethering_stats\n");
664 return NULL;
665 }
666 memcpy(data_tethering_stats,
667 &event_data_stats,
668 sizeof(struct ipa_get_data_stats_resp_msg_v01));
669 IPACMDBG("Received IPA_TETHERING_STATS_UPDATE_STATS ipa_stats_type: %d\n",data_tethering_stats->ipa_stats_type);
670 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);
671 evt_data.event = IPA_TETHERING_STATS_UPDATE_EVENT;
672 evt_data.evt_data = data_tethering_stats;
673 break;
674
675 case IPA_TETHERING_STATS_UPDATE_NETWORK_STATS:
676 memcpy(&event_network_stats, buffer + sizeof(struct ipa_msg_meta), sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
677 data_network_stats = (ipa_get_apn_data_stats_resp_msg_v01 *)malloc(sizeof(ipa_get_apn_data_stats_resp_msg_v01));
678 if(data_network_stats == NULL)
679 {
680 IPACMERR("unable to allocate memory for event data_network_stats\n");
681 return NULL;
682 }
683 memcpy(data_network_stats,
684 &event_network_stats,
685 sizeof(struct ipa_get_apn_data_stats_resp_msg_v01));
686 IPACMDBG("Received %d apn network stats \n", data_network_stats->apn_data_stats_list_len);
687 evt_data.event = IPA_NETWORK_STATS_UPDATE_EVENT;
688 evt_data.evt_data = data_network_stats;
689 break;
690 #ifdef FEATURE_IPACM_HAL
691 case IPA_QUOTA_REACH:
692 IPACMDBG_H("Received IPA_QUOTA_REACH\n");
693 OffloadMng = IPACM_OffloadManager::GetInstance();
694 if (OffloadMng->elrInstance == NULL) {
695 IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
696 } else {
697 IPACMERR("calling OffloadMng->elrInstance->onLimitReached \n");
698 OffloadMng->elrInstance->onLimitReached();
699 }
700 continue;
701 case IPA_SSR_BEFORE_SHUTDOWN:
702 IPACMDBG_H("Received IPA_SSR_BEFORE_SHUTDOWN\n");
703 OffloadMng = IPACM_OffloadManager::GetInstance();
704 if (OffloadMng->elrInstance == NULL) {
705 IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
706 } else {
707 IPACMERR("calling OffloadMng->elrInstance->onOffloadStopped \n");
708 OffloadMng->elrInstance->onOffloadStopped(IpaEventRelay::ERROR);
709 }
710 continue;
711 case IPA_SSR_AFTER_POWERUP:
712 IPACMDBG_H("Received IPA_SSR_AFTER_POWERUP\n");
713 OffloadMng = IPACM_OffloadManager::GetInstance();
714 if (OffloadMng->elrInstance == NULL) {
715 IPACMERR("OffloadMng->elrInstance is NULL, can't forward to framework!\n");
716 } else {
717 IPACMERR("calling OffloadMng->elrInstance->onOffloadSupportAvailable \n");
718 OffloadMng->elrInstance->onOffloadSupportAvailable();
719 }
720 continue;
721 #endif
722 default:
723 IPACMDBG_H("Unhandled message type: %d\n", event_hdr.msg_type);
724 continue;
725
726 }
727 /* finish command queue */
728 IPACMDBG_H("Posting event:%d\n", evt_data.event);
729 IPACM_EvtDispatcher::PostEvt(&evt_data);
730 /* push new_neighbor with netdev device internally */
731 if(new_neigh_data != NULL)
732 {
733 IPACMDBG_H("Internally post event IPA_NEW_NEIGH_EVENT\n");
734 IPACM_EvtDispatcher::PostEvt(&new_neigh_evt);
735 }
736 }
737
738 (void)close(fd);
739 return NULL;
740 }
741
IPACM_Sig_Handler(int sig)742 void IPACM_Sig_Handler(int sig)
743 {
744 ipacm_cmd_q_data evt_data;
745
746 printf("Received Signal: %d\n", sig);
747 memset(&evt_data, 0, sizeof(evt_data));
748
749 switch(sig)
750 {
751 case SIGUSR1:
752 IPACMDBG_H("Received SW_ROUTING_ENABLE request \n");
753 evt_data.event = IPA_SW_ROUTING_ENABLE;
754 IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = true;
755 break;
756
757 case SIGUSR2:
758 IPACMDBG_H("Received SW_ROUTING_DISABLE request \n");
759 evt_data.event = IPA_SW_ROUTING_DISABLE;
760 IPACM_Iface::ipacmcfg->ipa_sw_rt_enable = false;
761 break;
762 }
763 /* finish command queue */
764 IPACMDBG_H("Posting event:%d\n", evt_data.event);
765 IPACM_EvtDispatcher::PostEvt(&evt_data);
766 return;
767 }
768
RegisterForSignals(void)769 void RegisterForSignals(void)
770 {
771
772 signal(SIGUSR1, IPACM_Sig_Handler);
773 signal(SIGUSR2, IPACM_Sig_Handler);
774 }
775
776
main(int argc,char ** argv)777 int main(int argc, char **argv)
778 {
779 int ret;
780 pthread_t netlink_thread = 0, monitor_thread = 0, ipa_driver_thread = 0;
781 pthread_t cmd_queue_thread = 0;
782
783 /* check if ipacm is already running or not */
784 ipa_is_ipacm_running();
785
786 IPACMDBG_H("In main()\n");
787 (void)argc;
788 (void)argv;
789
790 neigh = new IPACM_Neighbor();
791 ifacemgr = new IPACM_IfaceManager();
792 #ifdef FEATURE_IPACM_HAL
793 OffloadMng = IPACM_OffloadManager::GetInstance();
794 hal = HAL::makeIPAHAL(1, OffloadMng);
795 IPACMDBG_H(" START IPACM_OffloadManager and link to android framework\n");
796 #endif
797
798 #ifdef FEATURE_ETH_BRIDGE_LE
799 IPACM_LanToLan* lan2lan = new IPACM_LanToLan();
800 #endif
801
802 CtList = new IPACM_ConntrackListener();
803
804 IPACMDBG_H("Staring IPA main\n");
805 IPACMDBG_H("ipa_cmdq_successful\n");
806
807
808 RegisterForSignals();
809
810 if (IPACM_SUCCESS == cmd_queue_thread)
811 {
812 ret = pthread_create(&cmd_queue_thread, NULL, MessageQueue::Process, NULL);
813 if (IPACM_SUCCESS != ret)
814 {
815 IPACMERR("unable to command queue thread\n");
816 return ret;
817 }
818 IPACMDBG_H("created command queue thread\n");
819 if(pthread_setname_np(cmd_queue_thread, "cmd queue process") != 0)
820 {
821 IPACMERR("unable to set thread name\n");
822 }
823 }
824
825 if (IPACM_SUCCESS == netlink_thread)
826 {
827 ret = pthread_create(&netlink_thread, NULL, netlink_start, NULL);
828 if (IPACM_SUCCESS != ret)
829 {
830 IPACMERR("unable to create netlink thread\n");
831 return ret;
832 }
833 IPACMDBG_H("created netlink thread\n");
834 if(pthread_setname_np(netlink_thread, "netlink socket") != 0)
835 {
836 IPACMERR("unable to set thread name\n");
837 }
838 }
839
840 /* Enable Firewall support only on MDM targets */
841 #ifndef FEATURE_IPA_ANDROID
842 if (IPACM_SUCCESS == monitor_thread)
843 {
844 ret = pthread_create(&monitor_thread, NULL, firewall_monitor, NULL);
845 if (IPACM_SUCCESS != ret)
846 {
847 IPACMERR("unable to create monitor thread\n");
848 return ret;
849 }
850 IPACMDBG_H("created firewall monitor thread\n");
851 if(pthread_setname_np(monitor_thread, "firewall cfg process") != 0)
852 {
853 IPACMERR("unable to set thread name\n");
854 }
855 }
856 #endif
857
858 if (IPACM_SUCCESS == ipa_driver_thread)
859 {
860 ret = pthread_create(&ipa_driver_thread, NULL, ipa_driver_msg_notifier, NULL);
861 if (IPACM_SUCCESS != ret)
862 {
863 IPACMERR("unable to create ipa_driver_wlan thread\n");
864 return ret;
865 }
866 IPACMDBG_H("created ipa_driver_wlan thread\n");
867 if(pthread_setname_np(ipa_driver_thread, "ipa driver ntfy") != 0)
868 {
869 IPACMERR("unable to set thread name\n");
870 }
871 }
872
873 pthread_join(cmd_queue_thread, NULL);
874 pthread_join(netlink_thread, NULL);
875 pthread_join(monitor_thread, NULL);
876 pthread_join(ipa_driver_thread, NULL);
877 return IPACM_SUCCESS;
878 }
879
880 /*===========================================================================
881 FUNCTION ipa_is_ipacm_running
882 ===========================================================================*/
883 /*!
884 @brief
885 Determine whether there's already an IPACM process running, if so, terminate
886 the current one
887
888 @return
889 None
890
891 @note
892
893 - Dependencies
894 - None
895
896 - Side Effects
897 - None
898 */
899 /*=========================================================================*/
900
ipa_is_ipacm_running(void)901 void ipa_is_ipacm_running(void) {
902
903 int fd;
904 struct flock lock;
905 int retval;
906
907 fd = open(IPACM_PID_FILE, O_RDWR | O_CREAT, 0600);
908 if ( fd <= 0 )
909 {
910 IPACMERR("Failed to open %s, error is %d - %s\n",
911 IPACM_PID_FILE, errno, strerror(errno));
912 exit(0);
913 }
914
915 /*
916 * Getting an exclusive Write lock on the file, if it fails,
917 * it means that another instance of IPACM is running and it
918 * got the lock before us.
919 */
920 memset(&lock, 0, sizeof(lock));
921 lock.l_type = F_WRLCK;
922 retval = fcntl(fd, F_SETLK, &lock);
923
924 if (retval != 0)
925 {
926 retval = fcntl(fd, F_GETLK, &lock);
927 if (retval == 0)
928 {
929 IPACMERR("Unable to get lock on file %s (my PID %d), PID %d already has it\n",
930 IPACM_PID_FILE, getpid(), lock.l_pid);
931 close(fd);
932 exit(0);
933 }
934 }
935 else
936 {
937 IPACMERR("PID %d is IPACM main process\n", getpid());
938 }
939
940 return;
941 }
942
943 /*===========================================================================
944 FUNCTION ipa_get_if_index
945 ===========================================================================*/
946 /*!
947 @brief
948 get ipa interface index by given the interface name
949
950 @return
951 IPACM_SUCCESS or IPA_FALUIRE
952
953 @note
954
955 - Dependencies
956 - None
957
958 - Side Effects
959 - None
960 */
961 /*=========================================================================*/
ipa_get_if_index(char * if_name,int * if_index)962 int ipa_get_if_index
963 (
964 char *if_name,
965 int *if_index
966 )
967 {
968 int fd;
969 struct ifreq ifr;
970
971 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
972 {
973 PERROR("get interface index socket create failed");
974 return IPACM_FAILURE;
975 }
976
977 memset(&ifr, 0, sizeof(struct ifreq));
978
979 (void)strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
980
981 if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
982 {
983 IPACMERR("call_ioctl_on_dev: ioctl failed: can't find device %s",if_name);
984 *if_index = -1;
985 close(fd);
986 return IPACM_FAILURE;
987 }
988
989 *if_index = ifr.ifr_ifindex;
990 close(fd);
991 return IPACM_SUCCESS;
992 }
993