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*/ 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).*/ 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 */ 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 */ 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 */ 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 */ 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 */ 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. */ 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. */ 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. */ 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 */ 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*/ 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 */ 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 */ 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 */ 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 */ 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