/*
 *
 *  Copyright (C) 2007 Mindspeed Technologies, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h>


#undef NLMSG_TAIL
#include <net/if.h>
#include <net/if_arp.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <netinet/icmp6.h>

#include "cmm.h"
#include "itf.h"
#include "forward_engine.h"
#include "neighbor_resolution.h"

extern pthread_mutex_t tnlMutex;

struct list_head neigh_table[2 * NEIGHBOR_HASH_TABLE_SIZE];
struct list_head neigh_table_by_mac[NEIGHBOR_HASH_TABLE_SIZE];
struct list_head neigh_state_table;

pthread_mutex_t neighMutex = PTHREAD_MUTEX_INITIALIZER;

static struct neighReq *neighReqHead = NULL;


static int cmmNeighborNetlinkLookupAllFilter(const struct sockaddr_nl *nladdr, struct nlmsghdr *nlh, void *arg)
{
	int ifindex = *(int *)arg;
	struct NeighborEntry *neigh;
	struct ndmsg *ndm;
	struct rtattr *attr;

	if (nlh->nlmsg_type != RTM_NEWNEIGH) {
		cmm_print(DEBUG_ERROR, "%s::%d: unexpected netlink message(%d)\n",
					 __func__, __LINE__, nlh->nlmsg_type);

		goto out;
	}

	ndm = NLMSG_DATA(nlh);

	if (ndm->ndm_state & NUD_NOARP)
		goto out;

	if (ndm->ndm_ifindex != ifindex)
		goto out;

	attr = cmm_get_rtattr(NDA_RTA(ndm), NDA_PAYLOAD(nlh), NDA_DST);
	if (!attr) {
		cmm_print(DEBUG_ERROR, "%s::%d: rtnetlink message missing daddr\n", __func__, __LINE__);
		goto out;
	}

	/* If an entry already exists then skip update,
	it will be done through the listner thread. This is to avoid calling the ARP/Neighbor state machine from here */
	neigh = __cmmNeighFind(ndm->ndm_family, RTA_DATA(attr), ifindex);
	if (!neigh) {
		neigh = __cmmNeighAdd(ndm->ndm_family, RTA_DATA(attr), ifindex);
		if (!neigh) {
			cmm_print(DEBUG_ERROR, "%s::%d: __cmmNeighAdd() failed\n", __func__, __LINE__);
			goto out;
		}
	}
	else
		goto out;

	/* Putting data in ArpEntry */
	neigh->state = ndm->ndm_state;

	if (neigh->state & NUD_VALID) {
		int key;

		attr = cmm_get_rtattr(NDA_RTA(ndm), NDA_PAYLOAD(nlh), NDA_LLADDR);

		memcpy(neigh->macAddr, RTA_DATA(attr), RTA_PAYLOAD(attr));

		key = HASH_MAC(neigh->macAddr);
		list_add(&neigh_table_by_mac[key], &neigh->list_by_mac);
	}
	else
		memset(neigh->macAddr, 0, ETH_ALEN);

out:
	return RTNL_CB_CONTINUE;
}

static int cmmNeighborNetlinkLookupAll(int family, int ifindex)
{
	struct rtnl_handle rth;
	struct ndmsg ndm = {
		.ndm_family = family,
		.ndm_ifindex = 0,
		.ndm_state = 0,
		.ndm_flags = 0,
		.ndm_type = 0,
	};

	cmm_print(DEBUG_INFO, "%s\n", __func__);

	if (cmm_rtnl_open(&rth, 0) < 0) {
		cmm_print(DEBUG_ERROR, "%s::%d: netlink socket() %s\n", __func__, __LINE__, strerror(errno));
		goto err0;
	}

	if (cmm_rtnl_dump_request(&rth, RTM_GETNEIGH, &ndm, sizeof(struct ndmsg)) < 0)
		goto err1;

	cmm_rtnl_listen(&rth, cmmNeighborNetlinkLookupAllFilter, &ifindex);

	cmm_rtnl_close(&rth);

	return 0;

err1:
	cmm_rtnl_close(&rth);

err0:
	return -1;
}




int cmmNeighAddSolicitQ(int family, int ifindex, unsigned int *dst_ip, unsigned char *dst_mac)
{
	struct neighReq *n;

	n = (struct neighReq *)malloc(sizeof(struct neighReq));
	if (!n) {
		return -1;
	}
	
	n->family = family;
	n->ifindex = ifindex;
	if (family == AF_INET)
		n->dst_ip[0] = *dst_ip;
	else
		memcpy((unsigned char *)n->dst_ip, (unsigned char *)dst_ip, 16);
	
	if (dst_mac != NULL) {
		memcpy(n->dst_mac, dst_mac, 6);
		n->dst_mac_null=0;
	}
	else {
		n->dst_mac_null=1;
	}

	if (neighReqHead != NULL)
		n->next = neighReqHead;
	else
		n->next = NULL;

	neighReqHead = n;
	
	return 0;
}

void cmmNeighSendSolicitQ(void)
{
	struct neighReq *n, *next;

	if (neighReqHead == NULL)
		return;
	 
	for(n = neighReqHead; n != NULL; n = next) {

		if (n->family == AF_INET) {
			cmmArpRequest(n->ifindex, n->dst_ip[0], 
						n->dst_mac_null ? NULL : n->dst_mac);
		}
		else  {
			cmmNeighborSolicitation(n->ifindex, n->dst_ip, 
						n->dst_mac_null ? NULL : n->dst_mac);
		}
		
		next = n->next;
		free(n);
	}
	neighReqHead = NULL;

	return;
}





#define MULTICAST_SOLICITED_NODE "FF02::1:FF00:0000"

int cmmNeighborSolicitation(int ifindex, unsigned int *dst_ip, unsigned char *dst_mac)
{
	struct sockaddr_in6 sockaddr;
	struct __attribute__((packed)) {
		struct nd_neighbor_solicit hdr;
		uint8_t nd_opt_type;
		uint8_t nd_opt_len;
		unsigned char src_mac[ETH_ALEN];
	} neighbor;
	int sockopt;
	unsigned int multi_addr[4];
	int fd;
	int len;
	int rc = -1;

	/* dst_mac is NULL for multicast solicitations */
	if(dst_mac == NULL)
		inet_pton(AF_INET6, MULTICAST_SOLICITED_NODE, multi_addr);

	fd = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
	if (fd < 0) {
		cmm_print(DEBUG_ERROR, "%s::%d: socket() %s\n", __func__, __LINE__, strerror(errno));
		goto out;
	}

	memset(&sockaddr, 0, sizeof(struct sockaddr_in6));

	sockaddr.sin6_family = AF_INET6;
	sockaddr.sin6_scope_id = ifindex;

	if (itf_get_ipaddr(ifindex, AF_INET6, RT_SCOPE_LINK, (unsigned int *)&sockaddr.sin6_addr.s6_addr32, dst_ip) < 0) {
		cmm_print(DEBUG_ERROR, "%s::%d: itf_get_ipaddr(%d) failed\n", __func__, __LINE__, ifindex);
		goto close;
	}
	

	if (bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0) {
		cmm_print(DEBUG_ERROR, "%s::%d: bind() %s\n", __func__, __LINE__, strerror(errno));
		goto close;
	}

	memset(&sockaddr, 0, sizeof(struct sockaddr_in6));
	sockaddr.sin6_family = AF_INET6;
	if(dst_mac == NULL)	{
		memcpy(sockaddr.sin6_addr.s6_addr, multi_addr, sizeof(multi_addr));
		memcpy(sockaddr.sin6_addr.s6_addr + 13, (unsigned char *)dst_ip + 13, 3);
	}
	else {
		memcpy(sockaddr.sin6_addr.s6_addr, (unsigned char *)dst_ip, 16);
	}
	
	memset(&neighbor.hdr, 0, sizeof(struct nd_neighbor_solicit));
	neighbor.hdr.nd_ns_type = ND_NEIGHBOR_SOLICIT;
	memcpy(&neighbor.hdr.nd_ns_target, dst_ip, 16);

	neighbor.nd_opt_type = ND_OPT_SOURCE_LINKADDR;
	neighbor.nd_opt_len = 1; /* 8 bytes */

	if (itf_get_macaddr(ifindex, neighbor.src_mac) < 0) {
		cmm_print(DEBUG_ERROR, "%s::%d: itf_get_macaddr(%d) failed\n", __func__, __LINE__, ifindex);
		goto close;
	}

	sockopt = 255;
	if(dst_mac == NULL)	{
		if (setsockopt(fd, SOL_IPV6, IPV6_MULTICAST_HOPS, (char *) &sockopt, sizeof(sockopt)) < 0) {
			cmm_print(DEBUG_ERROR, "%s::%d: setsockopt() %s\n", __func__, __LINE__, strerror(errno));
			goto close;
		}
	}
	else {
		if (setsockopt(fd, SOL_IPV6, IPV6_UNICAST_HOPS, (char *) &sockopt, sizeof(sockopt)) < 0) {
			cmm_print(DEBUG_ERROR, "%s::%d: setsockopt() %s\n", __func__, __LINE__, strerror(errno));
			goto close;
		}
	}

	len = sizeof(neighbor);
	if (sendto(fd, &neighbor, len, 0, (struct sockaddr *) &sockaddr, sizeof(sockaddr)) < len) {
		cmm_print(DEBUG_ERROR, "%s::%d: sendto() %s\n", __func__, __LINE__, strerror(errno));
		goto close;
	}

	rc = 0;

close:
	close(fd);
out:
	return rc;
}

int cmmArpRequest(int ifindex, unsigned int dst_ip, unsigned char *dst_mac)
{
	struct sockaddr_ll sockaddr;
	struct __attribute__((packed)) {
		struct arphdr ah;
		unsigned char src_mac[ETH_ALEN];
		unsigned int src_ip;
		unsigned char dst_mac[ETH_ALEN];
		unsigned int dst_ip;
	} arp;
	unsigned int src_ip;
	unsigned char src_mac[ETH_ALEN];
	int fd;
	int len;
	int rc = -1;

	fd = socket(PF_PACKET, SOCK_DGRAM, 0);
	if (fd < 0) {
		cmm_print(DEBUG_ERROR, "%s::%d: socket() %s\n", __func__, __LINE__, strerror(errno));
		goto out;
	}

	memset(&sockaddr, 0, sizeof(struct sockaddr_ll));
	sockaddr.sll_family = AF_PACKET;
	sockaddr.sll_ifindex = ifindex;
	sockaddr.sll_protocol = htons(ETH_P_ARP);

	if (bind(fd, (struct sockaddr *) &sockaddr, sizeof(struct sockaddr_ll)) < 0) {
		cmm_print(DEBUG_ERROR, "%s::%d: bind() %s\n", __func__, __LINE__, strerror(errno));
		goto close;
	}

	memset(&sockaddr, 0, sizeof(struct sockaddr_ll));
	sockaddr.sll_family = AF_PACKET;
	sockaddr.sll_ifindex = ifindex;
	sockaddr.sll_protocol = htons(ETH_P_ARP);
	sockaddr.sll_halen = ETH_ALEN;

	if (itf_get_ipaddr(ifindex, AF_INET, RT_SCOPE_UNIVERSE, &src_ip, &dst_ip) < 0) {
		cmm_print(DEBUG_ERROR, "%s::%d: itf_get_ipaddr(%d) failed\n", __func__, __LINE__, ifindex);
		goto close;
	}

	if (itf_get_macaddr(ifindex, src_mac) < 0) {
		cmm_print(DEBUG_ERROR, "%s::%d: itf_get_macaddr(%d) failed\n", __func__, __LINE__, ifindex);
		goto close;
	}

	if (!dst_mac)
		/* broadcast */
		memset(sockaddr.sll_addr, 0xFF, ETH_ALEN);
	else
		/* unicast */
		memcpy(sockaddr.sll_addr, dst_mac, ETH_ALEN);

	arp.ah.ar_hrd = htons(ARPHRD_ETHER);
	arp.ah.ar_pro = htons(ETH_P_IP);
	arp.ah.ar_hln = ETH_ALEN;
	arp.ah.ar_pln = 4;
	arp.ah.ar_op = htons(ARPOP_REQUEST);

	memcpy(arp.src_mac, src_mac, ETH_ALEN);
	memcpy(&arp.src_ip, &src_ip, 4);

	if (!dst_mac)
		memset(arp.dst_mac, 0, ETH_ALEN);
	else
		memcpy(arp.dst_mac, sockaddr.sll_addr, ETH_ALEN);

	memcpy(&arp.dst_ip, &dst_ip, 4);

	len = sizeof(arp);
	if (sendto(fd, &arp, len, 0, (struct sockaddr *) &sockaddr, sizeof(struct sockaddr_ll)) < len) {
		cmm_print(DEBUG_ERROR, "%s::%d: sendto() %s\n", __func__, __LINE__, strerror(errno));
		goto close;
	}

	rc = 0;

close:
	close(fd);
out:
	return rc;
}

/*****************************************************************
* __cmmNeighUpdateAllMacs
*
*
******************************************************************/
void __cmmNeighUpdateAllMacs(int ifindex, unsigned char *macAddr, int port)
{
	struct NeighborEntry *neigh;
	struct list_head *entry;
	int key;

	key = HASH_MAC(macAddr);

	entry = list_first(&neigh_table_by_mac[key]);

	while (entry != &neigh_table_by_mac[key])
	{
		neigh = container_of(entry, struct NeighborEntry, list_by_mac);

		if ((neigh->ifindex == ifindex) &&
		    !memcmp(neigh->macAddr, macAddr, ETH_ALEN))
			neigh->port = port;

		entry = list_next(entry);
	}
}

/*****************************************************************
* __cmmNeighFind
*
*
******************************************************************/
struct NeighborEntry *__cmmNeighFind(int family, const unsigned int *ipAddr, int ifindex)
{
	struct NeighborEntry *neigh;
	struct list_head *entry;
	char buf[INET6_ADDRSTRLEN];
	int key;
	int ipAddrLen = IPADDRLEN(family);

	cmm_print(DEBUG_INFO, "%s: Neighbor(%d, %s)\n", __func__, ifindex, inet_ntop(family, ipAddr, buf, sizeof(buf)));

	key = HASH_NEIGHBOR(family, ipAddr);

	entry = list_first(&neigh_table[key]);

	while (entry != &neigh_table[key])
	{
		neigh = container_of(entry, struct NeighborEntry, list);
		if (!memcmp(neigh->ipAddr, ipAddr, ipAddrLen) && neigh->ifindex == ifindex)
			goto found;

		entry = list_next(entry);
	}

	neigh = NULL;

found:

	return neigh;
}


/*****************************************************************
* __cmmNeighRemove
*
*
******************************************************************/

/* NOTE: The neighMutex must be locked by the caller of this routine. */

void __cmmNeighRemove(struct NeighborEntry *neigh)
{
	char buf[INET6_ADDRSTRLEN];

	list_del(&neigh->list);

	if (neigh->state & NUD_VALID)
		list_del(&neigh->list_by_mac);

	if (neigh->flags & NEEDS_SOLICIT)
		list_del(&neigh->list_by_state);
		
	cmm_print(DEBUG_INFO, "%s: Neighbor(%d, %s) removed\n", __func__, neigh->ifindex, inet_ntop(neigh->family, neigh->ipAddr, buf, sizeof(buf)));

	free(neigh);
}

/*****************************************************************
* __cmmNeighPut
*
*
******************************************************************/
void __cmmNeighPut(struct NeighborEntry *neigh)
{
	char buf[INET6_ADDRSTRLEN];

	cmm_print(DEBUG_INFO, "%s: Neighbor(%d, %s) put\n", __func__, neigh->ifindex, inet_ntop(neigh->family, neigh->ipAddr, buf, sizeof(buf)));

	neigh->count--;

	if (neigh->count <= 0)
	{
		__cmmNeighRemove(neigh);
	}
}


/*****************************************************************
* __cmmNeighAdd
*
*
******************************************************************/
struct NeighborEntry *__cmmNeighAdd(int family, const unsigned int *ipAddr, int ifindex)
{
	struct NeighborEntry *neigh;
	char buf[INET6_ADDRSTRLEN];
	int key;

	neigh = malloc(sizeof(struct NeighborEntry));
	if (!neigh)
	{
		cmm_print(DEBUG_ERROR, "%s::%d: malloc() failed\n", __func__, __LINE__);
		goto err0;
	}

	memset(neigh, 0, sizeof(struct NeighborEntry));

	neigh->count = 0;
	neigh->port = -1;
	neigh->nr_probes = 0;
	neigh->ifindex = ifindex;
	neigh->ipAddrLen = IPADDRLEN(family);
	neigh->family = family;
	memcpy(neigh->ipAddr, ipAddr, neigh->ipAddrLen);

	key = HASH_NEIGHBOR(family, ipAddr);

	list_add(&neigh_table[key], &neigh->list);

	cmm_print(DEBUG_INFO, "%s: Neighbor(%d, %s) added\n", __func__, ifindex, inet_ntop(family, ipAddr, buf, sizeof(buf)));

	return neigh;

err0:
	return NULL;
}


/*****************************************************************
* __cmmNeighGet
*
*
******************************************************************/
struct NeighborEntry *__cmmNeighGet(int family, const unsigned int *ipAddr, int ifindex)
{
	struct NeighborEntry *neigh;

	neigh = __cmmNeighFind(family, ipAddr, ifindex);
	if (!neigh)
	{
		if (cmmNeighborNetlinkLookupAll(family, ifindex) < 0)
		{
			cmm_print(DEBUG_ERROR, "%s::%d: cmmNeighborNetlinkLookupAll() failed\n", __func__, __LINE__);
			goto err;
		}

		neigh = __cmmNeighFind(family, ipAddr, ifindex);
		if (!neigh)
			goto err;
	}

	neigh->count++;

	return neigh;

err:
	return NULL;
}


/*****************************************************************
* cmmNeighShow
*
*
******************************************************************/
int cmmNeighShow(struct cli_def * cli, char *command, char *argv[], int argc)
{
	int i;
	struct NeighborEntry *temp;
	struct list_head *entry;
	char addr_buf[INET6_ADDRSTRLEN];
	char mac_buf[MAC_ADDRSTRLEN];
	char ifname[IFNAMSIZ];
	int count;

	cli_print(cli, "IPv4 ARP:");

	count = 0;

	for (i = 0; i < NEIGHBOR_HASH_TABLE_SIZE; i++)
	{
		__pthread_mutex_lock(&neighMutex);

		for (entry = list_first(&neigh_table[i]); entry != &neigh_table[i]; entry = list_next(entry))
		{
			temp = container_of(entry, struct NeighborEntry, list);

			cli_print(cli, "IP addr: %s --> MAC addr: %s If: %s, Port:%d, state: %x, Count: %d",
				inet_ntop(AF_INET, temp->ipAddr, addr_buf, sizeof(addr_buf)),
				mac_ntop(temp->macAddr, mac_buf, sizeof(mac_buf)),
				if_indextoname(temp->ifindex, ifname),
				temp->port,
				temp->state,
				temp->count);

			count++;
		}
		__pthread_mutex_unlock(&neighMutex);
	}

	cli_print(cli, "Total ARP Entries: %d\n", count);

	cli_print(cli, "IPv6 Neighbor:");

	count = 0;

	for (i = NEIGHBOR_HASH_TABLE_SIZE; i < 2 * NEIGHBOR_HASH_TABLE_SIZE; i++)
	{
		__pthread_mutex_lock(&neighMutex);
		for (entry = list_first(&neigh_table[i]); entry != &neigh_table[i]; entry = list_next(entry))
		{

			temp = container_of(entry, struct NeighborEntry, list);

			cli_print(cli, "IP addr: %s --> MAC addr: %s If: %s, Port: %d, state: %x, Count: %d",
				inet_ntop(AF_INET6, temp->ipAddr, addr_buf, sizeof(addr_buf)),
				mac_ntop(temp->macAddr, mac_buf, sizeof(mac_buf)),
				if_indextoname(temp->ifindex, ifname),
				temp->port,
				temp->state,
				temp->count);

				count++;
		}
		__pthread_mutex_unlock(&neighMutex);
	}

	cli_print(cli, "Total Neighbor Entries: %d\n", count);

	return CLI_OK;
}


/*****************************************************************
* cmmNeighborResolved
* 
*
******************************************************************/
static void __cmmNeighborResolved(FCI_CLIENT *fci_handle, struct NeighborEntry *neigh)
{
	/* Process conntrack entries that use this neighbor */
	struct RtEntry *route;
	struct list_head *entry;
	int key;

	/* Force lookup of bridge port */
	neigh->port = -1;

	key = HASH_MAC(neigh->macAddr);
	list_add(&neigh_table_by_mac[key], &neigh->list_by_mac);

	key = HASH_NEIGHBOR(neigh->family, neigh->ipAddr);

	entry = list_first(&rt_table_by_gw_ip[key]);
	while (entry != &rt_table_by_gw_ip[key])
	{
		route = container_of(entry, struct RtEntry, list_by_gw_ip);
		entry = list_next(entry);

		if (route->neighEntry != neigh)
			continue;

		/* Force lookup of bridge port */
		route->flags |= CHECK_BRIDGE_PORT;

		__cmmCtUpdateWithRoute(fci_handle, route);

		__cmmTunnelUpdateWithRoute(fci_handle, route);

		__cmmSocketUpdateWithRoute(fci_handle, route);
	}
}

/*****************************************************************
* cmmNeighborUnresolved
* 
*
******************************************************************/
static void __cmmNeighborUnresolved(FCI_CLIENT *fci_handle, struct NeighborEntry *neigh)
{
	/* Process conntrack entries that use this neighbor */
	struct RtEntry *route;
	struct list_head *entry;
	int key;

	cmm_print(DEBUG_INFO, "%s: Remove ARP/Neighbor entry\n", __func__);

	list_del(&neigh->list_by_mac);

	/* Reset bridge port information, if any */
	neigh->port = -1;

	key = HASH_NEIGHBOR(neigh->family, neigh->ipAddr);

	entry = list_first(&rt_table_by_gw_ip[key]);
	while (entry != &rt_table_by_gw_ip[key])
	{
		route = container_of(entry, struct RtEntry, list_by_gw_ip);
		entry = list_next(entry);

		if (route->neighEntry != neigh)
			continue;

		/* Force lookup of bridge port */
		route->flags |= CHECK_BRIDGE_PORT;

		__cmmCtUpdateWithRoute(fci_handle, route);

		__cmmTunnelUpdateWithRoute(fci_handle, route);

		__cmmSocketUpdateWithRoute(fci_handle, route);
	}
}

/*****************************************************************
* cmmNeighborUpdate
* 
*
******************************************************************/
static int cmmNeighborUpdate(struct cmm_ct *ctx, const struct sockaddr_nl *who, struct nlmsghdr *n)
{
	char buf[INET6_ADDRSTRLEN];
	struct ndmsg *r = NLMSG_DATA(n);
	struct rtattr * tb [NDA_MAX + 1];
	struct NeighborEntry *neigh;
	unsigned int *ipAddr;
	unsigned char *macAddr;
	unsigned int macAddrLen;
	unsigned short old_state;

	/*Parse the message*/
	cmm_parse_rtattr(tb, NDA_MAX, NDA_RTA(r), NDA_PAYLOAD(n));

	/* Check if the event can interrest us*/
	if (!tb[NDA_DST])
		return 0;

	if (r->ndm_state & NUD_NOARP)
		return 0;

	ipAddr = RTA_DATA(tb[NDA_DST]);

	if (tb[NDA_LLADDR])
	{
		macAddr = RTA_DATA(tb[NDA_LLADDR]);
		macAddrLen = RTA_PAYLOAD(tb[NDA_LLADDR]);
	}
	else
	{
		macAddr = NULL;
		macAddrLen = 0;
	}

	/*Get the IP address in ascii*/
	inet_ntop(r->ndm_family, ipAddr, buf, INET6_ADDRSTRLEN);
	cmm_print(DEBUG_INFO, "%s: %s, state=%x\n", __func__, buf, r->ndm_state);

	/*Try to find a corresponding entry in the ARP table*/
	__pthread_mutex_lock(&itf_table.lock);
	__pthread_mutex_lock(&ctMutex);
	__pthread_mutex_lock(&rtMutex);
	__pthread_mutex_lock(&neighMutex);
	__pthread_mutex_lock(&flowMutex);

	neigh = __cmmNeighFind(r->ndm_family, ipAddr, r->ndm_ifindex);
	if (!neigh)
		goto out;

	/* Update local entry */
	old_state = neigh->state;
	neigh->state = r->ndm_state;
	cmm_print(DEBUG_INFO, "%s: old state = 0x%0x new state = 0x%0x\n", __func__, old_state, neigh->state);

	if((r->ndm_state & NUD_REACHABLE) && (neigh->flags & NEEDS_SOLICIT))
	{
		neigh->flags &= ~NEEDS_SOLICIT;
		neigh->nr_probes = 0;
		list_del(&neigh->list_by_state);
		cmm_print(DEBUG_INFO, "%s: Deleted Entry in Neighbor by state list \n", __func__);
	}

	if ((r->ndm_state & NUD_STALE) && (!(neigh->flags & NEEDS_SOLICIT)))
	{
		neigh->flags |= NEEDS_SOLICIT;
		list_add(&neigh_state_table, &neigh->list_by_state);
		cmm_print(DEBUG_INFO, "%s: Added Entry in Neighbor by state list \n", __func__);
	}

	/*In those states, the MAC address is usable*/
	if (r->ndm_state & NUD_VALID)
	{
		cmm_print(DEBUG_INFO, "%s: Update ARP/Neighbor entry\n", __func__);

		if (!(old_state & NUD_VALID))
		{
			memcpy(neigh->macAddr, macAddr, macAddrLen);

			__cmmNeighborResolved(ctx->fci_handle, neigh);
		}
		else
		{
			if (memcmp(neigh->macAddr, macAddr, macAddrLen))
			{
				memcpy(neigh->macAddr, macAddr, macAddrLen);

				list_del(&neigh->list_by_mac);

				__cmmNeighborResolved(ctx->fci_handle, neigh);
			}
		}
	}
	else
	{
		memset(neigh->macAddr, 0, ETH_ALEN);

		if (old_state & NUD_VALID)
			__cmmNeighborUnresolved(ctx->fci_handle, neigh);
	}

out:
	__pthread_mutex_unlock(&flowMutex);
	__pthread_mutex_unlock(&neighMutex);
	__pthread_mutex_unlock(&rtMutex);
	__pthread_mutex_unlock(&ctMutex);
	__pthread_mutex_unlock(&itf_table.lock);

	return 0;
}


/*****************************************************************
* cmmNeighThread
*
* Function that sends neighbor soliciations
*
******************************************************************/
int cmmNeighSendSolicit(void)
{
	struct NeighborEntry *neigh;
	struct list_head *entry;
	struct list_head *next;

	__pthread_mutex_lock(&neighMutex);
	
	for (entry = list_first(&neigh_state_table); entry != &neigh_state_table; entry = next)
	{
		next = list_next(entry);
		
		neigh = container_of(entry, struct NeighborEntry, list_by_state);

		if(neigh->nr_probes < MAX_UCAST_SOLICIT )
		{
			if(cmmNeighAddSolicitQ(neigh->family, neigh->ifindex,
						neigh->ipAddr, neigh->macAddr) == 0)
				neigh->nr_probes++;
		}
		else if ((neigh->nr_probes >= MAX_UCAST_SOLICIT) && 
				(neigh->nr_probes < (MAX_UCAST_SOLICIT + MAX_MCAST_SOLICIT)))
		{
			if(cmmNeighAddSolicitQ(neigh->family, neigh->ifindex,
						neigh->ipAddr, NULL) == 0)
				neigh->nr_probes++;
		}
		else
		{
			neigh->flags &= ~NEEDS_SOLICIT;
			neigh->nr_probes = 0;
			list_del(&neigh->list_by_state);
			cmm_print(DEBUG_INFO, "%s: Deleted Entry in Neighbor by state list \n", __func__);
		}
		
	}

	__pthread_mutex_unlock(&neighMutex);

	cmmNeighSendSolicitQ();

	return 0;
}

/*****************************************************************
* cmmNeighborGet
* 
*
******************************************************************/
static int cmmNeighborGet(struct cmm_ct *ctx, const struct sockaddr_nl *who, struct nlmsghdr *n)
{
	struct ndmsg *r = NLMSG_DATA(n);
	char tab6[INET6_ADDRSTRLEN];
	char ifname[IFNAMSIZ];
	struct rtattr * tb [NDA_MAX + 1];

	/* ARP request immediately done by CMM as Kernel waits 1 seconds before sending it */	
	
	/*Parse the message*/
        cmm_parse_rtattr(tb, NDA_MAX, NDA_RTA(r), NDA_PAYLOAD(n));

	inet_ntop(r->ndm_family, RTA_DATA(tb[NDA_DST]), tab6, INET6_ADDRSTRLEN);
	cmm_print(DEBUG_INFO, "%s: %s(%s), state=%x\n", __func__, tab6, if_indextoname(r->ndm_ifindex, ifname), r->ndm_state);

	/*IPv4 Neighbor*/
	if (r->ndm_family == AF_INET)
	{
		cmmArpRequest(r->ndm_ifindex, *(unsigned int *)(RTA_DATA(tb[NDA_DST])), NULL);
	}
	else if(r->ndm_family == AF_INET6)
	{
		cmmNeighborSolicitation(r->ndm_ifindex, (unsigned int *)(RTA_DATA(tb[NDA_DST])), NULL);
	}

	// Return, 
	return RTNL_CB_CONTINUE;
}


/*****************************************************************
* cmmRtnlNeigh
* 
*
******************************************************************/
int cmmRtnlNeigh(const struct sockaddr_nl *who, struct nlmsghdr *nlh, void *arg)
{
	struct cmm_ct *ctx = arg;

	switch (nlh->nlmsg_type) {
	case RTM_GETNEIGH:
		cmmNeighborGet(ctx, who, nlh);
		break;

	case RTM_NEWNEIGH:
	case RTM_DELNEIGH:
		cmmNeighborUpdate(ctx, who, nlh);
		break;

	default:
		cmm_print(DEBUG_ERROR, "%s: unsupported NEIGH netlink message %x\n", __func__, nlh->nlmsg_type);
		break;
	}

	return RTNL_CB_CONTINUE;
}
