1 /*
2 Copyright (c) 2013, 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
690 /* Add IPACM support for ECM plug-in/plug_out */
691 /*--------------------------------------------------------------------------
692 Check if the interface is running.If its a RTM_NEWLINK and the interface
693 is running then it means that its a link up event
694 ---------------------------------------------------------------------------*/
695 if((msg_ptr->nl_link_info.metainfo.ifi_flags & IFF_RUNNING) &&
696 (msg_ptr->nl_link_info.metainfo.ifi_flags & IFF_LOWER_UP))
697 {
698
699 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
700 if(data_fid == NULL)
701 {
702 IPACMERR("unable to allocate memory for event data_fid\n");
703 return IPACM_FAILURE;
704 }
705 data_fid->if_index = msg_ptr->nl_link_info.metainfo.ifi_index;
706
707 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_link_info.metainfo.ifi_index);
708 if(ret_val != IPACM_SUCCESS)
709 {
710 IPACMERR("Error while getting interface name\n");
711 return IPACM_FAILURE;
712 }
713 IPACMDBG("Got a usb link_up event (Interface %s, %d) \n", dev_name, msg_ptr->nl_link_info.metainfo.ifi_index);
714
715 /*--------------------------------------------------------------------------
716 Post LAN iface (ECM) link up event
717 ---------------------------------------------------------------------------*/
718 evt_data.event = IPA_USB_LINK_UP_EVENT;
719 evt_data.evt_data = data_fid;
720 IPACMDBG_H("Posting usb IPA_LINK_UP_EVENT with if index: %d\n",
721 data_fid->if_index);
722 IPACM_EvtDispatcher::PostEvt(&evt_data);
723 }
724 else if (!(msg_ptr->nl_link_info.metainfo.ifi_flags & IFF_LOWER_UP))
725 {
726 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
727 if(data_fid == NULL)
728 {
729 IPACMERR("unable to allocate memory for event data_fid\n");
730 return IPACM_FAILURE;
731 }
732 data_fid->if_index = msg_ptr->nl_link_info.metainfo.ifi_index;
733
734 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_link_info.metainfo.ifi_index);
735 if(ret_val != IPACM_SUCCESS)
736 {
737 IPACMERR("Error while getting interface name\n");
738 return IPACM_FAILURE;
739 }
740 IPACMDBG_H("Got a usb link_down event (Interface %s) \n", dev_name);
741
742 /*--------------------------------------------------------------------------
743 Post LAN iface (ECM) link down event
744 ---------------------------------------------------------------------------*/
745 evt_data.event = IPA_LINK_DOWN_EVENT;
746 evt_data.evt_data = data_fid;
747 IPACMDBG_H("Posting usb IPA_LINK_DOWN_EVENT with if index: %d\n",
748 data_fid->if_index);
749 IPACM_EvtDispatcher::PostEvt(&evt_data);
750 }
751 }
752 break;
753
754 case RTM_DELLINK:
755 IPACMDBG("\n GOT dellink event\n");
756 msg_ptr->type = nlh->nlmsg_type;
757 msg_ptr->link_event = true;
758 IPACMDBG("entering rtm decode\n");
759 if(IPACM_SUCCESS != ipa_nl_decode_rtm_link(buffer, buflen, &(msg_ptr->nl_link_info)))
760 {
761 IPACMERR("Failed to decode rtm link message\n");
762 return IPACM_FAILURE;
763 }
764 else
765 {
766 IPACMDBG("Got RTM_DELLINK with below values\n");
767 IPACMDBG("RTM_DELLINK, ifi_change:%d\n", msg_ptr->nl_link_info.metainfo.ifi_change);
768 IPACMDBG("RTM_DELLINK, ifi_flags:%d\n", msg_ptr->nl_link_info.metainfo.ifi_flags);
769 IPACMDBG("RTM_DELLINK, ifi_index:%d\n", msg_ptr->nl_link_info.metainfo.ifi_index);
770 IPACMDBG("RTM_DELLINK, family:%d\n", msg_ptr->nl_link_info.metainfo.ifi_family);
771 /* RTM_NEWLINK event with AF_BRIDGE family should be ignored in Android
772 but this should be processed in case of MDM for Ehernet interface.
773 */
774 #ifdef FEATURE_IPA_ANDROID
775 if (msg_ptr->nl_link_info.metainfo.ifi_family == AF_BRIDGE)
776 {
777 IPACMERR(" ignore this RTM_DELLINK msg \n");
778 return IPACM_SUCCESS;
779 }
780 #endif
781 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_link_info.metainfo.ifi_index);
782 if(ret_val != IPACM_SUCCESS)
783 {
784 IPACMERR("Error while getting interface name\n");
785 return IPACM_FAILURE;
786 }
787 IPACMDBG("Interface %s bring down \n", dev_name);
788
789 /* post link down to command queue */
790 evt_data.event = IPA_LINK_DOWN_EVENT;
791 data_fid = (ipacm_event_data_fid *)malloc(sizeof(ipacm_event_data_fid));
792 if(data_fid == NULL)
793 {
794 IPACMERR("unable to allocate memory for event data_fid\n");
795 return IPACM_FAILURE;
796 }
797
798 data_fid->if_index = msg_ptr->nl_link_info.metainfo.ifi_index;
799
800 IPACMDBG_H("posting IPA_LINK_DOWN_EVENT with if idnex:%d\n",
801 data_fid->if_index);
802 evt_data.evt_data = data_fid;
803 IPACM_EvtDispatcher::PostEvt(&evt_data);
804 /* finish command queue */
805 }
806 break;
807
808 case RTM_NEWADDR:
809 IPACMDBG("\n GOT RTM_NEWADDR event\n");
810 if(IPACM_SUCCESS != ipa_nl_decode_rtm_addr(buffer, buflen, &(msg_ptr->nl_addr_info)))
811 {
812 IPACMERR("Failed to decode rtm addr message\n");
813 return IPACM_FAILURE;
814 }
815 else
816 {
817 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_addr_info.metainfo.ifa_index);
818 if(ret_val != IPACM_SUCCESS)
819 {
820 IPACMERR("Error while getting interface name\n");
821 }
822 IPACMDBG("Interface %s \n", dev_name);
823
824 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
825 if(data_addr == NULL)
826 {
827 IPACMERR("unable to allocate memory for event data_addr\n");
828 return IPACM_FAILURE;
829 }
830
831 if(AF_INET6 == msg_ptr->nl_addr_info.attr_info.prefix_addr.ss_family)
832 {
833 data_addr->iptype = IPA_IP_v6;
834 IPACM_NL_REPORT_ADDR( "IFA_ADDRESS:", msg_ptr->nl_addr_info.attr_info.prefix_addr );
835 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_addr_info.attr_info.prefix_addr);
836 data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
837 data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
838 data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
839 data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
840 }
841 else
842 {
843 data_addr->iptype = IPA_IP_v4;
844 IPACM_NL_REPORT_ADDR( "IFA_ADDRESS:", msg_ptr->nl_addr_info.attr_info.prefix_addr );
845 IPACM_EVENT_COPY_ADDR_v4( data_addr->ipv4_addr, msg_ptr->nl_addr_info.attr_info.prefix_addr);
846 data_addr->ipv4_addr = ntohl(data_addr->ipv4_addr);
847
848 }
849
850 evt_data.event = IPA_ADDR_ADD_EVENT;
851 data_addr->if_index = msg_ptr->nl_addr_info.metainfo.ifa_index;
852 if(AF_INET6 == msg_ptr->nl_addr_info.attr_info.prefix_addr.ss_family)
853 {
854 IPACMDBG("Posting IPA_ADDR_ADD_EVENT with if index:%d, ipv6 addr:0x%x:%x:%x:%x\n",
855 data_addr->if_index,
856 data_addr->ipv6_addr[0],
857 data_addr->ipv6_addr[1],
858 data_addr->ipv6_addr[2],
859 data_addr->ipv6_addr[3]);
860 }
861 else
862 {
863 IPACMDBG("Posting IPA_ADDR_ADD_EVENT with if index:%d, ipv4 addr:0x%x\n",
864 data_addr->if_index,
865 data_addr->ipv4_addr);
866 }
867 evt_data.evt_data = data_addr;
868 IPACM_EvtDispatcher::PostEvt(&evt_data);
869 }
870 break;
871
872 case RTM_NEWROUTE:
873
874 if(IPACM_SUCCESS != ipa_nl_decode_rtm_route(buffer, buflen, &(msg_ptr->nl_route_info)))
875 {
876 IPACMERR("Failed to decode rtm route message\n");
877 return IPACM_FAILURE;
878 }
879
880 IPACMDBG("In case RTM_NEWROUTE\n");
881 IPACMDBG("rtm_type: %d\n", msg_ptr->nl_route_info.metainfo.rtm_type);
882 IPACMDBG("protocol: %d\n", msg_ptr->nl_route_info.metainfo.rtm_protocol);
883 IPACMDBG("rtm_scope: %d\n", msg_ptr->nl_route_info.metainfo.rtm_scope);
884 IPACMDBG("rtm_table: %d\n", msg_ptr->nl_route_info.metainfo.rtm_table);
885 IPACMDBG("rtm_family: %d\n", msg_ptr->nl_route_info.metainfo.rtm_family);
886 IPACMDBG("param_mask: 0x%x\n", msg_ptr->nl_route_info.attr_info.param_mask);
887
888 /* take care of route add default route & uniroute */
889 if((msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) &&
890 ((msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_BOOT) ||
891 (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_RA)) &&
892 (msg_ptr->nl_route_info.metainfo.rtm_scope == RT_SCOPE_UNIVERSE) &&
893 (msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN))
894 {
895 IPACMDBG("\n GOT RTM_NEWROUTE event\n");
896
897 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_DST)
898 {
899 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index);
900 if(ret_val != IPACM_SUCCESS)
901 {
902 IPACMERR("Error while getting interface name\n");
903 return IPACM_FAILURE;
904 }
905
906 IPACM_NL_REPORT_ADDR( "route add -host", msg_ptr->nl_route_info.attr_info.dst_addr );
907 IPACM_NL_REPORT_ADDR( "gw", msg_ptr->nl_route_info.attr_info.gateway_addr );
908 IPACMDBG("dev %s\n",dev_name );
909 /* insert to command queue */
910 IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
911 temp = (-1);
912
913 evt_data.event = IPA_ROUTE_ADD_EVENT;
914 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
915 if(data_addr == NULL)
916 {
917 IPACMERR("unable to allocate memory for event data_addr\n");
918 return IPACM_FAILURE;
919 }
920
921 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
922 data_addr->iptype = IPA_IP_v4;
923 data_addr->ipv4_addr = ntohl(if_ipv4_addr);
924 data_addr->ipv4_addr_mask = ntohl(if_ipipv4_addr_mask);
925
926 IPACMDBG("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv4 address 0x%x, mask:0x%x\n",
927 data_addr->if_index,
928 data_addr->ipv4_addr,
929 data_addr->ipv4_addr_mask);
930 evt_data.evt_data = data_addr;
931 IPACM_EvtDispatcher::PostEvt(&evt_data);
932 /* finish command queue */
933
934 }
935 else
936 {
937 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index);
938 if(ret_val != IPACM_SUCCESS)
939 {
940 IPACMERR("Error while getting interface name\n");
941 return IPACM_FAILURE;
942 }
943
944 if(AF_INET6 == msg_ptr->nl_route_info.metainfo.rtm_family)
945 {
946 /* insert to command queue */
947 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
948 if(data_addr == NULL)
949 {
950 IPACMERR("unable to allocate memory for event data_addr\n");
951 return IPACM_FAILURE;
952 }
953
954 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_PRIORITY)
955 {
956 IPACMDBG_H("ip -6 route add default dev %s metric %d\n",
957 dev_name,
958 msg_ptr->nl_route_info.attr_info.priority);
959 }
960 else
961 {
962 IPACMDBG_H("ip -6 route add default dev %s\n", dev_name);
963 }
964
965 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
966 data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
967 data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
968 data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
969 data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
970
971 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
972 data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]);
973 data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]);
974 data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]);
975 data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]);
976
977 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_gw, msg_ptr->nl_route_info.attr_info.gateway_addr);
978 data_addr->ipv6_addr_gw[0] = ntohl(data_addr->ipv6_addr_gw[0]);
979 data_addr->ipv6_addr_gw[1] = ntohl(data_addr->ipv6_addr_gw[1]);
980 data_addr->ipv6_addr_gw[2] = ntohl(data_addr->ipv6_addr_gw[2]);
981 data_addr->ipv6_addr_gw[3] = ntohl(data_addr->ipv6_addr_gw[3]);
982 IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_route_info.attr_info.gateway_addr);
983
984 evt_data.event = IPA_ROUTE_ADD_EVENT;
985 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
986 data_addr->iptype = IPA_IP_v6;
987
988 IPACMDBG("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv6 address\n",
989 data_addr->if_index);
990 evt_data.evt_data = data_addr;
991 IPACM_EvtDispatcher::PostEvt(&evt_data);
992 /* finish command queue */
993
994 }
995 else
996 {
997 IPACM_NL_REPORT_ADDR( "route add default gw \n", msg_ptr->nl_route_info.attr_info.gateway_addr );
998 IPACMDBG_H("dev %s \n", dev_name);
999 IPACM_NL_REPORT_ADDR( "dstIP:", msg_ptr->nl_route_info.attr_info.dst_addr );
1000
1001 /* insert to command queue */
1002 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
1003 if(data_addr == NULL)
1004 {
1005 IPACMERR("unable to allocate memory for event data_addr\n");
1006 return IPACM_FAILURE;
1007 }
1008
1009 IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1010 IPACM_EVENT_COPY_ADDR_v4( if_ipipv4_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
1011 IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr_gw, msg_ptr->nl_route_info.attr_info.gateway_addr);
1012
1013 evt_data.event = IPA_ROUTE_ADD_EVENT;
1014 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
1015 data_addr->iptype = IPA_IP_v4;
1016 data_addr->ipv4_addr = ntohl(if_ipv4_addr);
1017 data_addr->ipv4_addr_gw = ntohl(if_ipv4_addr_gw);
1018 data_addr->ipv4_addr_mask = ntohl(if_ipipv4_addr_mask);
1019
1020 IPACMDBG_H("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv4 addr:0x%x, mask: 0x%x and gw: 0x%x\n",
1021 data_addr->if_index,
1022 data_addr->ipv4_addr,
1023 data_addr->ipv4_addr_mask,
1024 data_addr->ipv4_addr_gw);
1025 evt_data.evt_data = data_addr;
1026 IPACM_EvtDispatcher::PostEvt(&evt_data);
1027 /* finish command queue */
1028 }
1029 }
1030 }
1031
1032 /* ipv6 routing table */
1033 if((AF_INET6 == msg_ptr->nl_route_info.metainfo.rtm_family) &&
1034 (msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) &&
1035 (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_KERNEL) &&
1036 (msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN))
1037 {
1038 IPACMDBG("\n GOT valid v6-RTM_NEWROUTE event\n");
1039 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index);
1040 if(ret_val != IPACM_SUCCESS)
1041 {
1042 IPACMERR("Error while getting interface name\n");
1043 return IPACM_FAILURE;
1044 }
1045
1046 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_DST)
1047 {
1048 IPACM_NL_REPORT_ADDR( "Route ADD DST:", msg_ptr->nl_route_info.attr_info.dst_addr );
1049 IPACMDBG("%d, metric %d, dev %s\n",
1050 msg_ptr->nl_route_info.metainfo.rtm_dst_len,
1051 msg_ptr->nl_route_info.attr_info.priority,
1052 dev_name);
1053
1054 /* insert to command queue */
1055 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
1056 if(data_addr == NULL)
1057 {
1058 IPACMERR("unable to allocate memory for event data_addr\n");
1059 return IPACM_FAILURE;
1060 }
1061
1062 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1063
1064 data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
1065 data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
1066 data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
1067 data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
1068
1069 mask_value_v6 = msg_ptr->nl_route_info.metainfo.rtm_dst_len;
1070 for(mask_index = 0; mask_index < 4; mask_index++)
1071 {
1072 if(mask_value_v6 >= 32)
1073 {
1074 mask_v6(32, &data_addr->ipv6_addr_mask[mask_index]);
1075 mask_value_v6 -= 32;
1076 }
1077 else
1078 {
1079 mask_v6(mask_value_v6, &data_addr->ipv6_addr_mask[mask_index]);
1080 mask_value_v6 = 0;
1081 }
1082 }
1083
1084 IPACMDBG("ADD IPV6 MASK %d: %08x:%08x:%08x:%08x \n",
1085 msg_ptr->nl_route_info.metainfo.rtm_dst_len,
1086 data_addr->ipv6_addr_mask[0],
1087 data_addr->ipv6_addr_mask[1],
1088 data_addr->ipv6_addr_mask[2],
1089 data_addr->ipv6_addr_mask[3]);
1090
1091 data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]);
1092 data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]);
1093 data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]);
1094 data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]);
1095
1096 evt_data.event = IPA_ROUTE_ADD_EVENT;
1097 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
1098 data_addr->iptype = IPA_IP_v6;
1099
1100 IPACMDBG("Posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv6 addr\n",
1101 data_addr->if_index);
1102 evt_data.evt_data = data_addr;
1103 IPACM_EvtDispatcher::PostEvt(&evt_data);
1104 /* finish command queue */
1105 }
1106 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_GATEWAY)
1107 {
1108 IPACM_NL_REPORT_ADDR( "Route ADD ::/0 Next Hop:", msg_ptr->nl_route_info.attr_info.gateway_addr );
1109 IPACMDBG(" metric %d, dev %s\n",
1110 msg_ptr->nl_route_info.attr_info.priority,
1111 dev_name);
1112
1113 /* insert to command queue */
1114 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
1115 if(data_addr == NULL)
1116 {
1117 IPACMERR("unable to allocate memory for event data_addr\n");
1118 return IPACM_FAILURE;
1119 }
1120
1121 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1122
1123 data_addr->ipv6_addr[0]=ntohl(data_addr->ipv6_addr[0]);
1124 data_addr->ipv6_addr[1]=ntohl(data_addr->ipv6_addr[1]);
1125 data_addr->ipv6_addr[2]=ntohl(data_addr->ipv6_addr[2]);
1126 data_addr->ipv6_addr[3]=ntohl(data_addr->ipv6_addr[3]);
1127
1128 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
1129
1130 data_addr->ipv6_addr_mask[0]=ntohl(data_addr->ipv6_addr_mask[0]);
1131 data_addr->ipv6_addr_mask[1]=ntohl(data_addr->ipv6_addr_mask[1]);
1132 data_addr->ipv6_addr_mask[2]=ntohl(data_addr->ipv6_addr_mask[2]);
1133 data_addr->ipv6_addr_mask[3]=ntohl(data_addr->ipv6_addr_mask[3]);
1134
1135 evt_data.event = IPA_ROUTE_ADD_EVENT;
1136 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
1137 data_addr->iptype = IPA_IP_v6;
1138
1139 IPACMDBG("posting IPA_ROUTE_ADD_EVENT with if index:%d, ipv6 address\n",
1140 data_addr->if_index);
1141 evt_data.evt_data = data_addr;
1142 IPACM_EvtDispatcher::PostEvt(&evt_data);
1143 /* finish command queue */
1144 }
1145 }
1146 break;
1147
1148 case RTM_DELROUTE:
1149 if(IPACM_SUCCESS != ipa_nl_decode_rtm_route(buffer, buflen, &(msg_ptr->nl_route_info)))
1150 {
1151 IPACMERR("Failed to decode rtm route message\n");
1152 return IPACM_FAILURE;
1153 }
1154 /* take care of route delete of default route & uniroute */
1155 if((msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) &&
1156 ((msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_BOOT) ||
1157 (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_RA)) &&
1158 (msg_ptr->nl_route_info.metainfo.rtm_scope == 0) &&
1159 (msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN))
1160 {
1161
1162 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_DST)
1163 {
1164 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index);
1165 if(ret_val != IPACM_SUCCESS)
1166 {
1167 IPACMERR("Error while getting interface name\n");
1168 return IPACM_FAILURE;
1169 }
1170 IPACM_NL_REPORT_ADDR( "route del -host ", msg_ptr->nl_route_info.attr_info.dst_addr);
1171 IPACM_NL_REPORT_ADDR( " gw ", msg_ptr->nl_route_info.attr_info.gateway_addr);
1172 IPACMDBG("dev %s\n", dev_name);
1173
1174 /* insert to command queue */
1175 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
1176 if(data_addr == NULL)
1177 {
1178 IPACMERR("unable to allocate memory for event data_addr\n");
1179 return IPACM_FAILURE;
1180 }
1181 IPACM_EVENT_COPY_ADDR_v4( if_ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1182 temp = (-1);
1183 if_ipipv4_addr_mask = ntohl(temp);
1184
1185 evt_data.event = IPA_ROUTE_DEL_EVENT;
1186 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
1187 data_addr->iptype = IPA_IP_v4;
1188 data_addr->ipv4_addr = ntohl(if_ipv4_addr);
1189 data_addr->ipv4_addr_mask = ntohl(if_ipipv4_addr_mask);
1190
1191 IPACMDBG_H("Posting event IPA_ROUTE_DEL_EVENT with if index:%d, ipv4 address 0x%x, mask:0x%x\n",
1192 data_addr->if_index,
1193 data_addr->ipv4_addr,
1194 data_addr->ipv4_addr_mask);
1195 evt_data.evt_data = data_addr;
1196 IPACM_EvtDispatcher::PostEvt(&evt_data);
1197 /* finish command queue */
1198 }
1199 else
1200 {
1201 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index);
1202 if(ret_val != IPACM_SUCCESS)
1203 {
1204 IPACMERR("Error while getting interface name\n");
1205 return IPACM_FAILURE;
1206 }
1207
1208 /* insert to command queue */
1209 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
1210 if(data_addr == NULL)
1211 {
1212 IPACMERR("unable to allocate memory for event data_addr\n");
1213 return IPACM_FAILURE;
1214 }
1215
1216 if(AF_INET6 == msg_ptr->nl_route_info.metainfo.rtm_family)
1217 {
1218 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_PRIORITY)
1219 {
1220 IPACMDBG("ip -6 route del default dev %s metric %d\n",
1221 dev_name,
1222 msg_ptr->nl_route_info.attr_info.priority);
1223 }
1224 else
1225 {
1226 IPACMDBG("ip -6 route del default dev %s\n", dev_name);
1227 }
1228 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1229 data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
1230 data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
1231 data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
1232 data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
1233
1234 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
1235 data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]);
1236 data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]);
1237 data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]);
1238 data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]);
1239
1240 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr_gw, msg_ptr->nl_route_info.attr_info.gateway_addr);
1241 data_addr->ipv6_addr_gw[0] = ntohl(data_addr->ipv6_addr_gw[0]);
1242 data_addr->ipv6_addr_gw[1] = ntohl(data_addr->ipv6_addr_gw[1]);
1243 data_addr->ipv6_addr_gw[2] = ntohl(data_addr->ipv6_addr_gw[2]);
1244 data_addr->ipv6_addr_gw[3] = ntohl(data_addr->ipv6_addr_gw[3]);
1245 IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_route_info.attr_info.gateway_addr);
1246 data_addr->iptype = IPA_IP_v6;
1247 }
1248 else
1249 {
1250 IPACM_NL_REPORT_ADDR( "route del default gw", msg_ptr->nl_route_info.attr_info.gateway_addr);
1251 IPACMDBG("dev %s\n", dev_name);
1252
1253 IPACM_EVENT_COPY_ADDR_v4( data_addr->ipv4_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1254 data_addr->ipv4_addr = ntohl(data_addr->ipv4_addr);
1255
1256 IPACM_EVENT_COPY_ADDR_v4( data_addr->ipv4_addr_mask, msg_ptr->nl_route_info.attr_info.dst_addr);
1257 data_addr->ipv4_addr_mask = ntohl(data_addr->ipv4_addr_mask);
1258
1259 data_addr->iptype = IPA_IP_v4;
1260 }
1261
1262 evt_data.event = IPA_ROUTE_DEL_EVENT;
1263 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
1264
1265 IPACMDBG_H("Posting IPA_ROUTE_DEL_EVENT with if index:%d\n",
1266 data_addr->if_index);
1267 evt_data.evt_data = data_addr;
1268 IPACM_EvtDispatcher::PostEvt(&evt_data);
1269 /* finish command queue */
1270 }
1271 }
1272
1273 /* ipv6 routing table */
1274 if((AF_INET6 == msg_ptr->nl_route_info.metainfo.rtm_family) &&
1275 (msg_ptr->nl_route_info.metainfo.rtm_type == RTN_UNICAST) &&
1276 (msg_ptr->nl_route_info.metainfo.rtm_protocol == RTPROT_KERNEL) &&
1277 (msg_ptr->nl_route_info.metainfo.rtm_table == RT_TABLE_MAIN))
1278 {
1279 IPACMDBG("\n GOT valid v6-RTM_DELROUTE event\n");
1280 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_route_info.attr_info.oif_index);
1281 if(ret_val != IPACM_SUCCESS)
1282 {
1283 IPACMERR("Error while getting interface name");
1284 return IPACM_FAILURE;
1285 }
1286
1287 if(msg_ptr->nl_route_info.attr_info.param_mask & IPA_RTA_PARAM_DST)
1288 {
1289 IPACM_NL_REPORT_ADDR( "DEL", msg_ptr->nl_route_info.attr_info.dst_addr);
1290 IPACMDBG("/%d, metric %d, dev %s\n",
1291 msg_ptr->nl_route_info.metainfo.rtm_dst_len,
1292 msg_ptr->nl_route_info.attr_info.priority,
1293 dev_name);
1294
1295 /* insert to command queue */
1296 data_addr = (ipacm_event_data_addr *)malloc(sizeof(ipacm_event_data_addr));
1297 if(data_addr == NULL)
1298 {
1299 IPACMERR("unable to allocate memory for event data_addr\n");
1300 return IPACM_FAILURE;
1301 }
1302
1303 IPACM_EVENT_COPY_ADDR_v6( data_addr->ipv6_addr, msg_ptr->nl_route_info.attr_info.dst_addr);
1304
1305 data_addr->ipv6_addr[0] = ntohl(data_addr->ipv6_addr[0]);
1306 data_addr->ipv6_addr[1] = ntohl(data_addr->ipv6_addr[1]);
1307 data_addr->ipv6_addr[2] = ntohl(data_addr->ipv6_addr[2]);
1308 data_addr->ipv6_addr[3] = ntohl(data_addr->ipv6_addr[3]);
1309
1310 mask_value_v6 = msg_ptr->nl_route_info.metainfo.rtm_dst_len;
1311 for(mask_index = 0; mask_index < 4; mask_index++)
1312 {
1313 IPACMDBG("%dst %d \n",
1314 mask_index,
1315 mask_value_v6);
1316 if(mask_value_v6 >= 32)
1317 {
1318 mask_v6(32, &data_addr->ipv6_addr_mask[mask_index]);
1319 mask_value_v6 -= 32;
1320 IPACMDBG("%dst: %08x \n",
1321 mask_index,
1322 data_addr->ipv6_addr_mask[mask_index]);
1323 }
1324 else
1325 {
1326 mask_v6(mask_value_v6, data_addr->ipv6_addr_mask);
1327 mask_value_v6 = 0;
1328 IPACMDBG("%dst: %08x \n",
1329 mask_index,
1330 data_addr->ipv6_addr_mask[mask_index]);
1331 }
1332 }
1333
1334 IPACMDBG("DEL IPV6 MASK 0st: %08x ",
1335 data_addr->ipv6_addr_mask[0]);
1336 IPACMDBG("1st: %08x ",
1337 data_addr->ipv6_addr_mask[1]);
1338 IPACMDBG("2st: %08x ",
1339 data_addr->ipv6_addr_mask[2]);
1340 IPACMDBG("3st: %08x \n",
1341 data_addr->ipv6_addr_mask[3]);
1342
1343 data_addr->ipv6_addr_mask[0] = ntohl(data_addr->ipv6_addr_mask[0]);
1344 data_addr->ipv6_addr_mask[1] = ntohl(data_addr->ipv6_addr_mask[1]);
1345 data_addr->ipv6_addr_mask[2] = ntohl(data_addr->ipv6_addr_mask[2]);
1346 data_addr->ipv6_addr_mask[3] = ntohl(data_addr->ipv6_addr_mask[3]);
1347
1348 evt_data.event = IPA_ROUTE_DEL_EVENT;
1349 data_addr->if_index = msg_ptr->nl_route_info.attr_info.oif_index;
1350 data_addr->iptype = IPA_IP_v6;
1351
1352 IPACMDBG_H("posting event IPA_ROUTE_DEL_EVENT with if index:%d, ipv4 address\n",
1353 data_addr->if_index);
1354 evt_data.evt_data = data_addr;
1355 IPACM_EvtDispatcher::PostEvt(&evt_data);
1356 /* finish command queue */
1357 }
1358 }
1359 break;
1360
1361 case RTM_NEWNEIGH:
1362 if(IPACM_SUCCESS != ipa_nl_decode_rtm_neigh(buffer, buflen, &(msg_ptr->nl_neigh_info)))
1363 {
1364 IPACMERR("Failed to decode rtm neighbor message\n");
1365 return IPACM_FAILURE;
1366 }
1367
1368 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_neigh_info.metainfo.ndm_ifindex);
1369 if(ret_val != IPACM_SUCCESS)
1370 {
1371 IPACMERR("Error while getting interface index\n");
1372 return IPACM_FAILURE;
1373 }
1374 else
1375 {
1376 IPACMDBG("\n GOT RTM_NEWNEIGH event (%s) ip %d\n",dev_name,msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family);
1377 }
1378
1379 /* insert to command queue */
1380 data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
1381 if(data_all == NULL)
1382 {
1383 IPACMERR("unable to allocate memory for event data_all\n");
1384 return IPACM_FAILURE;
1385 }
1386
1387 memset(data_all, 0, sizeof(ipacm_event_data_all));
1388 if(msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET6)
1389 {
1390 IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr);
1391 IPACM_EVENT_COPY_ADDR_v6( data_all->ipv6_addr, msg_ptr->nl_neigh_info.attr_info.local_addr);
1392
1393 data_all->ipv6_addr[0]=ntohl(data_all->ipv6_addr[0]);
1394 data_all->ipv6_addr[1]=ntohl(data_all->ipv6_addr[1]);
1395 data_all->ipv6_addr[2]=ntohl(data_all->ipv6_addr[2]);
1396 data_all->ipv6_addr[3]=ntohl(data_all->ipv6_addr[3]);
1397 data_all->iptype = IPA_IP_v6;
1398 }
1399 else if (msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET)
1400 {
1401 IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr);
1402 IPACM_EVENT_COPY_ADDR_v4( data_all->ipv4_addr, msg_ptr->nl_neigh_info.attr_info.local_addr);
1403 data_all->ipv4_addr = ntohl(data_all->ipv4_addr);
1404 data_all->iptype = IPA_IP_v4;
1405 }
1406 else
1407 {
1408 data_all->iptype = IPA_IP_v6;
1409 }
1410
1411 IPACMDBG("NDA_LLADDR:MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1412 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[0],
1413 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[1],
1414 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[2],
1415 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[3],
1416 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[4],
1417 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[5]);
1418
1419
1420 memcpy(data_all->mac_addr,
1421 msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr.sa_data,
1422 sizeof(data_all->mac_addr));
1423 data_all->if_index = msg_ptr->nl_neigh_info.metainfo.ndm_ifindex;
1424 /* Add support to replace src-mac as bridge0 mac */
1425 if((msg_ptr->nl_neigh_info.metainfo.ndm_family == AF_BRIDGE) &&
1426 (msg_ptr->nl_neigh_info.metainfo.ndm_state == NUD_PERMANENT))
1427 {
1428 /* Posting IPA_BRIDGE_LINK_UP_EVENT event */
1429 evt_data.event = IPA_BRIDGE_LINK_UP_EVENT;
1430 IPACMDBG_H("posting IPA_BRIDGE_LINK_UP_EVENT (%s):index:%d \n",
1431 dev_name,
1432 data_all->if_index);
1433 }
1434 else
1435 {
1436 /* Posting new_neigh events for all LAN/WAN clients */
1437 evt_data.event = IPA_NEW_NEIGH_EVENT;
1438 IPACMDBG_H("posting IPA_NEW_NEIGH_EVENT (%s):index:%d ip-family: %d\n",
1439 dev_name,
1440 data_all->if_index,
1441 msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family);
1442 }
1443 evt_data.evt_data = data_all;
1444 IPACM_EvtDispatcher::PostEvt(&evt_data);
1445 /* finish command queue */
1446 break;
1447
1448 case RTM_DELNEIGH:
1449 if(IPACM_SUCCESS != ipa_nl_decode_rtm_neigh(buffer, buflen, &(msg_ptr->nl_neigh_info)))
1450 {
1451 IPACMERR("Failed to decode rtm neighbor message\n");
1452 return IPACM_FAILURE;
1453 }
1454
1455 ret_val = ipa_get_if_name(dev_name, msg_ptr->nl_neigh_info.metainfo.ndm_ifindex);
1456 if(ret_val != IPACM_SUCCESS)
1457 {
1458 IPACMERR("Error while getting interface index\n");
1459 return IPACM_FAILURE;
1460 }
1461 else
1462 {
1463 IPACMDBG("\n GOT RTM_DELNEIGH event (%s) ip %d\n",dev_name,msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family);
1464 }
1465
1466 /* insert to command queue */
1467 data_all = (ipacm_event_data_all *)malloc(sizeof(ipacm_event_data_all));
1468 if(data_all == NULL)
1469 {
1470 IPACMERR("unable to allocate memory for event data_all\n");
1471 return IPACM_FAILURE;
1472 }
1473
1474 memset(data_all, 0, sizeof(ipacm_event_data_all));
1475 if(msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET6)
1476 {
1477 IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr);
1478 IPACM_EVENT_COPY_ADDR_v6( data_all->ipv6_addr, msg_ptr->nl_neigh_info.attr_info.local_addr);
1479
1480 data_all->ipv6_addr[0] = ntohl(data_all->ipv6_addr[0]);
1481 data_all->ipv6_addr[1] = ntohl(data_all->ipv6_addr[1]);
1482 data_all->ipv6_addr[2] = ntohl(data_all->ipv6_addr[2]);
1483 data_all->ipv6_addr[3] = ntohl(data_all->ipv6_addr[3]);
1484 data_all->iptype = IPA_IP_v6;
1485 }
1486 else if (msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family == AF_INET)
1487 {
1488 IPACM_NL_REPORT_ADDR( " ", msg_ptr->nl_neigh_info.attr_info.local_addr);
1489 IPACM_EVENT_COPY_ADDR_v4( data_all->ipv4_addr, msg_ptr->nl_neigh_info.attr_info.local_addr);
1490 data_all->ipv4_addr = ntohl(data_all->ipv4_addr);
1491 data_all->iptype = IPA_IP_v4;
1492 }
1493 else
1494 {
1495 data_all->iptype = IPA_IP_v6;
1496 }
1497
1498 IPACMDBG("NDA_LLADDR:MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
1499 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[0],
1500 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[1],
1501 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[2],
1502 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[3],
1503 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[4],
1504 (unsigned char)(msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr).sa_data[5]);
1505
1506 memcpy(data_all->mac_addr,
1507 msg_ptr->nl_neigh_info.attr_info.lladdr_hwaddr.sa_data,
1508 sizeof(data_all->mac_addr));
1509 evt_data.event = IPA_DEL_NEIGH_EVENT;
1510 data_all->if_index = msg_ptr->nl_neigh_info.metainfo.ndm_ifindex;
1511
1512 IPACMDBG_H("posting IPA_DEL_NEIGH_EVENT (%s):index:%d ip-family: %d\n",
1513 dev_name,
1514 data_all->if_index,
1515 msg_ptr->nl_neigh_info.attr_info.local_addr.ss_family);
1516 evt_data.evt_data = data_all;
1517 IPACM_EvtDispatcher::PostEvt(&evt_data);
1518 /* finish command queue */
1519 break;
1520
1521 default:
1522 IPACMDBG(" ignore NL event %d!!!\n ", nlh->nlmsg_type);
1523 break;
1524
1525 }
1526 nlh = NLMSG_NEXT(nlh, buflen);
1527 }
1528
1529 return IPACM_SUCCESS;
1530 }
1531
1532
1533 /* Virtual function registered to receive incoming messages over the NETLINK routing socket*/
ipa_nl_recv_msg(int fd)1534 int ipa_nl_recv_msg(int fd)
1535 {
1536 struct msghdr *msghdr = NULL;
1537 struct iovec *iov = NULL;
1538 unsigned int msglen = 0;
1539 ipa_nl_msg_t *nlmsg = NULL;
1540
1541 nlmsg = (ipa_nl_msg_t *)malloc(sizeof(ipa_nl_msg_t));
1542 if(NULL == nlmsg)
1543 {
1544 IPACMERR("Failed alloc of nlmsg \n");
1545 goto error;
1546 }
1547 else
1548 {
1549 if(IPACM_SUCCESS != ipa_nl_recv(fd, &msghdr, &msglen))
1550 {
1551 IPACMERR("Failed to receive nl message \n");
1552 goto error;
1553 }
1554
1555 if(msghdr== NULL)
1556 {
1557 IPACMERR(" failed to get msghdr\n");
1558 goto error;
1559 }
1560
1561 iov = msghdr->msg_iov;
1562
1563 memset(nlmsg, 0, sizeof(ipa_nl_msg_t));
1564 if(IPACM_SUCCESS != ipa_nl_decode_nlmsg((char *)iov->iov_base, msglen, nlmsg))
1565 {
1566 IPACMERR("Failed to decode nl message \n");
1567 goto error;
1568 }
1569 /* Release NetLink message buffer */
1570 if(msghdr)
1571 {
1572 ipa_nl_release_msg(msghdr);
1573 }
1574 if(nlmsg)
1575 {
1576 free(nlmsg);
1577 }
1578 }
1579
1580 return IPACM_SUCCESS;
1581
1582 error:
1583 if(msghdr)
1584 {
1585 ipa_nl_release_msg(msghdr);
1586 }
1587 if(nlmsg)
1588 {
1589 free(nlmsg);
1590 }
1591
1592 return IPACM_FAILURE;
1593 }
1594
1595 /* get ipa interface name */
ipa_get_if_name(char * if_name,int if_index)1596 int ipa_get_if_name
1597 (
1598 char *if_name,
1599 int if_index
1600 )
1601 {
1602 int fd;
1603 struct ifreq ifr;
1604
1605 if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1606 {
1607 IPACMERR("get interface name socket create failed \n");
1608 return IPACM_FAILURE;
1609 }
1610
1611 memset(&ifr, 0, sizeof(struct ifreq));
1612 ifr.ifr_ifindex = if_index;
1613 IPACMDBG("Interface index %d\n", if_index);
1614
1615 if(ioctl(fd, SIOCGIFNAME, &ifr) < 0)
1616 {
1617 IPACMERR("call_ioctl_on_dev: ioctl failed:\n");
1618 close(fd);
1619 return IPACM_FAILURE;
1620 }
1621
1622 (void)strncpy(if_name, ifr.ifr_name, sizeof(ifr.ifr_name));
1623 IPACMDBG("interface name %s\n", ifr.ifr_name);
1624 close(fd);
1625
1626 return IPACM_SUCCESS;
1627 }
1628
1629 /* 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)1630 int ipa_nl_listener_init
1631 (
1632 unsigned int nl_type,
1633 unsigned int nl_groups,
1634 ipa_nl_sk_fd_set_info_t *sk_fdset,
1635 ipa_sock_thrd_fd_read_f read_f
1636 )
1637 {
1638 ipa_nl_sk_info_t sk_info;
1639 int ret_val;
1640
1641 memset(&sk_info, 0, sizeof(ipa_nl_sk_info_t));
1642 IPACMDBG_H("Entering IPA NL listener init\n");
1643
1644 if(ipa_nl_open_socket(&sk_info, nl_type, nl_groups) == IPACM_SUCCESS)
1645 {
1646 IPACMDBG_H("IPA Open netlink socket succeeds\n");
1647 }
1648 else
1649 {
1650 IPACMERR("Netlink socket open failed\n");
1651 return IPACM_FAILURE;
1652 }
1653
1654 /* Add NETLINK socket to the list of sockets that the listener
1655 thread should listen on. */
1656
1657 if(ipa_nl_addfd_map(sk_fdset, sk_info.sk_fd, read_f) != IPACM_SUCCESS)
1658 {
1659 IPACMERR("cannot add nl routing sock for reading\n");
1660 close(sk_info.sk_fd);
1661 return IPACM_FAILURE;
1662 }
1663
1664 /* Start the socket listener thread */
1665 ret_val = ipa_nl_sock_listener_start(sk_fdset);
1666
1667 if(ret_val != IPACM_SUCCESS)
1668 {
1669 IPACMERR("Failed to start NL listener\n");
1670 }
1671
1672 return IPACM_SUCCESS;
1673 }
1674
1675 /* find the newroute subnet mask */
find_mask(int ip_v4_last,int * mask_value)1676 int find_mask(int ip_v4_last, int *mask_value)
1677 {
1678
1679 switch(ip_v4_last)
1680 {
1681
1682 case 3:
1683 *mask_value = 252;
1684 return IPACM_SUCCESS;
1685 break;
1686
1687 case 7:
1688 *mask_value = 248;
1689 return IPACM_SUCCESS;
1690 break;
1691
1692 case 15:
1693 *mask_value = 240;
1694 return IPACM_SUCCESS;
1695 break;
1696
1697 case 31:
1698 *mask_value = 224;
1699 return IPACM_SUCCESS;
1700 break;
1701
1702 case 63:
1703 *mask_value = 192;
1704 return IPACM_SUCCESS;
1705 break;
1706
1707 case 127:
1708 *mask_value = 128;
1709 return IPACM_SUCCESS;
1710 break;
1711
1712 case 255:
1713 *mask_value = 0;
1714 return IPACM_SUCCESS;
1715 break;
1716
1717 default:
1718 return IPACM_FAILURE;
1719 break;
1720
1721 }
1722 }
1723
1724 /* map mask value for ipv6 */
mask_v6(int index,uint32_t * mask)1725 int mask_v6(int index, uint32_t *mask)
1726 {
1727 switch(index)
1728 {
1729
1730 case 0:
1731 *mask = 0x00000000;
1732 return IPACM_SUCCESS;
1733 break;
1734 case 4:
1735 *mask = 0xf0000000;
1736 return IPACM_SUCCESS;
1737 break;
1738 case 8:
1739 *mask = 0xff000000;
1740 return IPACM_SUCCESS;
1741 break;
1742 case 12:
1743 *mask = 0xfff00000;
1744 return IPACM_SUCCESS;
1745 break;
1746 case 16:
1747 *mask = 0xffff0000;
1748 return IPACM_SUCCESS;
1749 break;
1750 case 20:
1751 *mask = 0xfffff000;
1752 return IPACM_SUCCESS;
1753 break;
1754 case 24:
1755 *mask = 0xffffff00;
1756 return IPACM_SUCCESS;
1757 break;
1758 case 28:
1759 *mask = 0xfffffff0;
1760 return IPACM_SUCCESS;
1761 break;
1762 case 32:
1763 *mask = 0xffffffff;
1764 return IPACM_SUCCESS;
1765 break;
1766 default:
1767 return IPACM_FAILURE;
1768 break;
1769
1770 }
1771 }
1772
1773
1774