Home | History | Annotate | Download | only in src
      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