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