/* nbr.c - Neighbor table management */

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <logging/log.h>
LOG_MODULE_REGISTER(net_nbr, CONFIG_NET_IPV6_NBR_CACHE_LOG_LEVEL);

#include <errno.h>

#include <net/net_core.h>

#include "net_private.h"

#include "nbr.h"

NET_NBR_LLADDR_INIT(net_neighbor_lladdr, CONFIG_NET_IPV6_MAX_NEIGHBORS);

#if defined(CONFIG_NET_IPV6_NBR_CACHE_LOG_LEVEL_DBG)
void net_nbr_unref_debug(struct net_nbr *nbr, const char *caller, int line)
#define net_nbr_unref(nbr) net_nbr_unref_debug(nbr, __func__, __LINE__)
#else
void net_nbr_unref(struct net_nbr *nbr)
#endif
{
#if defined(CONFIG_NET_IPV6_NBR_CACHE_LOG_LEVEL_DBG)
	NET_DBG("nbr %p ref %u (%s():%d)", nbr, nbr->ref - 1, caller, line);
#else
	NET_DBG("nbr %p ref %u", nbr, nbr->ref - 1);
#endif
	if (--nbr->ref) {
		return;
	}

	if (nbr->remove) {
		nbr->remove(nbr);
	}
}

#if defined(CONFIG_NET_IPV6_NBR_CACHE_LOG_LEVEL_DBG)
struct net_nbr *net_nbr_ref_debug(struct net_nbr *nbr, const char *caller,
				  int line)
#else
struct net_nbr *net_nbr_ref(struct net_nbr *nbr)
#endif
{
#if defined(CONFIG_NET_IPV6_NBR_CACHE_LOG_LEVEL_DBG)
	NET_DBG("nbr %p ref %u (%s():%d)", nbr, nbr->ref + 1, caller, line);
#else
	NET_DBG("nbr %p ref %u", nbr, nbr->ref + 1);
#endif
	nbr->ref++;

	return nbr;
}

static inline struct net_nbr *get_nbr(struct net_nbr *start, int idx)
{
	NET_ASSERT(idx < CONFIG_NET_IPV6_MAX_NEIGHBORS);

	return (struct net_nbr *)((u8_t *)start +
			((sizeof(struct net_nbr) +
			  start->size + start->extra_data_size) * idx));
}

struct net_nbr *net_nbr_get(struct net_nbr_table *table)
{
	int i;

	for (i = 0; i < table->nbr_count; i++) {
		struct net_nbr *nbr = get_nbr(table->nbr, i);

		if (!nbr->ref) {
			nbr->data = nbr->__nbr;

			return net_nbr_ref(nbr);
		}
	}

	return NULL;
}

int net_nbr_link(struct net_nbr *nbr, struct net_if *iface,
		 struct net_linkaddr *lladdr)
{
	int i, avail = -1;

	if (nbr->idx != NET_NBR_LLADDR_UNKNOWN) {
		return -EALREADY;
	}

	for (i = 0; i < CONFIG_NET_IPV6_MAX_NEIGHBORS; i++) {
		if (avail < 0 && !net_neighbor_lladdr[i].ref) {
			avail = i;
		}

		if (net_neighbor_lladdr[i].ref &&
		    !memcmp(lladdr->addr,
			    net_neighbor_lladdr[i].lladdr.addr,
			    lladdr->len)) {
			/* We found same lladdr in nbr cache so just
			 * increase the ref count.
			 */
			net_neighbor_lladdr[i].ref++;

			nbr->idx = i;
			nbr->iface = iface;

			return 0;
		}
	}

	if (avail < 0) {
		return -ENOENT;
	}

	/* There was no existing entry in the lladdr cache,
	 * so allocate one for this lladdr.
	 */
	net_neighbor_lladdr[avail].ref++;
	nbr->idx = avail;

	net_linkaddr_set(&net_neighbor_lladdr[avail].lladdr, lladdr->addr,
			 lladdr->len);
	net_neighbor_lladdr[avail].lladdr.len = lladdr->len;
	net_neighbor_lladdr[avail].lladdr.type = lladdr->type;

	nbr->iface = iface;

	return 0;
}

int net_nbr_unlink(struct net_nbr *nbr, struct net_linkaddr *lladdr)
{
	ARG_UNUSED(lladdr);

	if (nbr->idx == NET_NBR_LLADDR_UNKNOWN) {
		return -EALREADY;
	}

	NET_ASSERT(nbr->idx < CONFIG_NET_IPV6_MAX_NEIGHBORS);
	NET_ASSERT(net_neighbor_lladdr[nbr->idx].ref > 0);

	net_neighbor_lladdr[nbr->idx].ref--;

	if (!net_neighbor_lladdr[nbr->idx].ref) {
		(void)memset(net_neighbor_lladdr[nbr->idx].lladdr.addr, 0,
			     sizeof(net_neighbor_lladdr[nbr->idx].lladdr.addr));
	}

	nbr->idx = NET_NBR_LLADDR_UNKNOWN;
	nbr->iface = NULL;

	return 0;
}

struct net_nbr *net_nbr_lookup(struct net_nbr_table *table,
			       struct net_if *iface,
			       struct net_linkaddr *lladdr)
{
	int i;

	for (i = 0; i < table->nbr_count; i++) {
		struct net_nbr *nbr = get_nbr(table->nbr, i);

		if (nbr->ref && nbr->iface == iface &&
		    net_neighbor_lladdr[nbr->idx].ref &&
		    !memcmp(net_neighbor_lladdr[nbr->idx].lladdr.addr,
			    lladdr->addr, lladdr->len)) {
			return nbr;
		}
	}

	return NULL;
}

struct net_linkaddr_storage *net_nbr_get_lladdr(u8_t idx)
{
	NET_ASSERT_INFO(idx < CONFIG_NET_IPV6_MAX_NEIGHBORS,
			"idx %d >= max %d", idx,
			CONFIG_NET_IPV6_MAX_NEIGHBORS);

	return &net_neighbor_lladdr[idx].lladdr;
}

void net_nbr_clear_table(struct net_nbr_table *table)
{
	int i;

	for (i = 0; i < table->nbr_count; i++) {
		struct net_nbr *nbr = get_nbr(table->nbr, i);
		struct net_linkaddr lladdr = {
			.addr = net_neighbor_lladdr[i].lladdr.addr,
			.len = net_neighbor_lladdr[i].lladdr.len
		};

		net_nbr_unlink(nbr, &lladdr);
	}

	if (table->clear) {
		table->clear(table);
	}
}

void net_nbr_print(struct net_nbr_table *table)
{
	if (CONFIG_NET_IPV6_NBR_CACHE_LOG_LEVEL >= LOG_LEVEL_DBG) {
		int i;

		for (i = 0; i < table->nbr_count; i++) {
			struct net_nbr *nbr = get_nbr(table->nbr, i);

			if (!nbr->ref) {
				continue;
			}

			NET_DBG("[%d] nbr %p data %p ref %d iface %p idx %d "
				"ll %s",
				i, nbr, nbr->data, nbr->ref, nbr->iface,
				nbr->idx,
				nbr->idx == NET_NBR_LLADDR_UNKNOWN ?
				"<unknown>" :
				log_strdup(net_sprint_ll_addr(
				   net_neighbor_lladdr[nbr->idx].lladdr.addr,
				   net_neighbor_lladdr[nbr->idx].lladdr.len)));
		}
	}
}
