/*
 * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
 *
 * Marek Lindner, Simon Wunderlich
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA
 *
 */

#include "main.h"
#include "translation-table.h"
#include "log.h"
#include "soft-interface.h"
#include "types.h"
#include "hash.h"
#include "compat.h"

struct hashtable_t *hna_local_hash;
static struct hashtable_t *hna_global_hash;
atomic_t hna_local_changed;

DEFINE_SPINLOCK(hna_local_hash_lock);
static DEFINE_SPINLOCK(hna_global_hash_lock);

static DECLARE_DELAYED_WORK(hna_local_purge_wq, hna_local_purge);

static void hna_local_start_timer(void)
{
	queue_delayed_work(bat_event_workqueue, &hna_local_purge_wq, 10 * HZ);
}

int hna_local_init(void)
{
	if (hna_local_hash)
		return 1;

	hna_local_hash = hash_new(128, compare_orig, choose_orig);

	if (!hna_local_hash)
		return 0;

	atomic_set(&hna_local_changed, 0);
	hna_local_start_timer();

	return 1;
}

void hna_local_add(uint8_t *addr)
{
	struct hna_local_entry *hna_local_entry;
	struct hna_global_entry *hna_global_entry;
	struct hashtable_t *swaphash;
	char hna_str[ETH_STR_LEN];
	unsigned long flags;

	spin_lock_irqsave(&hna_local_hash_lock, flags);
	hna_local_entry =
		((struct hna_local_entry *)hash_find(hna_local_hash, addr));
	spin_unlock_irqrestore(&hna_local_hash_lock, flags);

	if (hna_local_entry != NULL) {
		hna_local_entry->last_seen = jiffies;
		return;
	}

	addr_to_string(hna_str, addr);

	/* only announce as many hosts as possible in the batman-packet and
	   space in batman_packet->num_hna That also should give a limit to
	   MAC-flooding. */
	if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) ||
	    (num_hna + 1 > 255)) {
		debug_log(LOG_TYPE_ROUTES, "Can't add new local hna entry (%s): number of local hna entries exceeds packet size \n", hna_str);
		return;
	}

	debug_log(LOG_TYPE_ROUTES, "Creating new local hna entry: %s \n",
		  hna_str);

	hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
	if (!hna_local_entry)
		return;

	memcpy(hna_local_entry->addr, addr, ETH_ALEN);
	hna_local_entry->last_seen = jiffies;

	/* the batman interface mac address should never be purged */
	if (compare_orig(addr, soft_device->dev_addr))
		hna_local_entry->never_purge = 1;
	else
		hna_local_entry->never_purge = 0;

	spin_lock_irqsave(&hna_local_hash_lock, flags);

	hash_add(hna_local_hash, hna_local_entry);
	num_hna++;
	atomic_set(&hna_local_changed, 1);

	if (hna_local_hash->elements * 4 > hna_local_hash->size) {
		swaphash = hash_resize(hna_local_hash,
				       hna_local_hash->size * 2);

		if (swaphash == NULL)
			debug_log(LOG_TYPE_CRIT, "Couldn't resize local hna hash table \n");
		else
			hna_local_hash = swaphash;
	}

	spin_unlock_irqrestore(&hna_local_hash_lock, flags);

	/* remove address from global hash if present */
	spin_lock_irqsave(&hna_global_hash_lock, flags);

	hna_global_entry =
		((struct hna_global_entry *)hash_find(hna_global_hash, addr));

	if (hna_global_entry != NULL)
		_hna_global_del_orig(hna_global_entry, "local hna received");

	spin_unlock_irqrestore(&hna_global_hash_lock, flags);
}

int hna_local_fill_buffer(unsigned char *buff, int buff_len)
{
	struct hna_local_entry *hna_local_entry;
	struct hash_it_t *hashit = NULL;
	int i = 0;
	unsigned long flags;

	spin_lock_irqsave(&hna_local_hash_lock, flags);

	while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {

		if (buff_len < (i + 1) * ETH_ALEN)
			break;

		hna_local_entry = hashit->bucket->data;
		memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN);

		i++;
	}

	/* if we did not get all new local hnas see you next time  ;-) */
	if (i == num_hna)
		atomic_set(&hna_local_changed, 0);

	spin_unlock_irqrestore(&hna_local_hash_lock, flags);

	return i;
}

int hna_local_fill_buffer_text(unsigned char *buff, int buff_len)
{
	struct hna_local_entry *hna_local_entry;
	struct hash_it_t *hashit = NULL;
	int bytes_written = 0;
	unsigned long flags;

	spin_lock_irqsave(&hna_local_hash_lock, flags);

	while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {

		if (buff_len < bytes_written + ETH_STR_LEN + 4)
			break;

		hna_local_entry = hashit->bucket->data;

		bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4,
					  " * %02x:%02x:%02x:%02x:%02x:%02x\n",
					  hna_local_entry->addr[0],
					  hna_local_entry->addr[1],
					  hna_local_entry->addr[2],
					  hna_local_entry->addr[3],
					  hna_local_entry->addr[4],
					  hna_local_entry->addr[5]);
	}

	spin_unlock_irqrestore(&hna_local_hash_lock, flags);

	return bytes_written;
}

static void _hna_local_del(void *data)
{
	kfree(data);
	num_hna--;
	atomic_set(&hna_local_changed, 1);
}

static void hna_local_del(struct hna_local_entry *hna_local_entry,
			  char *message)
{
	char hna_str[ETH_STR_LEN];

	addr_to_string(hna_str, hna_local_entry->addr);
	debug_log(LOG_TYPE_ROUTES, "Deleting local hna entry (%s): %s \n",
		  hna_str, message);

	hash_remove(hna_local_hash, hna_local_entry->addr);
	_hna_local_del(hna_local_entry);
}

void hna_local_purge(struct work_struct *work)
{
	struct hna_local_entry *hna_local_entry;
	struct hash_it_t *hashit = NULL;
	unsigned long flags;
	unsigned long timeout;

	spin_lock_irqsave(&hna_local_hash_lock, flags);

	while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) {
		hna_local_entry = hashit->bucket->data;

		timeout = hna_local_entry->last_seen +
			((LOCAL_HNA_TIMEOUT / 1000) * HZ);
		if ((!hna_local_entry->never_purge) &&
		    time_after(jiffies, timeout))
			hna_local_del(hna_local_entry, "address timed out");
	}

	spin_unlock_irqrestore(&hna_local_hash_lock, flags);
	hna_local_start_timer();
}

void hna_local_free(void)
{
	if (!hna_local_hash)
		return;

	cancel_delayed_work_sync(&hna_local_purge_wq);
	hash_delete(hna_local_hash, _hna_local_del);
	hna_local_hash = NULL;
}

int hna_global_init(void)
{
	if (hna_global_hash)
		return 1;

	hna_global_hash = hash_new(128, compare_orig, choose_orig);

	if (!hna_global_hash)
		return 0;

	return 1;
}

void hna_global_add_orig(struct orig_node *orig_node,
			 unsigned char *hna_buff, int hna_buff_len)
{
	struct hna_global_entry *hna_global_entry;
	struct hna_local_entry *hna_local_entry;
	struct hashtable_t *swaphash;
	char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN];
	int hna_buff_count = 0;
	unsigned long flags;
	unsigned char *hna_ptr;

	addr_to_string(orig_str, orig_node->orig);

	while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) {
		spin_lock_irqsave(&hna_global_hash_lock, flags);

		hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
		hna_global_entry = (struct hna_global_entry *)
			hash_find(hna_global_hash, hna_ptr);

		if (hna_global_entry == NULL) {
			spin_unlock_irqrestore(&hna_global_hash_lock, flags);

			hna_global_entry =
				kmalloc(sizeof(struct hna_global_entry),
					GFP_ATOMIC);

			if (!hna_global_entry)
				break;

			memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);

			addr_to_string(hna_str, hna_global_entry->addr);
			debug_log(LOG_TYPE_ROUTES, "Creating new global hna entry: %s (via %s)\n", hna_str, orig_str);

			spin_lock_irqsave(&hna_global_hash_lock, flags);
			hash_add(hna_global_hash, hna_global_entry);

		}

		hna_global_entry->orig_node = orig_node;
		spin_unlock_irqrestore(&hna_global_hash_lock, flags);

		/* remove address from local hash if present */
		spin_lock_irqsave(&hna_local_hash_lock, flags);

		hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
		hna_local_entry = (struct hna_local_entry *)
			hash_find(hna_local_hash, hna_ptr);

		if (hna_local_entry != NULL)
			hna_local_del(hna_local_entry, "global hna received");

		spin_unlock_irqrestore(&hna_local_hash_lock, flags);

		hna_buff_count++;
	}

	orig_node->hna_buff_len = hna_buff_len;

	if (orig_node->hna_buff_len > 0) {
		orig_node->hna_buff = kmalloc(orig_node->hna_buff_len,
					      GFP_ATOMIC);
		memcpy(orig_node->hna_buff, hna_buff, orig_node->hna_buff_len);
	} else {
		orig_node->hna_buff = NULL;
	}

	spin_lock_irqsave(&hna_global_hash_lock, flags);

	if (hna_global_hash->elements * 4 > hna_global_hash->size) {
		swaphash = hash_resize(hna_global_hash,
				       hna_global_hash->size * 2);

		if (swaphash == NULL)
			debug_log(LOG_TYPE_CRIT, "Couldn't resize global hna hash table \n");
		else
			hna_global_hash = swaphash;
	}

	spin_unlock_irqrestore(&hna_global_hash_lock, flags);
}

int hna_global_fill_buffer_text(unsigned char *buff, int buff_len)
{
	struct hna_global_entry *hna_global_entry;
	struct hash_it_t *hashit = NULL;
	int bytes_written = 0;
	unsigned long flags;

	spin_lock_irqsave(&hna_global_hash_lock, flags);

	while (NULL != (hashit = hash_iterate(hna_global_hash, hashit))) {
		if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 10)
			break;

		hna_global_entry = hashit->bucket->data;

		bytes_written += snprintf(buff + bytes_written,
					  (2 * ETH_STR_LEN) + 10,
					  " * %02x:%02x:%02x:%02x:%02x:%02x via %02x:%02x:%02x:%02x:%02x:%02x \n",
					  hna_global_entry->addr[0],
					  hna_global_entry->addr[1],
					  hna_global_entry->addr[2],
					  hna_global_entry->addr[3],
					  hna_global_entry->addr[4],
					  hna_global_entry->addr[5],
					  hna_global_entry->orig_node->orig[0],
					  hna_global_entry->orig_node->orig[1],
					  hna_global_entry->orig_node->orig[2],
					  hna_global_entry->orig_node->orig[3],
					  hna_global_entry->orig_node->orig[4],
					  hna_global_entry->orig_node->orig[5]);
	}

	spin_unlock_irqrestore(&hna_global_hash_lock, flags);

	return bytes_written;
}

void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
			  char *message)
{
	char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN];

	addr_to_string(orig_str, hna_global_entry->orig_node->orig);
	addr_to_string(hna_str, hna_global_entry->addr);

	debug_log(LOG_TYPE_ROUTES, "Deleting global hna entry %s (via %s): %s \n", hna_str, orig_str, message);

	hash_remove(hna_global_hash, hna_global_entry->addr);
	kfree(hna_global_entry);
}

void hna_global_del_orig(struct orig_node *orig_node, char *message)
{
	struct hna_global_entry *hna_global_entry;
	int hna_buff_count = 0;
	unsigned long flags;
	unsigned char *hna_ptr;

	if (orig_node->hna_buff_len == 0)
		return;

	spin_lock_irqsave(&hna_global_hash_lock, flags);

	while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) {
		hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN);
		hna_global_entry = (struct hna_global_entry *)
			hash_find(hna_global_hash, hna_ptr);

		if ((hna_global_entry != NULL) &&
		    (hna_global_entry->orig_node == orig_node))
			_hna_global_del_orig(hna_global_entry, message);

		hna_buff_count++;
	}

	spin_unlock_irqrestore(&hna_global_hash_lock, flags);

	orig_node->hna_buff_len = 0;
	kfree(orig_node->hna_buff);
	orig_node->hna_buff = NULL;
}

static void hna_global_del(void *data)
{
	kfree(data);
}

void hna_global_free(void)
{
	if (!hna_global_hash)
		return;

	hash_delete(hna_global_hash, hna_global_del);
	hna_global_hash = NULL;
}

struct orig_node *transtable_search(uint8_t *addr)
{
	struct hna_global_entry *hna_global_entry;
	unsigned long flags;

	spin_lock_irqsave(&hna_global_hash_lock, flags);
	hna_global_entry = (struct hna_global_entry *)
		hash_find(hna_global_hash, addr);
	spin_unlock_irqrestore(&hna_global_hash_lock, flags);

	if (hna_global_entry == NULL)
		return NULL;

	return hna_global_entry->orig_node;
}
