/* 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;

	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)));
		}
	}
}
