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