1 /*
2 Copyright (c) 2013-2017, 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_Netlink.cpp
32
33 @brief
34 This file implements the IPAM Netlink Socket Parer functionality.
35
36 @Author
37 Skylar Chang
38
39 */
40 #include <string.h>
41 #include <unistd.h>
42 #include <sys/ioctl.h>
43 #include <netinet/in.h>
44 #include "IPACM_CmdQueue.h"
45 #include "IPACM_Defs.h"
46 #include "IPACM_Netlink.h"
47 #include "IPACM_EvtDispatcher.h"
48 #include "IPACM_Log.h"
49
50 int ipa_get_if_name(char *if_name, int if_index);
51 int find_mask(int ip_v4_last, int *mask_value);
52
53 #ifdef FEATURE_IPA_ANDROID
54
55 #define IPACM_NL_COPY_ADDR( event_info, element ) \
56 memcpy( &event_info->attr_info.element.__data, \
57 RTA_DATA(rtah), \
58 sizeof(event_info->attr_info.element.__data) );
59
60 #define IPACM_EVENT_COPY_ADDR_v6( event_data, element) \
61 memcpy( event_data, element.__data, sizeof(event_data));
62
63 #define IPACM_EVENT_COPY_ADDR_v4( event_data, element) \
64 memcpy( &event_data, element.__data, sizeof(event_data));
65
66 #define IPACM_NL_REPORT_ADDR( prefix, addr ) \
67 if( AF_INET6 == (addr).ss_family ) { \
68 IPACM_LOG_IPV6_ADDR( prefix, addr.__data); \
69 } else { \
70 IPACM_LOG_IPV4_ADDR( prefix, (*(unsigned int*)&(addr).__data) ); \
71 }
72
73 #else/* defined(FEATURE_IPA_ANDROID) */
74
75 #define IPACM_NL_COPY_ADDR( event_info, element ) \
76 memcpy( &event_info->attr_info.element.__ss_padding, \
77 RTA_DATA(rtah), \
78 sizeof(event_info->attr_info.element.__ss_padding) );
79
80 #define IPACM_EVENT_COPY_ADDR_v6( event_data, element) \
81 memcpy( event_data, element.__ss_padding, sizeof(event_data));
82
83 #define IPACM_EVENT_COPY_ADDR_v4( event_data, element) \
84 memcpy( &event_data, element.__ss_padding, sizeof(event_data));
85
86 #define IPACM_NL_REPORT_ADDR( prefix, addr ) \
87 if( AF_INET6 == (addr).ss_family ) { \
88 IPACM_LOG_IPV6_ADDR( prefix, addr.__ss_padding); \
89 } else { \
90 IPACM_LOG_IPV4_ADDR( prefix, (*(unsigned int*)&(addr).__ss_padding) ); \
91 }
92 #endif /* defined(FEATURE_IPA_ANDROID)*/
93
94 #define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
95 #define IPACM_LOG_IPV6_ADDR(prefix, ip_addr) \
96 IPACMDBG_H(prefix); \
97 IPACMDBG_H(" IPV6 Address %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", \
98 (int)ip_addr[0], (int)ip_addr[1], \
99 (int)ip_addr[2], (int)ip_addr[3], \
100 (int)ip_addr[4], (int)ip_addr[5], \
101 (int)ip_addr[6], (int)ip_addr[7], \
102 (int)ip_addr[8], (int)ip_addr[9], \
103 (int)ip_addr[10], (int)ip_addr[11], \
104 (int)ip_addr[12], (int)ip_addr[13], \
105 (int)ip_addr[14], (int)ip_addr[15]);
106
107 #define IPACM_LOG_IPV4_ADDR(prefix, ip_addr) \
108 IPACMDBG_H(prefix); \
109 IPACMDBG_H(" IPV4 Address %d.%d.%d.%d\n", \
110 (unsigned char)(ip_addr), \
111 (unsigned char)(ip_addr >> 8), \
112 (unsigned char)(ip_addr >> 16) , \
113 (unsigned char)(ip_addr >> 24));
114
115 /* Opens a netlink socket*/
ipa_nl_open_socket(ipa_nl_sk_info_t * sk_info,int protocol,unsigned int grps)116 static int ipa_nl_open_socket
117 (
118 ipa_nl_sk_info_t *sk_info,
119 int protocol,
120 unsigned int grps
121 )
122 {
123 int *p_sk_fd;
124 int buf_size = 6669999, sendbuff=0, res;
125 struct sockaddr_nl *p_sk_addr_loc;
126 socklen_t optlen;
127
128 p_sk_fd = &(sk_info->sk_fd);
129 p_sk_addr_loc = &(sk_info->sk_addr_loc);
130
131 /* Open netlink socket for specified protocol */
132 if((*p_sk_fd = socket(AF_NETLINK, SOCK_RAW, protocol)) < 0)
133 {
134 IPACMERR("cannot open netlink socket\n");
135 return IPACM_FAILURE;
136 }
137
138 optlen = sizeof(sendbuff);
139 res = getsockopt(*p_sk_fd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);
140
141 if(res == -1) {
142 IPACMDBG("Error getsockopt one");
143 } else {
144 IPACMDBG("orignal send buffer size = %d\n", sendbuff);
145 }
146 IPACMDBG("sets the send buffer to %d\n", buf_size);
147 if (setsockopt(*p_sk_fd, SOL_SOCKET, SO_RCVBUF, &buf_size, sizeof(int)) == -1) {
148 IPACMERR("Error setting socket opts\n");
149 }
150
151 /* Initialize socket addresses to null */
152 memset(p_sk_addr_loc, 0, sizeof(struct sockaddr_nl));
153
154 /* Populate local socket address using specified groups */
155 p_sk_addr_loc->nl_family = AF_NETLINK;
156 p_sk_addr_loc->nl_pid = getpid();
157 p_sk_addr_loc->nl_groups = grps;
158
159 /* Bind socket to the local address, i.e. specified groups. This ensures
160 that multicast messages for these groups are delivered over this
161 socket. */
162
163 if(bind(*p_sk_fd,
164 (struct sockaddr *)p_sk_addr_loc,
165 sizeof(struct sockaddr_nl)) < 0)
166 {
167 IPACMERR("Socket bind failed\n");
168 return IPACM_FAILURE;
169 }
170
171 return IPACM_SUCCESS;
172 }
173
174 /* Add fd to fdmap array and store read handler function ptr (up to MAX_NUM_OF_FD).*/
ipa_nl_addfd_map(ipa_nl_sk_fd_set_info_t * info,int fd,ipa_sock_thrd_fd_read_f read_f)175 static int ipa_nl_addfd_map
176 (
177 ipa_nl_sk_fd_set_info_t *info,
178 int fd,
179 ipa_sock_thrd_fd_read_f read_f
180 )
181 {
182 if(info->num_fd < MAX_NUM_OF_FD)
183 {
184 FD_SET(fd, &info->fdset);
185
186 /* Add fd to fdmap array and store read handler function ptr */
187 info->sk_fds[info->num_fd].sk_fd = fd;
188 info->sk_fds[info->num_fd].read_func = read_f;
189
190 /* Increment number of fds stored in fdmap */
191 info->num_fd++;
192 if(info->max_fd < fd)
193 info->max_fd = fd;
194 }
195 else
196 {
197 return IPACM_FAILURE;
198 }
199
200 return IPACM_SUCCESS;
201 }
202
203 /* start socket listener */
ipa_nl_sock_listener_start(ipa_nl_sk_fd_set_info_t * sk_fd_set)204 static int ipa_nl_sock_listener_start
205 (
206 ipa_nl_sk_fd_set_info_t *sk_fd_set
207 )
208 {
209 int i, ret;
210
211 while(true)
212 {
213 for(i = 0; i < sk_fd_set->num_fd; i++ )
214 {
215 FD_SET(sk_fd_set->sk_fds[i].sk_fd, &(sk_fd_set->fdset));
216 }
217
218 if((ret = select(sk_fd_set->max_fd + 1, &(sk_fd_set->fdset), NULL, NULL, NULL)) < 0)
219 {
220 IPACMERR("ipa_nl select failed\n");
221 }
222 else
223 {
224 for(i = 0; i < sk_fd_set->num_fd; i++)
225 {
226
227 if(FD_ISSET(sk_fd_set->sk_fds[i].sk_fd, &(sk_fd_set->fdset)))
228 {
229
230 if(sk_fd_set->sk_fds[i].read_func)
231 {
232 if(IPACM_SUCCESS != ((sk_fd_set->sk_fds[i].read_func)(sk_fd_set->sk_fds[i].sk_fd)))
233 {
234 IPACMERR("Error on read callback[%d] fd=%d\n",
235 i,
236 sk_fd_set->sk_fds[i].sk_fd);
237 }
238 FD_CLR(sk_fd_set->sk_fds[i].sk_fd, &(sk_fd_set->fdset));
239 }
240 else
241 {
242 IPACMERR("No read function\n");
243 }
244 }
245
246 } /* end of for loop*/
247 } /* end of else */
248 } /* end of while */
249
250 return IPACM_SUCCESS;
251 }
252
253 /* allocate memory for ipa_nl__msg */
ipa_nl_alloc_msg(uint32_t msglen)254 static struct msghdr* ipa_nl_alloc_msg
255 (
256 uint32_t msglen
257 )
258 {
259 unsigned char *buf = NULL;
260 struct sockaddr_nl *nladdr = NULL;
261 struct iovec *iov = NULL;
262 struct msghdr *msgh = NULL;
263
264 if(IPA_NL_MSG_MAX_LEN < msglen)
265 {
266 IPACMERR("Netlink message exceeds maximum length\n");
267 return NULL;
268 }
269
270 msgh = (struct msghdr *)malloc(sizeof(struct msghdr));
271 if(msgh == NULL)
272 {
273 IPACMERR("Failed malloc for msghdr\n");
274 return NULL;
275 }
276
277 nladdr = (struct sockaddr_nl *)malloc(sizeof(struct sockaddr_nl));
278 if(nladdr == NULL)
279 {
280 IPACMERR("Failed malloc for sockaddr\n");
281 free(msgh);
282 return NULL;
283 }
284
285 iov = (struct iovec *)malloc(sizeof(struct iovec));
286 if(iov == NULL)
287 {
288 PERROR("Failed malloc for iovec");
289 free(nladdr);
290 free(msgh);
291 return NULL;
292 }
293
294 buf = (unsigned char *)malloc(msglen);
295 if(buf == NULL)
296 {
297 IPACMERR("Failed malloc for mglen\n");
298 free(iov);
299 free(nladdr);
300 free(msgh);
301 return NULL;
302 }
303
304 memset(nladdr, 0, sizeof(struct sockaddr_nl));
305 nladdr->nl_family = AF_NETLINK;
306
307 memset(msgh, 0x0, sizeof(struct msghdr));
308 msgh->msg_name = nladdr;
309 msgh->msg_namelen = sizeof(struct sockaddr_nl);
310 msgh->msg_iov = iov;
311 msgh->msg_iovlen = 1;
312
313 memset(iov, 0x0, sizeof(struct iovec));
314 iov->iov_base = buf;
315 iov->iov_len = msglen;
316
317 return msgh;
318 }
319
320 /* release IPA message */
ipa_nl_release_msg(struct msghdr * msgh)321 static void ipa_nl_release_msg
322 (
323 struct msghdr *msgh
324 )
325 {
326 unsigned char *buf = NULL;
327 struct sockaddr_nl *nladdr = NULL;
328 struct iovec *iov = NULL;
329
330 if(NULL == msgh)
331 {
332 return;
333 }
334
335 nladdr = (struct sockaddr_nl *)msgh->msg_name;
336 iov = msgh->msg_iov;
337 if(msgh->msg_iov)
338 {
339 buf = (unsigned char *)msgh->msg_iov->iov_base;
340 }
341
342 if(buf)
343 {
344 free(buf);
345 }
346 if(iov)
347 {
348 free(iov);
349 }
350 if(nladdr)
351 {
352 free(nladdr);
353 }
354 if(msgh)
355 {
356 free(msgh);
357 }
358 return;
359 }
360
361 /* receive and process nl message */
ipa_nl_recv(int fd,struct msghdr ** msg_pptr,unsigned int * msglen_ptr)362 static int ipa_nl_recv
363 (
364 int fd,
365 struct msghdr **msg_pptr,
366 unsigned int *msglen_ptr
367 )
368 {
369 struct msghdr *msgh = NULL;
370 int rmsgl;
371
372 msgh = ipa_nl_alloc_msg(IPA_NL_MSG_MAX_LEN);
373 if(NULL == msgh)
374 {
375 IPACMERR("Failed to allocate NL message\n");
376 goto error;
377 }
378
379
380 /* Receive message over the socket */
381 rmsgl = recvmsg(fd, msgh, 0);
382
383 /* Verify that something was read */
384 if(rmsgl <= 0)
385 {
386 PERROR("NL recv error");
387 goto error;
388 }
389
390 /* Verify that NL address length in the received message is expected value */
391 if(sizeof(struct sockaddr_nl) != msgh->msg_namelen)
392 {
393 IPACMERR("rcvd msg with namelen != sizeof sockaddr_nl\n");
394 goto error;
395 }
396
397 /* Verify that message was not truncated. This should not occur */
398 if(msgh->msg_flags & MSG_TRUNC)
399 {
400 IPACMERR("Rcvd msg truncated!\n");
401 goto error;
402 }
403
404 *msg_pptr = msgh;
405 *msglen_ptr = rmsgl;
406
407 return IPACM_SUCCESS;
408
409 /* An error occurred while receiving the message. Free all memory before
410 returning. */
411 error:
412 ipa_nl_release_msg(msgh);
413 *msg_pptr = NULL;
414 *msglen_ptr = 0;
415
416 return IPACM_FAILURE;
417 }
418
419 /* decode the rtm netlink message */
ipa_nl_decode_rtm_link(const char * buffer,unsigned int buflen,ipa_nl_link_info_t * link_info)420 static int ipa_nl_decode_rtm_link
421 (
422 const char *buffer,
423 unsigned int buflen,
424 ipa_nl_link_info_t *link_info
425 )
426 {
427 struct rtattr;
428 /* NL message header */
429 struct nlmsghdr *nlh = (struct nlmsghdr *)buffer;
430
431 /* Extract the header data */
432 link_info->metainfo = *(struct ifinfomsg *)NLMSG_DATA(nlh);
433 buflen -= sizeof(struct nlmsghdr);
434
435 return IPACM_SUCCESS;
436 }
437
438 /* Decode kernel address message parameters from Netlink attribute TLVs. */
ipa_nl_decode_rtm_addr(const char * buffer,unsigned int buflen,ipa_nl_addr_info_t * addr_info)439 static int ipa_nl_decode_rtm_addr
440 (
441 const char *buffer,
442 unsigned int buflen,
443 ipa_nl_addr_info_t *addr_info
444 )
445 {
446 struct nlmsghdr *nlh = (struct nlmsghdr *)buffer; /* NL message header */
447 struct rtattr *rtah = NULL;
448
449 /* Extract the header data */
450 addr_info->metainfo = *((struct ifaddrmsg *)NLMSG_DATA(nlh));
451 buflen -= sizeof(struct nlmsghdr);
452
453 /* Extract the available attributes */
454 addr_info->attr_info.param_mask = IPA_NLA_PARAM_NONE;
455
456 rtah = IFA_RTA(NLMSG_DATA(nlh));
457
458 while(RTA_OK(rtah, buflen))
459 {
460 switch(rtah->rta_type)
461 {
462
463 case IFA_ADDRESS:
464 addr_info->attr_info.prefix_addr.ss_family = addr_info->metainfo.ifa_family;
465 IPACM_NL_COPY_ADDR( addr_info, prefix_addr );
466 addr_info->attr_info.param_mask |= IPA_NLA_PARAM_PREFIXADDR;
467 break;
468 default:
469 break;
470
471 }
472 /* Advance to next attribute */
473 rtah = RTA_NEXT(rtah, buflen);
474 }
475
476 return IPACM_SUCCESS;
477 }
478
479 /* Decode kernel neighbor message parameters from Netlink attribute TLVs. */
ipa_nl_decode_rtm_neigh(const char * buffer,unsigned int buflen,ipa_nl_neigh_info_t * neigh_info)480 static int ipa_nl_decode_rtm_neigh
481 (
482 const char *buffer,
483 unsigned int buflen,
484 ipa_nl_neigh_info_t *neigh_info
485 )
486 {
487 struct nlmsghdr *nlh = (struct nlmsghdr *)buffer; /* NL message header */
488 struct rtattr *rtah = NULL;
489
490 /* Extract the header data */
491 neigh_info->metainfo = *((struct ndmsg *)NLMSG_DATA(nlh));
492 buflen -= sizeof(struct nlmsghdr);
493
494 /* Extract the available attributes */
495 neigh_info->attr_info.param_mask = IPA_NLA_PARAM_NONE;
496
497 rtah = NDA_RTA(NLMSG_DATA(nlh));
498
499 while(RTA_OK(rtah, buflen))
500 {
501 switch(rtah->rta_type)
502 {
503
504 case NDA_DST:
505 neigh_info->attr_info.local_addr.ss_family = neigh_info->metainfo.ndm_family;
506 IPACM_NL_COPY_ADDR( neigh_info, local_addr );
507 break;
508
509 case NDA_LLADDR:
510 memcpy(neigh_info->attr_info.lladdr_hwaddr.sa_data,
511 RTA_DATA(rtah),
512 sizeof(neigh_info->attr_info.lladdr_hwaddr.sa_data));
513 break;
514
515 default:
516 break;
517
518 }
519
520 /* Advance to next attribute */
521 rtah = RTA_NEXT(rtah, buflen);
522 }
523
524 return IPACM_SUCCESS;
525 }
526
527 /* Decode kernel route message parameters from Netlink attribute TLVs. */
ipa_nl_decode_rtm_route(const char * buffer,unsigned int buflen,ipa_nl_route_info_t * route_info)528 static int ipa_nl_decode_rtm_route
529 (
530 const char *buffer,
531 unsigned int buflen,
532 ipa_nl_route_info_t *route_info
533 )
534 {
535 struct nlmsghdr *nlh = (struct nlmsghdr *)buffer; /* NL message header */
536 struct rtattr *rtah = NULL;
537
538 /* Extract the header data */
539 route_info->metainfo = *((struct rtmsg *)NLMSG_DATA(nlh));
540 buflen -= sizeof(struct nlmsghdr);
541
542 route_info->attr_info.param_mask = IPA_RTA_PARAM_NONE;
543 rtah = RTM_RTA(NLMSG_DATA(nlh));
544
545 while(RTA_OK(rtah, buflen))
546 {
547 switch(rtah->rta_type)
548 {
549
550 case RTA_DST:
551 route_info->attr_info.dst_addr.ss_family = route_info->metainfo.rtm_family;
552 IPACM_NL_COPY_ADDR( route_info, dst_addr );
553 route_info->attr_info.param_mask |= IPA_RTA_PARAM_DST;
554 break;
555
556 case RTA_SRC:
557 route_info->attr_info.src_addr.ss_family = route_info->metainfo.rtm_family;
558 IPACM_NL_COPY_ADDR( route_info, src_addr );
559 route_info->attr_info.param_mask |= IPA_RTA_PARAM_SRC;
560 break;
561
562 case RTA_GATEWAY:
563 route_info->attr_info.gateway_addr.ss_family = route_info->metainfo.rtm_family;
564 IPACM_NL_COPY_ADDR( route_info, gateway_addr );
565 route_info->attr_info.param_mask |= IPA_RTA_PARAM_GATEWAY;
566 break;
567
568 case RTA_IIF:
569 memcpy(&route_info->attr_info.iif_index,
570 RTA_DATA(rtah),
571 sizeof(route_info->attr_info.iif_index));
572 route_info->attr_info.param_mask |= IPA_RTA_PARAM_IIF;
573 break;
574
575 case RTA_OIF:
576 memcpy(&route_info->attr_info.oif_index,
577 RTA_DATA(rtah),
578 sizeof(route_info->attr_info.oif_index));
579 route_info->attr_info.param_mask |= IPA_RTA_PARAM_OIF;
580 break;
581
582 case RTA_PRIORITY:
583 memcpy(&route_info->attr_info.priority,
584 RTA_DATA(rtah),
585 sizeof(route_info->attr_info.priority));
586 route_info->attr_info.param_mask |= IPA_RTA_PARAM_PRIORITY;
587 break;
588
589 default:
590 break;
591
592 }
593
594 /* Advance to next attribute */
595 rtah = RTA_NEXT(rtah, buflen);
596 }
597
598 return IPACM_SUCCESS;
599 }
600
601 /* decode the ipa nl-message */
ipa_nl_decode_nlmsg(const char * buffer,unsigned int buflen,ipa_nl_msg_t * msg_ptr)602 static int ipa_nl_decode_nlmsg
603 (
604 const char *buffer,
605 unsigned int buflen,
606 ipa_nl_msg_t *msg_ptr
607 )
608 {
609 char dev_name[IF_NAME_LEN]={0};
610 int ret_val, mask_index, mask_value_v6;
611 struct nlmsghdr *nlh = (struct nlmsghdr *)buffer;
612
613 uint32_t if_ipv4_addr =0, if_ipipv4_addr_mask =0, temp =0, if_ipv4_addr_gw =0;
614
615 ipacm_cmd_q_data evt_data;
616 ipacm_event_data_all *data_all;
617 ipacm_event_data_fid *data_fid;
618 ipacm_event_data_addr *data_addr;
619
620
621 while(NLMSG_OK(nlh, buflen))
622 {
623 memset(dev_name,0,IF_NAME_LEN);
624 IPACMDBG("Received msg:%d from netlink\n", nlh->nlmsg_type)
625 switch(nlh->nlmsg_type)
626 {
627 case RTM_NEWLINK:
628 msg_ptr->type = nlh->nlmsg_type;
629 msg_ptr->link_event = true;
630 if(IPACM_SUCCESS != ipa_nl_decode_rtm_link(buffer, buflen, &(msg_ptr->nl_link_info)))
631 {
632 IPACMERR("Failed to decode rtm link message\n");
633 return IPACM_FAILURE;
634 }
635 else
636 {
637 IPACMDBG("Got RTM_NEWLINK with below values\n");
638 IPACMDBG("RTM_NEWLINK, ifi_change:%d\n", msg_ptr->nl_link_info.metainfo.ifi_change);
639 IPACMDBG("RTM_NEWLINK, ifi_flags:%d\n", msg_ptr->nl_link_info.metainfo.ifi_flags);
640 IPACMDBG("RTM_NEWLINK, ifi_index:%d\n", msg_ptr->nl_link_info.metainfo.ifi_index);
641 IPACMDBG("RTM_NEWLINK, family:%d\n", msg_ptr->nl_link_info.metainfo.ifi_family);
642 /* RTM_NEWLINK event with AF_BRIDGE family should be ignored in Android
643 but this should be processed in case of MDM for Ehernet interface.
644 */
645 #ifdef FEATURE_IPA_ANDROID
646 if (msg_ptr->nl_link_info.metainfo.ifi_family == AF_BRIDGE)
647 {
648 IPACMERR(" ignore this RTM_NEWLINK msg \n");
649 return IPACM_SUCCESS;
650 }
651 #endif
652 if(IFF_UP & msg_ptr->nl_link_info.metainfo.ifi_change)
653 {
654 IPACMDBG("GOT useful newlink event\n");
655 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_link_info.metainfo.ifi_index);
656 if(ret_val != IPACM_SUCCESS)
657 {
658 IPACMERR("Error while getting interface name\n");
659 return IPACM_FAILURE;
660 }
661
662 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
663 if(data_fid == NULL)
664 {
665 IPACMERR("unable to allocate memory for event data_fid\n");
666 return IPACM_FAILURE;
667 }
668 data_fid->if_index = msg_ptr->nl_link_info.metainfo.ifi_index;
669
670 if(msg_ptr->nl_link_info.metainfo.ifi_flags & IFF_UP)
671 {
672 IPACMDBG_H("Interface %s bring up with IP-family: %d \n", dev_name, msg_ptr->nl_link_info.metainfo.ifi_family);
673 /* post link up to command queue */
674 evt_data.event = IPA_LINK_UP_EVENT;
675 IPACMDBG_H("Posting IPA_LINK_UP_EVENT with if index: %d\n",
676 msg_ptr->nl_link_info.metainfo.ifi_index);
677 }
678 else
679 {
680 IPACMDBG_H("Interface %s bring down with IP-family: %d \n", dev_name, msg_ptr->nl_link_info.metainfo.ifi_family);
681 /* post link down to command queue */
682 evt_data.event = IPA_LINK_DOWN_EVENT;
683 IPACMDBG_H("Posting IPA_LINK_DOWN_EVENT with if index: %d\n",
684 data_fid->if_index);
685 }
686 evt_data.evt_data = data_fid;
687 IPACM_EvtDispatcher::PostEvt(&evt_data);
688 }
689 /* Andorid platform will use events from usb-driver directly */
690 #ifndef FEATURE_IPA_ANDROID
691 /* Add IPACM support for ECM plug-in/plug_out */
692 /*--------------------------------------------------------------------------
693 Check if the interface is running.If its a RTM_NEWLINK and the interface
694 is running then it means that its a link up event
695 ---------------------------------------------------------------------------*/
696 if((msg_ptr->nl_link_info.metainfo.ifi_flags & IFF_RUNNING) &&
697 (msg_ptr->nl_link_info.metainfo.ifi_flags & IFF_LOWER_UP))
698 {
699
700 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
701 if(data_fid == NULL)
702 {
703 IPACMERR("unable to allocate memory for event data_fid\n");
704 return IPACM_FAILURE;
705 }
706 data_fid->if_index = msg_ptr->nl_link_info.metainfo.ifi_index;
707
708 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_link_info.metainfo.ifi_index);
709 if(ret_val != IPACM_SUCCESS)
710 {
711 IPACMERR("Error while getting interface name\n");
712 return IPACM_FAILURE;
713 }
714 IPACMDBG_H("Got a usb link_up event (Interface %s, %d) \n", dev_name, msg_ptr->nl_link_info.metainfo.ifi_index);
715 /* We don't expect change in iff_flags for rmnet_data interfaces. */
716 if (!strncmp(dev_name,"rmnet_data",strlen("rmnet_data")))
717 {
718 IPACMERR("Don't expect iff_flags change for rmnet_data interface. IGNORE\n");
719 return IPACM_FAILURE;
720 }
721
722 /*--------------------------------------------------------------------------
723 Post LAN iface (ECM) link up event
724 ---------------------------------------------------------------------------*/
725 evt_data.event = IPA_USB_LINK_UP_EVENT;
726 evt_data.evt_data = data_fid;
727 IPACMDBG_H("Posting usb IPA_USB_LINK_UP_EVENT with if index: %d\n",
728 data_fid->if_index);
729 IPACM_EvtDispatcher::PostEvt(&evt_data);
730 }
731 else if (!(msg_ptr->nl_link_info.metainfo.ifi_flags & IFF_LOWER_UP))
732 {
733 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
734 if(data_fid == NULL)
735 {
736 IPACMERR("unable to allocate memory for event data_fid\n");
737 return IPACM_FAILURE;
738 }
739 data_fid->if_index = msg_ptr->nl_link_info.metainfo.ifi_index;
740
741 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_link_info.metainfo.ifi_index);
742 if(ret_val != IPACM_SUCCESS)
743 {
744 IPACMERR("Error while getting interface name\n");
745 return IPACM_FAILURE;
746 }
747 IPACMDBG_H("Got a usb link_down event (Interface %s) \n", dev_name);
748
749 /*--------------------------------------------------------------------------
750 Post LAN iface (ECM) link down event
751 ---------------------------------------------------------------------------*/
752 evt_data.event = IPA_LINK_DOWN_EVENT;
753 evt_data.evt_data = data_fid;
754 IPACMDBG_H("Posting usb IPA_LINK_DOWN_EVENT with if index: %d\n",
755 data_fid->if_index);
756 IPACM_EvtDispatcher::PostEvt(&evt_data);
757 }
758 #endif /* not defined(FEATURE_IPA_ANDROID)*/
759 }
760 break;
761
762 case RTM_DELLINK:
763 IPACMDBG("\n GOT dellink event\n");
764 msg_ptr->type = nlh->nlmsg_type;
765 msg_ptr->link_event = true;
766 IPACMDBG("entering rtm decode\n");
767 if(IPACM_SUCCESS != ipa_nl_decode_rtm_link(buffer, buflen, &(msg_ptr->nl_link_info)))
768 {
769 IPACMERR("Failed to decode rtm link message\n");
770 return IPACM_FAILURE;
771 }
772 else
773 {
774 IPACMDBG("Got RTM_DELLINK with below values\n");
775 IPACMDBG("RTM_DELLINK, ifi_change:%d\n", msg_ptr->nl_link_info.metainfo.ifi_change);
776 IPACMDBG("RTM_DELLINK, ifi_flags:%d\n", msg_ptr->nl_link_info.metainfo.ifi_flags);
777 IPACMDBG("RTM_DELLINK, ifi_index:%d\n", msg_ptr->nl_link_info.metainfo.ifi_index);
778 IPACMDBG("RTM_DELLINK, family:%d\n", msg_ptr->nl_link_info.metainfo.ifi_family);
779 /* RTM_NEWLINK event with AF_BRIDGE family should be ignored in Android
780 but this should be processed in case of MDM for Ehernet interface.
781 */
782 #ifdef FEATURE_IPA_ANDROID
783 if (msg_ptr->nl_link_info.metainfo.ifi_family == AF_BRIDGE)
784 {
785 IPACMERR(" ignore this RTM_DELLINK msg \n");
786 return IPACM_SUCCESS;
787 }
788 #endif
789 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_link_info.metainfo.ifi_index);
790 if(ret_val != IPACM_SUCCESS)
791 {
792 IPACMERR("Error while getting interface name\n");
793 return IPACM_FAILURE;
794 }
795 IPACMDBG("Interface %s bring down \n", dev_name);
796
797 /* post link down to command queue */
798 evt_data.event = IPA_LINK_DOWN_EVENT;
799 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
800 if(data_fid == NULL)
801 {
802 IPACMERR("unable to allocate memory for event data_fid\n");
803 return IPACM_FAILURE;
804 }
805
806 data_fid->if_index = msg_ptr->nl_link_info.metainfo.ifi_index;
807
808 IPACMDBG_H("posting IPA_LINK_DOWN_EVENT with if idnex:%d\n",
809 data_fid->if_index);
810 evt_data.evt_data = data_fid;
811 IPACM_EvtDispatcher::PostEvt(&evt_data);
812 /* finish command queue */
813 }
814 break;
815
816 case RTM_NEWADDR:
817 IPACMDBG("\n GOT RTM_NEWADDR event\n");
818 if(IPACM_SUCCESS != ipa_nl_decode_rtm_addr(buffer, buflen, &(msg_ptr->nl_addr_info)))
819 {
820 IPACMERR("Failed to decode rtm addr message\n");
821 return IPACM_FAILURE;
822 }
823 else
824 {
825 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_addr_info.metainfo.ifa_index);
826 if(ret_val != IPACM_SUCCESS)
827 {
828 IPACMERR("Error while getting interface name\n");
829 }
830 IPACMDBG("Interface %s \n", dev_name);
831
832 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
833 if(data_addr == NULL)
834 {
835 IPACMERR("unable to allocate memory for event data_addr\n");
836 return IPACM_FAILURE;
837 }
838
839 if(AF_INET6 == msg_ptr->nl_addr_info.attr_info.prefix_addr.ss_family)
840 {
841 data_addr->iptype = IPA_IP_v6;
842 IPACM_NL_REPORT_ADDR( "IFA_ADDRESS:", msg_ptr->nl_addr_info.attr_info.prefix_addr );
843 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_addr_info.attr_info.prefix_addr);
844 data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
845 data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
846 data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
847 data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
848 }
849 else
850 {
851 data_addr->iptype = IPA_IP_v4;
852 IPACM_NL_REPORT_ADDR( "IFA_ADDRESS:", msg_ptr->nl_addr_info.attr_info.prefix_addr );
853 IPACM_EVENT_COPY_ADDR_v4( data_addr->ipv4_addr, msg_ptr->nl_addr_info.attr_info.prefix_addr);
854 data_addr->ipv4_addr = ntohl(data_addr->ipv4_addr);
855
856 }
857
858 evt_data.event = IPA_ADDR_ADD_EVENT;
859 data_addr->if_index = msg_ptr->nl_addr_info.metainfo.ifa_index;
860 strlcpy(data_addr->iface_name, dev_name, sizeof(data_addr->iface_name));
861 if(AF_INET6 == msg_ptr->nl_addr_info.attr_info.prefix_addr.ss_family)
862 {
863 IPACMDBG("Posting IPA_ADDR_ADD_EVENT with if index:%d, ipv6 addr:0x%x:%x:%x:%x\n",
864 data_addr->if_index,
865 data_addr->ipv6_addr[0],
866 data_addr->ipv6_addr[1],
867 data_addr->ipv6_addr[2],
868 data_addr->ipv6_addr[3]);
869 }
870 else
871 {
872 IPACMDBG("Posting IPA_ADDR_ADD_EVENT with if index:%d, ipv4 addr:0x%x\n",
873 data_addr->if_index,
874 data_addr->ipv4_addr);
875 }
876 evt_data.evt_data = data_addr;
877 IPACM_EvtDispatcher::PostEvt(&evt_data);
878 }
879 break;
880
881 case RTM_NEWROUTE:
882
883 if(IPACM_SUCCESS != ipa_nl_decode_rtm_route(buffer, buflen, &(msg_ptr->nl_route_info)))
884 {
885 IPACMERR("Failed to decode rtm route message\n");
886 return IPACM_FAILURE;
887 }
888
889 IPACMDBG("In case RTM_NEWROUTE\n");
890 IPACMDBG("rtm_type: %d\n", msg_ptr->nl_route_info.metainfo.rtm_type);
891 IPACMDBG("protocol: %d\n", msg_ptr->nl_route_info.metainfo.rtm_protocol);
892 IPACMDBG("rtm_scope: %d\n", msg_ptr->nl_route_info.metainfo.rtm_scope);
893 IPACMDBG("rtm_table: %d\n", msg_ptr->nl_route_info.metainfo.rtm_table);
894 IPACMDBG("rtm_family: %d\n", msg_ptr->nl_route_info.metainfo.rtm_family);
895 IPACMDBG("param_mask: 0x%x\n", msg_ptr->nl_route_info.attr_info.param_mask);
896
897 /* take care of route add default route & uniroute */
898 if((msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) &&
899 ((msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_BOOT) ||
900 (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_RA)) &&
901 (msg_ptr->nl_route_info.metainfo.rtm_scope == RT_SCOPE_UNIVERSE) &&
902 (msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN))
903 {
904 IPACMDBG("\n GOT RTM_NEWROUTE event\n");
905
906 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_DST)
907 {
908 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index);
909 if(ret_val != IPACM_SUCCESS)
910 {
911 IPACMERR("Error while getting interface name\n");
912 return IPACM_FAILURE;
913 }
914
915 IPACM_NL_REPORT_ADDR( "route add -host", msg_ptr->nl_route_info.attr_info.dst_addr );
916 IPACM_NL_REPORT_ADDR( "gw", msg_ptr->nl_route_info.attr_info.gateway_addr );
917 IPACMDBG("dev %s\n",dev_name );
918 /* insert to command queue */
919 IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
920 temp = (-1);
921
922 evt_data.event = IPA_ROUTE_ADD_EVENT;
923 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
924 if(data_addr == NULL)
925 {
926 IPACMERR("unable to allocate memory for event data_addr\n");
927 return IPACM_FAILURE;
928 }
929
930 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
931 data_addr->iptype = IPA_IP_v4;
932 data_addr->ipv4_addr = ntohl(if_ipv4_addr);
933 data_addr->ipv4_addr_mask = ntohl(if_ipipv4_addr_mask);
934
935 IPACMDBG("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv4 address 0x%x, mask:0x%x\n",
936 data_addr->if_index,
937 data_addr->ipv4_addr,
938 data_addr->ipv4_addr_mask);
939 evt_data.evt_data = data_addr;
940 IPACM_EvtDispatcher::PostEvt(&evt_data);
941 /* finish command queue */
942
943 }
944 else
945 {
946 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index);
947 if(ret_val != IPACM_SUCCESS)
948 {
949 IPACMERR("Error while getting interface name\n");
950 return IPACM_FAILURE;
951 }
952
953 if(AF_INET6 == msg_ptr->nl_route_info.metainfo.rtm_family)
954 {
955 /* insert to command queue */
956 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
957 if(data_addr == NULL)
958 {
959 IPACMERR("unable to allocate memory for event data_addr\n");
960 return IPACM_FAILURE;
961 }
962
963 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_PRIORITY)
964 {
965 IPACMDBG_H("ip -6 route add default dev %s metric %d\n",
966 dev_name,
967 msg_ptr->nl_route_info.attr_info.priority);
968 }
969 else
970 {
971 IPACMDBG_H("ip -6 route add default dev %s\n", dev_name);
972 }
973
974 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
975 data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
976 data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
977 data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
978 data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
979
980 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
981 data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]);
982 data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]);
983 data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]);
984 data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]);
985
986 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_gw, msg_ptr->nl_route_info.attr_info.gateway_addr);
987 data_addr->ipv6_addr_gw[0] = ntohl(data_addr->ipv6_addr_gw[0]);
988 data_addr->ipv6_addr_gw[1] = ntohl(data_addr->ipv6_addr_gw[1]);
989 data_addr->ipv6_addr_gw[2] = ntohl(data_addr->ipv6_addr_gw[2]);
990 data_addr->ipv6_addr_gw[3] = ntohl(data_addr->ipv6_addr_gw[3]);
991 IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_route_info.attr_info.gateway_addr);
992
993 evt_data.event = IPA_ROUTE_ADD_EVENT;
994 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
995 data_addr->iptype = IPA_IP_v6;
996
997 IPACMDBG("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv6 address\n",
998 data_addr->if_index);
999 evt_data.evt_data = data_addr;
1000 IPACM_EvtDispatcher::PostEvt(&evt_data);
1001 /* finish command queue */
1002
1003 }
1004 else
1005 {
1006 IPACM_NL_REPORT_ADDR( "route add default gw \n", msg_ptr->nl_route_info.attr_info.gateway_addr );
1007 IPACMDBG_H("dev %s \n", dev_name);
1008 IPACM_NL_REPORT_ADDR( "dstIP:", msg_ptr->nl_route_info.attr_info.dst_addr );
1009
1010 /* insert to command queue */
1011 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
1012 if(data_addr == NULL)
1013 {
1014 IPACMERR("unable to allocate memory for event data_addr\n");
1015 return IPACM_FAILURE;
1016 }
1017
1018 IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1019 IPACM_EVENT_COPY_ADDR_v4( if_ipipv4_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
1020 IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr_gw, msg_ptr->nl_route_info.attr_info.gateway_addr);
1021
1022 evt_data.event = IPA_ROUTE_ADD_EVENT;
1023 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
1024 data_addr->iptype = IPA_IP_v4;
1025 data_addr->ipv4_addr = ntohl(if_ipv4_addr);
1026 data_addr->ipv4_addr_gw = ntohl(if_ipv4_addr_gw);
1027 data_addr->ipv4_addr_mask = ntohl(if_ipipv4_addr_mask);
1028
1029 IPACMDBG_H("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv4 addr:0x%x, mask: 0x%x and gw: 0x%x\n",
1030 data_addr->if_index,
1031 data_addr->ipv4_addr,
1032 data_addr->ipv4_addr_mask,
1033 data_addr->ipv4_addr_gw);
1034 evt_data.evt_data = data_addr;
1035 IPACM_EvtDispatcher::PostEvt(&evt_data);
1036 /* finish command queue */
1037 }
1038 }
1039 }
1040
1041 /* ipv6 routing table */
1042 if((AF_INET6 == msg_ptr->nl_route_info.metainfo.rtm_family) &&
1043 (msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) &&
1044 (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_KERNEL) &&
1045 (msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN))
1046 {
1047 IPACMDBG("\n GOT valid v6-RTM_NEWROUTE event\n");
1048 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index);
1049 if(ret_val != IPACM_SUCCESS)
1050 {
1051 IPACMERR("Error while getting interface name\n");
1052 return IPACM_FAILURE;
1053 }
1054
1055 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_DST)
1056 {
1057 IPACM_NL_REPORT_ADDR( "Route ADD DST:", msg_ptr->nl_route_info.attr_info.dst_addr );
1058 IPACMDBG("%d, metric %d, dev %s\n",
1059 msg_ptr->nl_route_info.metainfo.rtm_dst_len,
1060 msg_ptr->nl_route_info.attr_info.priority,
1061 dev_name);
1062
1063 /* insert to command queue */
1064 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
1065 if(data_addr == NULL)
1066 {
1067 IPACMERR("unable to allocate memory for event data_addr\n");
1068 return IPACM_FAILURE;
1069 }
1070
1071 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1072
1073 data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
1074 data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
1075 data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
1076 data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
1077
1078 mask_value_v6 = msg_ptr->nl_route_info.metainfo.rtm_dst_len;
1079 for(mask_index = 0; mask_index < 4; mask_index++)
1080 {
1081 if(mask_value_v6 >= 32)
1082 {
1083 mask_v6(32, &data_addr->ipv6_addr_mask[mask_index]);
1084 mask_value_v6 -= 32;
1085 }
1086 else
1087 {
1088 mask_v6(mask_value_v6, &data_addr->ipv6_addr_mask[mask_index]);
1089 mask_value_v6 = 0;
1090 }
1091 }
1092
1093 IPACMDBG("ADD IPV6 MASK %d: %08x:%08x:%08x:%08x \n",
1094 msg_ptr->nl_route_info.metainfo.rtm_dst_len,
1095 data_addr->ipv6_addr_mask[0],
1096 data_addr->ipv6_addr_mask[1],
1097 data_addr->ipv6_addr_mask[2],
1098 data_addr->ipv6_addr_mask[3]);
1099
1100 data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]);
1101 data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]);
1102 data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]);
1103 data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]);
1104
1105 evt_data.event = IPA_ROUTE_ADD_EVENT;
1106 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
1107 data_addr->iptype = IPA_IP_v6;
1108
1109 IPACMDBG("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv6 addr\n",
1110 data_addr->if_index);
1111 evt_data.evt_data = data_addr;
1112 IPACM_EvtDispatcher::PostEvt(&evt_data);
1113 /* finish command queue */
1114 }
1115 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_GATEWAY)
1116 {
1117 IPACM_NL_REPORT_ADDR( "Route ADD ::/0 Next Hop:", msg_ptr->nl_route_info.attr_info.gateway_addr );
1118 IPACMDBG(" metric %d, dev %s\n",
1119 msg_ptr->nl_route_info.attr_info.priority,
1120 dev_name);
1121
1122 /* insert to command queue */
1123 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
1124 if(data_addr == NULL)
1125 {
1126 IPACMERR("unable to allocate memory for event data_addr\n");
1127 return IPACM_FAILURE;
1128 }
1129
1130 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1131
1132 data_addr->ipv6_addr[0]=ntohl(data_addr->ipv6_addr[0]);
1133 data_addr->ipv6_addr[1]=ntohl(data_addr->ipv6_addr[1]);
1134 data_addr->ipv6_addr[2]=ntohl(data_addr->ipv6_addr[2]);
1135 data_addr->ipv6_addr[3]=ntohl(data_addr->ipv6_addr[3]);
1136
1137 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
1138
1139 data_addr->ipv6_addr_mask[0]=ntohl(data_addr->ipv6_addr_mask[0]);
1140 data_addr->ipv6_addr_mask[1]=ntohl(data_addr->ipv6_addr_mask[1]);
1141 data_addr->ipv6_addr_mask[2]=ntohl(data_addr->ipv6_addr_mask[2]);
1142 data_addr->ipv6_addr_mask[3]=ntohl(data_addr->ipv6_addr_mask[3]);
1143
1144 evt_data.event = IPA_ROUTE_ADD_EVENT;
1145 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
1146 data_addr->iptype = IPA_IP_v6;
1147
1148 IPACMDBG("posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv6 address\n",
1149 data_addr->if_index);
1150 evt_data.evt_data = data_addr;
1151 IPACM_EvtDispatcher::PostEvt(&evt_data);
1152 /* finish command queue */
1153 }
1154 }
1155 break;
1156
1157 case RTM_DELROUTE:
1158 if(IPACM_SUCCESS != ipa_nl_decode_rtm_route(buffer, buflen, &(msg_ptr->nl_route_info)))
1159 {
1160 IPACMERR("Failed to decode rtm route message\n");
1161 return IPACM_FAILURE;
1162 }
1163 /* take care of route delete of default route & uniroute */
1164 if((msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) &&
1165 ((msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_BOOT) ||
1166 (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_RA)) &&
1167 (msg_ptr->nl_route_info.metainfo.rtm_scope == 0) &&
1168 (msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN))
1169 {
1170
1171 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_DST)
1172 {
1173 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index);
1174 if(ret_val != IPACM_SUCCESS)
1175 {
1176 IPACMERR("Error while getting interface name\n");
1177 return IPACM_FAILURE;
1178 }
1179 IPACM_NL_REPORT_ADDR( "route del -host ", msg_ptr->nl_route_info.attr_info.dst_addr);
1180 IPACM_NL_REPORT_ADDR( " gw ", msg_ptr->nl_route_info.attr_info.gateway_addr);
1181 IPACMDBG("dev %s\n", dev_name);
1182
1183 /* insert to command queue */
1184 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
1185 if(data_addr == NULL)
1186 {
1187 IPACMERR("unable to allocate memory for event data_addr\n");
1188 return IPACM_FAILURE;
1189 }
1190 IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1191 temp = (-1);
1192 if_ipipv4_addr_mask = ntohl(temp);
1193
1194 evt_data.event = IPA_ROUTE_DEL_EVENT;
1195 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
1196 data_addr->iptype = IPA_IP_v4;
1197 data_addr->ipv4_addr = ntohl(if_ipv4_addr);
1198 data_addr->ipv4_addr_mask = ntohl(if_ipipv4_addr_mask);
1199
1200 IPACMDBG_H("Posting event IPA_ROUTE_DEL_EVENT with if index:%d, ipv4 address 0x%x, mask:0x%x\n",
1201 data_addr->if_index,
1202 data_addr->ipv4_addr,
1203 data_addr->ipv4_addr_mask);
1204 evt_data.evt_data = data_addr;
1205 IPACM_EvtDispatcher::PostEvt(&evt_data);
1206 /* finish command queue */
1207 }
1208 else
1209 {
1210 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index);
1211 if(ret_val != IPACM_SUCCESS)
1212 {
1213 IPACMERR("Error while getting interface name\n");
1214 return IPACM_FAILURE;
1215 }
1216
1217 /* insert to command queue */
1218 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
1219 if(data_addr == NULL)
1220 {
1221 IPACMERR("unable to allocate memory for event data_addr\n");
1222 return IPACM_FAILURE;
1223 }
1224
1225 if(AF_INET6 == msg_ptr->nl_route_info.metainfo.rtm_family)
1226 {
1227 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_PRIORITY)
1228 {
1229 IPACMDBG("ip -6 route del default dev %s metric %d\n",
1230 dev_name,
1231 msg_ptr->nl_route_info.attr_info.priority);
1232 }
1233 else
1234 {
1235 IPACMDBG("ip -6 route del default dev %s\n", dev_name);
1236 }
1237 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1238 data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
1239 data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
1240 data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
1241 data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
1242
1243 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
1244 data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]);
1245 data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]);
1246 data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]);
1247 data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]);
1248
1249 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_gw, msg_ptr->nl_route_info.attr_info.gateway_addr);
1250 data_addr->ipv6_addr_gw[0] = ntohl(data_addr->ipv6_addr_gw[0]);
1251 data_addr->ipv6_addr_gw[1] = ntohl(data_addr->ipv6_addr_gw[1]);
1252 data_addr->ipv6_addr_gw[2] = ntohl(data_addr->ipv6_addr_gw[2]);
1253 data_addr->ipv6_addr_gw[3] = ntohl(data_addr->ipv6_addr_gw[3]);
1254 IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_route_info.attr_info.gateway_addr);
1255 data_addr->iptype = IPA_IP_v6;
1256 }
1257 else
1258 {
1259 IPACM_NL_REPORT_ADDR( "route del default gw", msg_ptr->nl_route_info.attr_info.gateway_addr);
1260 IPACMDBG("dev %s\n", dev_name);
1261
1262 IPACM_EVENT_COPY_ADDR_v4( data_addr->ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1263 data_addr->ipv4_addr = ntohl(data_addr->ipv4_addr);
1264
1265 IPACM_EVENT_COPY_ADDR_v4( data_addr->ipv4_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
1266 data_addr->ipv4_addr_mask = ntohl(data_addr->ipv4_addr_mask);
1267
1268 data_addr->iptype = IPA_IP_v4;
1269 }
1270
1271 evt_data.event = IPA_ROUTE_DEL_EVENT;
1272 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
1273
1274 IPACMDBG_H("Posting IPA_ROUTE_DEL_EVENT with if index:%d\n",
1275 data_addr->if_index);
1276 evt_data.evt_data = data_addr;
1277 IPACM_EvtDispatcher::PostEvt(&evt_data);
1278 /* finish command queue */
1279 }
1280 }
1281
1282 /* ipv6 routing table */
1283 if((AF_INET6 == msg_ptr->nl_route_info.metainfo.rtm_family) &&
1284 (msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) &&
1285 (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_KERNEL) &&
1286 (msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN))
1287 {
1288 IPACMDBG("\n GOT valid v6-RTM_DELROUTE event\n");
1289 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index);
1290 if(ret_val != IPACM_SUCCESS)
1291 {
1292 IPACMERR("Error while getting interface name");
1293 return IPACM_FAILURE;
1294 }
1295
1296 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_DST)
1297 {
1298 IPACM_NL_REPORT_ADDR( "DEL", msg_ptr->nl_route_info.attr_info.dst_addr);
1299 IPACMDBG("/%d, metric %d, dev %s\n",
1300 msg_ptr->nl_route_info.metainfo.rtm_dst_len,
1301 msg_ptr->nl_route_info.attr_info.priority,
1302 dev_name);
1303
1304 /* insert to command queue */
1305 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
1306 if(data_addr == NULL)
1307 {
1308 IPACMERR("unable to allocate memory for event data_addr\n");
1309 return IPACM_FAILURE;
1310 }
1311
1312 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1313
1314 data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
1315 data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
1316 data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
1317 data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
1318
1319 mask_value_v6 = msg_ptr->nl_route_info.metainfo.rtm_dst_len;
1320 for(mask_index = 0; mask_index < 4; mask_index++)
1321 {
1322 IPACMDBG("%dst %d \n",
1323 mask_index,
1324 mask_value_v6);
1325 if(mask_value_v6 >= 32)
1326 {
1327 mask_v6(32, &data_addr->ipv6_addr_mask[mask_index]);
1328 mask_value_v6 -= 32;
1329 IPACMDBG("%dst: %08x \n",
1330 mask_index,
1331 data_addr->ipv6_addr_mask[mask_index]);
1332 }
1333 else
1334 {
1335 mask_v6(mask_value_v6, data_addr->ipv6_addr_mask);
1336 mask_value_v6 = 0;
1337 IPACMDBG("%dst: %08x \n",
1338 mask_index,
1339 data_addr->ipv6_addr_mask[mask_index]);
1340 }
1341 }
1342
1343 IPACMDBG("DEL IPV6 MASK 0st: %08x ",
1344 data_addr->ipv6_addr_mask[0]);
1345 IPACMDBG("1st: %08x ",
1346 data_addr->ipv6_addr_mask[1]);
1347 IPACMDBG("2st: %08x ",
1348 data_addr->ipv6_addr_mask[2]);
1349 IPACMDBG("3st: %08x \n",
1350 data_addr->ipv6_addr_mask[3]);
1351
1352 data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]);
1353 data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]);
1354 data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]);
1355 data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]);
1356
1357 evt_data.event = IPA_ROUTE_DEL_EVENT;
1358 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
1359 data_addr->iptype = IPA_IP_v6;
1360
1361 IPACMDBG_H("posting event IPA_ROUTE_DEL_EVENT with if index:%d, ipv4 address\n",
1362 data_addr->if_index);
1363 evt_data.evt_data = data_addr;
1364 IPACM_EvtDispatcher::PostEvt(&evt_data);
1365 /* finish command queue */
1366 }
1367 }
1368 break;
1369
1370 case RTM_NEWNEIGH:
1371 if(IPACM_SUCCESS != ipa_nl_decode_rtm_neigh(buffer, buflen, &(msg_ptr->nl_neigh_info)))
1372 {
1373 IPACMERR("Failed to decode rtm neighbor message\n");
1374 return IPACM_FAILURE;
1375 }
1376
1377 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_neigh_info.metainfo.ndm_ifindex);
1378 if(ret_val != IPACM_SUCCESS)
1379 {
1380 IPACMERR("Error while getting interface index\n");
1381 return IPACM_FAILURE;
1382 }
1383 else
1384 {
1385 IPACMDBG("\n GOT RTM_NEWNEIGH event (%s) ip %d\n",dev_name,msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family);
1386 }
1387
1388 /* insert to command queue */
1389 data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
1390 if(data_all == NULL)
1391 {
1392 IPACMERR("unable to allocate memory for event data_all\n");
1393 return IPACM_FAILURE;
1394 }
1395
1396 memset(data_all, 0, sizeof(ipacm_event_data_all));
1397 if(msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET6)
1398 {
1399 IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr);
1400 IPACM_EVENT_COPY_ADDR_v6( data_all->ipv6_addr, msg_ptr->nl_neigh_info.attr_info.local_addr);
1401
1402 data_all->ipv6_addr[0]=ntohl(data_all->ipv6_addr[0]);
1403 data_all->ipv6_addr[1]=ntohl(data_all->ipv6_addr[1]);
1404 data_all->ipv6_addr[2]=ntohl(data_all->ipv6_addr[2]);
1405 data_all->ipv6_addr[3]=ntohl(data_all->ipv6_addr[3]);
1406 data_all->iptype = IPA_IP_v6;
1407 }
1408 else if (msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET)
1409 {
1410 IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr);
1411 IPACM_EVENT_COPY_ADDR_v4( data_all->ipv4_addr, msg_ptr->nl_neigh_info.attr_info.local_addr);
1412 data_all->ipv4_addr = ntohl(data_all->ipv4_addr);
1413 data_all->iptype = IPA_IP_v4;
1414 }
1415 else
1416 {
1417 data_all->iptype = IPA_IP_v6;
1418 }
1419
1420 IPACMDBG("NDA_LLADDR:MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1421 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[0],
1422 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[1],
1423 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[2],
1424 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[3],
1425 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[4],
1426 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[5]);
1427
1428
1429 memcpy(data_all->mac_addr,
1430 msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr.sa_data,
1431 sizeof(data_all->mac_addr));
1432 data_all->if_index = msg_ptr->nl_neigh_info.metainfo.ndm_ifindex;
1433 strlcpy(data_all->iface_name, dev_name, sizeof(data_all->iface_name));
1434 /* Add support to replace src-mac as bridge0 mac */
1435 if((msg_ptr->nl_neigh_info.metainfo.ndm_family == AF_BRIDGE) &&
1436 (msg_ptr->nl_neigh_info.metainfo.ndm_state == NUD_PERMANENT))
1437 {
1438 /* Posting IPA_BRIDGE_LINK_UP_EVENT event */
1439 evt_data.event = IPA_BRIDGE_LINK_UP_EVENT;
1440 IPACMDBG_H("posting IPA_BRIDGE_LINK_UP_EVENT (%s):index:%d \n",
1441 dev_name,
1442 data_all->if_index);
1443 }
1444 else
1445 {
1446 /* Posting new_neigh events for all LAN/WAN clients */
1447 evt_data.event = IPA_NEW_NEIGH_EVENT;
1448 IPACMDBG_H("posting IPA_NEW_NEIGH_EVENT (%s):index:%d ip-family: %d\n",
1449 dev_name,
1450 data_all->if_index,
1451 msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family);
1452 }
1453 evt_data.evt_data = data_all;
1454 IPACM_EvtDispatcher::PostEvt(&evt_data);
1455 /* finish command queue */
1456 break;
1457
1458 case RTM_DELNEIGH:
1459 if(IPACM_SUCCESS != ipa_nl_decode_rtm_neigh(buffer, buflen, &(msg_ptr->nl_neigh_info)))
1460 {
1461 IPACMERR("Failed to decode rtm neighbor message\n");
1462 return IPACM_FAILURE;
1463 }
1464
1465 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_neigh_info.metainfo.ndm_ifindex);
1466 if(ret_val != IPACM_SUCCESS)
1467 {
1468 IPACMERR("Error while getting interface index\n");
1469 return IPACM_FAILURE;
1470 }
1471 else
1472 {
1473 IPACMDBG("\n GOT RTM_DELNEIGH event (%s) ip %d\n",dev_name,msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family);
1474 }
1475
1476 /* insert to command queue */
1477 data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
1478 if(data_all == NULL)
1479 {
1480 IPACMERR("unable to allocate memory for event data_all\n");
1481 return IPACM_FAILURE;
1482 }
1483
1484 memset(data_all, 0, sizeof(ipacm_event_data_all));
1485 if(msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET6)
1486 {
1487 IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr);
1488 IPACM_EVENT_COPY_ADDR_v6( data_all->ipv6_addr, msg_ptr->nl_neigh_info.attr_info.local_addr);
1489
1490 data_all->ipv6_addr[0] = ntohl(data_all->ipv6_addr[0]);
1491 data_all->ipv6_addr[1] = ntohl(data_all->ipv6_addr[1]);
1492 data_all->ipv6_addr[2] = ntohl(data_all->ipv6_addr[2]);
1493 data_all->ipv6_addr[3] = ntohl(data_all->ipv6_addr[3]);
1494 data_all->iptype = IPA_IP_v6;
1495 }
1496 else if (msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET)
1497 {
1498 IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr);
1499 IPACM_EVENT_COPY_ADDR_v4( data_all->ipv4_addr, msg_ptr->nl_neigh_info.attr_info.local_addr);
1500 data_all->ipv4_addr = ntohl(data_all->ipv4_addr);
1501 data_all->iptype = IPA_IP_v4;
1502 }
1503 else
1504 {
1505 data_all->iptype = IPA_IP_v6;
1506 }
1507
1508 IPACMDBG("NDA_LLADDR:MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1509 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[0],
1510 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[1],
1511 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[2],
1512 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[3],
1513 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[4],
1514 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[5]);
1515
1516 memcpy(data_all->mac_addr,
1517 msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr.sa_data,
1518 sizeof(data_all->mac_addr));
1519 evt_data.event = IPA_DEL_NEIGH_EVENT;
1520 data_all->if_index = msg_ptr->nl_neigh_info.metainfo.ndm_ifindex;
1521
1522 IPACMDBG_H("posting IPA_DEL_NEIGH_EVENT (%s):index:%d ip-family: %d\n",
1523 dev_name,
1524 data_all->if_index,
1525 msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family);
1526 evt_data.evt_data = data_all;
1527 IPACM_EvtDispatcher::PostEvt(&evt_data);
1528 /* finish command queue */
1529 break;
1530
1531 default:
1532 IPACMDBG(" ignore NL event %d!!!\n ", nlh->nlmsg_type);
1533 break;
1534
1535 }
1536 nlh = NLMSG_NEXT(nlh, buflen);
1537 }
1538
1539 return IPACM_SUCCESS;
1540 }
1541
1542
1543 /* Virtual function registered to receive incoming messages over the NETLINK routing socket*/
ipa_nl_recv_msg(int fd)1544 int ipa_nl_recv_msg(int fd)
1545 {
1546 struct msghdr *msghdr = NULL;
1547 struct iovec *iov = NULL;
1548 unsigned int msglen = 0;
1549 ipa_nl_msg_t *nlmsg = NULL;
1550
1551 nlmsg = (ipa_nl_msg_t *)malloc(sizeof(ipa_nl_msg_t));
1552 if(NULL == nlmsg)
1553 {
1554 IPACMERR("Failed alloc of nlmsg \n");
1555 goto error;
1556 }
1557 else
1558 {
1559 if(IPACM_SUCCESS != ipa_nl_recv(fd, &msghdr, &msglen))
1560 {
1561 IPACMERR("Failed to receive nl message \n");
1562 goto error;
1563 }
1564
1565 if(msghdr== NULL)
1566 {
1567 IPACMERR(" failed to get msghdr\n");
1568 goto error;
1569 }
1570
1571 iov = msghdr->msg_iov;
1572
1573 memset(nlmsg, 0, sizeof(ipa_nl_msg_t));
1574 if(IPACM_SUCCESS != ipa_nl_decode_nlmsg((char *)iov->iov_base, msglen, nlmsg))
1575 {
1576 IPACMERR("Failed to decode nl message \n");
1577 goto error;
1578 }
1579 /* Release NetLink message buffer */
1580 if(msghdr)
1581 {
1582 ipa_nl_release_msg(msghdr);
1583 }
1584 if(nlmsg)
1585 {
1586 free(nlmsg);
1587 }
1588 }
1589
1590 return IPACM_SUCCESS;
1591
1592 error:
1593 if(msghdr)
1594 {
1595 ipa_nl_release_msg(msghdr);
1596 }
1597 if(nlmsg)
1598 {
1599 free(nlmsg);
1600 }
1601
1602 return IPACM_FAILURE;
1603 }
1604
1605 /* get ipa interface name */
ipa_get_if_name(char * if_name,int if_index)1606 int ipa_get_if_name
1607 (
1608 char *if_name,
1609 int if_index
1610 )
1611 {
1612 int fd;
1613 struct ifreq ifr;
1614
1615 if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1616 {
1617 IPACMERR("get interface name socket create failed \n");
1618 return IPACM_FAILURE;
1619 }
1620
1621 memset(&ifr, 0, sizeof(struct ifreq));
1622 ifr.ifr_ifindex = if_index;
1623 IPACMDBG("Interface index %d\n", if_index);
1624
1625 if(ioctl(fd, SIOCGIFNAME, &ifr) < 0)
1626 {
1627 IPACMERR("call_ioctl_on_dev: ioctl failed:\n");
1628 close(fd);
1629 return IPACM_FAILURE;
1630 }
1631
1632 (void)strlcpy(if_name, ifr.ifr_name, sizeof(ifr.ifr_name));
1633 IPACMDBG("interface name %s\n", ifr.ifr_name);
1634 close(fd);
1635
1636 return IPACM_SUCCESS;
1637 }
1638
1639 /* Initialization routine for listener on NetLink sockets interface */
ipa_nl_listener_init(unsigned int nl_type,unsigned int nl_groups,ipa_nl_sk_fd_set_info_t * sk_fdset,ipa_sock_thrd_fd_read_f read_f)1640 int ipa_nl_listener_init
1641 (
1642 unsigned int nl_type,
1643 unsigned int nl_groups,
1644 ipa_nl_sk_fd_set_info_t *sk_fdset,
1645 ipa_sock_thrd_fd_read_f read_f
1646 )
1647 {
1648 ipa_nl_sk_info_t sk_info;
1649 int ret_val;
1650
1651 memset(&sk_info, 0, sizeof(ipa_nl_sk_info_t));
1652 IPACMDBG_H("Entering IPA NL listener init\n");
1653
1654 if(ipa_nl_open_socket(&sk_info, nl_type, nl_groups) == IPACM_SUCCESS)
1655 {
1656 IPACMDBG_H("IPA Open netlink socket succeeds\n");
1657 }
1658 else
1659 {
1660 IPACMERR("Netlink socket open failed\n");
1661 return IPACM_FAILURE;
1662 }
1663
1664 /* Add NETLINK socket to the list of sockets that the listener
1665 thread should listen on. */
1666
1667 if(ipa_nl_addfd_map(sk_fdset, sk_info.sk_fd, read_f) != IPACM_SUCCESS)
1668 {
1669 IPACMERR("cannot add nl routing sock for reading\n");
1670 close(sk_info.sk_fd);
1671 return IPACM_FAILURE;
1672 }
1673
1674 /* Start the socket listener thread */
1675 ret_val = ipa_nl_sock_listener_start(sk_fdset);
1676
1677 if(ret_val != IPACM_SUCCESS)
1678 {
1679 IPACMERR("Failed to start NL listener\n");
1680 }
1681
1682 return IPACM_SUCCESS;
1683 }
1684
1685 /* find the newroute subnet mask */
find_mask(int ip_v4_last,int * mask_value)1686 int find_mask(int ip_v4_last, int *mask_value)
1687 {
1688
1689 switch(ip_v4_last)
1690 {
1691
1692 case 3:
1693 *mask_value = 252;
1694 return IPACM_SUCCESS;
1695 break;
1696
1697 case 7:
1698 *mask_value = 248;
1699 return IPACM_SUCCESS;
1700 break;
1701
1702 case 15:
1703 *mask_value = 240;
1704 return IPACM_SUCCESS;
1705 break;
1706
1707 case 31:
1708 *mask_value = 224;
1709 return IPACM_SUCCESS;
1710 break;
1711
1712 case 63:
1713 *mask_value = 192;
1714 return IPACM_SUCCESS;
1715 break;
1716
1717 case 127:
1718 *mask_value = 128;
1719 return IPACM_SUCCESS;
1720 break;
1721
1722 case 255:
1723 *mask_value = 0;
1724 return IPACM_SUCCESS;
1725 break;
1726
1727 default:
1728 return IPACM_FAILURE;
1729 break;
1730
1731 }
1732 }
1733
1734 /* map mask value for ipv6 */
mask_v6(int index,uint32_t * mask)1735 int mask_v6(int index, uint32_t *mask)
1736 {
1737 switch(index)
1738 {
1739
1740 case 0:
1741 *mask = 0x00000000;
1742 return IPACM_SUCCESS;
1743 break;
1744 case 4:
1745 *mask = 0xf0000000;
1746 return IPACM_SUCCESS;
1747 break;
1748 case 8:
1749 *mask = 0xff000000;
1750 return IPACM_SUCCESS;
1751 break;
1752 case 12:
1753 *mask = 0xfff00000;
1754 return IPACM_SUCCESS;
1755 break;
1756 case 16:
1757 *mask = 0xffff0000;
1758 return IPACM_SUCCESS;
1759 break;
1760 case 20:
1761 *mask = 0xfffff000;
1762 return IPACM_SUCCESS;
1763 break;
1764 case 24:
1765 *mask = 0xffffff00;
1766 return IPACM_SUCCESS;
1767 break;
1768 case 28:
1769 *mask = 0xfffffff0;
1770 return IPACM_SUCCESS;
1771 break;
1772 case 32:
1773 *mask = 0xffffffff;
1774 return IPACM_SUCCESS;
1775 break;
1776 default:
1777 return IPACM_FAILURE;
1778 break;
1779
1780 }
1781 }
1782
1783
1784