/* Copyright (C) 2008-2012 B.A.T.M.A.N. contributors:
 *
 * 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 "send.h"
#include "translation-table.h"
#include "vis.h"
#include "soft-interface.h"
#include "hard-interface.h"
#include "hash.h"
#include "originator.h"

#define BATADV_MAX_VIS_PACKET_SIZE 1000

static void batadv_start_vis_timer(struct batadv_priv *bat_priv);

/* free the info */
static void batadv_free_info(struct kref *ref)
{
	struct batadv_vis_info *info;
	struct batadv_priv *bat_priv;
	struct batadv_recvlist_node *entry, *tmp;

	info = container_of(ref, struct batadv_vis_info, refcount);
	bat_priv = info->bat_priv;

	list_del_init(&info->send_list);
	spin_lock_bh(&bat_priv->vis.list_lock);
	list_for_each_entry_safe(entry, tmp, &info->recv_list, list) {
		list_del(&entry->list);
		kfree(entry);
	}

	spin_unlock_bh(&bat_priv->vis.list_lock);
	kfree_skb(info->skb_packet);
	kfree(info);
}

/* Compare two vis packets, used by the hashing algorithm */
static int batadv_vis_info_cmp(const struct hlist_node *node, const void *data2)
{
	const struct batadv_vis_info *d1, *d2;
	const struct batadv_vis_packet *p1, *p2;

	d1 = container_of(node, struct batadv_vis_info, hash_entry);
	d2 = data2;
	p1 = (struct batadv_vis_packet *)d1->skb_packet->data;
	p2 = (struct batadv_vis_packet *)d2->skb_packet->data;
	return batadv_compare_eth(p1->vis_orig, p2->vis_orig);
}

/* hash function to choose an entry in a hash table of given size
 * hash algorithm from http://en.wikipedia.org/wiki/Hash_table
 */
static uint32_t batadv_vis_info_choose(const void *data, uint32_t size)
{
	const struct batadv_vis_info *vis_info = data;
	const struct batadv_vis_packet *packet;
	const unsigned char *key;
	uint32_t hash = 0;
	size_t i;

	packet = (struct batadv_vis_packet *)vis_info->skb_packet->data;
	key = packet->vis_orig;
	for (i = 0; i < ETH_ALEN; i++) {
		hash += key[i];
		hash += (hash << 10);
		hash ^= (hash >> 6);
	}

	hash += (hash << 3);
	hash ^= (hash >> 11);
	hash += (hash << 15);

	return hash % size;
}

static struct batadv_vis_info *
batadv_vis_hash_find(struct batadv_priv *bat_priv, const void *data)
{
	struct batadv_hashtable *hash = bat_priv->vis.hash;
	struct hlist_head *head;
	struct hlist_node *node;
	struct batadv_vis_info *vis_info, *vis_info_tmp = NULL;
	uint32_t index;

	if (!hash)
		return NULL;

	index = batadv_vis_info_choose(data, hash->size);
	head = &hash->table[index];

	rcu_read_lock();
	hlist_for_each_entry_rcu(vis_info, node, head, hash_entry) {
		if (!batadv_vis_info_cmp(node, data))
			continue;

		vis_info_tmp = vis_info;
		break;
	}
	rcu_read_unlock();

	return vis_info_tmp;
}

/* insert interface to the list of interfaces of one originator, if it
 * does not already exist in the list
 */
static void batadv_vis_data_insert_interface(const uint8_t *interface,
					     struct hlist_head *if_list,
					     bool primary)
{
	struct batadv_if_list_entry *entry;
	struct hlist_node *pos;

	hlist_for_each_entry(entry, pos, if_list, list) {
		if (batadv_compare_eth(entry->addr, interface))
			return;
	}

	/* it's a new address, add it to the list */
	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
	if (!entry)
		return;
	memcpy(entry->addr, interface, ETH_ALEN);
	entry->primary = primary;
	hlist_add_head(&entry->list, if_list);
}

static void batadv_vis_data_read_prim_sec(struct seq_file *seq,
					  const struct hlist_head *if_list)
{
	struct batadv_if_list_entry *entry;
	struct hlist_node *pos;

	hlist_for_each_entry(entry, pos, if_list, list) {
		if (entry->primary)
			seq_printf(seq, "PRIMARY, ");
		else
			seq_printf(seq,  "SEC %pM, ", entry->addr);
	}
}

/* read an entry  */
static ssize_t
batadv_vis_data_read_entry(struct seq_file *seq,
			   const struct batadv_vis_info_entry *entry,
			   const uint8_t *src, bool primary)
{
	if (primary && entry->quality == 0)
		return seq_printf(seq, "TT %pM, ", entry->dest);
	else if (batadv_compare_eth(entry->src, src))
		return seq_printf(seq, "TQ %pM %d, ", entry->dest,
				  entry->quality);

	return 0;
}

static void
batadv_vis_data_insert_interfaces(struct hlist_head *list,
				  struct batadv_vis_packet *packet,
				  struct batadv_vis_info_entry *entries)
{
	int i;

	for (i = 0; i < packet->entries; i++) {
		if (entries[i].quality == 0)
			continue;

		if (batadv_compare_eth(entries[i].src, packet->vis_orig))
			continue;

		batadv_vis_data_insert_interface(entries[i].src, list, false);
	}
}

static void batadv_vis_data_read_entries(struct seq_file *seq,
					 struct hlist_head *list,
					 struct batadv_vis_packet *packet,
					 struct batadv_vis_info_entry *entries)
{
	int i;
	struct batadv_if_list_entry *entry;
	struct hlist_node *pos;

	hlist_for_each_entry(entry, pos, list, list) {
		seq_printf(seq, "%pM,", entry->addr);

		for (i = 0; i < packet->entries; i++)
			batadv_vis_data_read_entry(seq, &entries[i],
						   entry->addr, entry->primary);

		/* add primary/secondary records */
		if (batadv_compare_eth(entry->addr, packet->vis_orig))
			batadv_vis_data_read_prim_sec(seq, list);

		seq_printf(seq, "\n");
	}
}

static void batadv_vis_seq_print_text_bucket(struct seq_file *seq,
					     const struct hlist_head *head)
{
	struct hlist_node *node;
	struct batadv_vis_info *info;
	struct batadv_vis_packet *packet;
	uint8_t *entries_pos;
	struct batadv_vis_info_entry *entries;
	struct batadv_if_list_entry *entry;
	struct hlist_node *pos, *n;

	HLIST_HEAD(vis_if_list);

	hlist_for_each_entry_rcu(info, node, head, hash_entry) {
		packet = (struct batadv_vis_packet *)info->skb_packet->data;
		entries_pos = (uint8_t *)packet + sizeof(*packet);
		entries = (struct batadv_vis_info_entry *)entries_pos;

		batadv_vis_data_insert_interface(packet->vis_orig, &vis_if_list,
						 true);
		batadv_vis_data_insert_interfaces(&vis_if_list, packet,
						  entries);
		batadv_vis_data_read_entries(seq, &vis_if_list, packet,
					     entries);

		hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
			hlist_del(&entry->list);
			kfree(entry);
		}
	}
}

int batadv_vis_seq_print_text(struct seq_file *seq, void *offset)
{
	struct batadv_hard_iface *primary_if;
	struct hlist_head *head;
	struct net_device *net_dev = (struct net_device *)seq->private;
	struct batadv_priv *bat_priv = netdev_priv(net_dev);
	struct batadv_hashtable *hash = bat_priv->vis.hash;
	uint32_t i;
	int ret = 0;
	int vis_server = atomic_read(&bat_priv->vis_mode);

	primary_if = batadv_primary_if_get_selected(bat_priv);
	if (!primary_if)
		goto out;

	if (vis_server == BATADV_VIS_TYPE_CLIENT_UPDATE)
		goto out;

	spin_lock_bh(&bat_priv->vis.hash_lock);
	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];
		batadv_vis_seq_print_text_bucket(seq, head);
	}
	spin_unlock_bh(&bat_priv->vis.hash_lock);

out:
	if (primary_if)
		batadv_hardif_free_ref(primary_if);
	return ret;
}

/* add the info packet to the send list, if it was not
 * already linked in.
 */
static void batadv_send_list_add(struct batadv_priv *bat_priv,
				 struct batadv_vis_info *info)
{
	if (list_empty(&info->send_list)) {
		kref_get(&info->refcount);
		list_add_tail(&info->send_list, &bat_priv->vis.send_list);
	}
}

/* delete the info packet from the send list, if it was
 * linked in.
 */
static void batadv_send_list_del(struct batadv_vis_info *info)
{
	if (!list_empty(&info->send_list)) {
		list_del_init(&info->send_list);
		kref_put(&info->refcount, batadv_free_info);
	}
}

/* tries to add one entry to the receive list. */
static void batadv_recv_list_add(struct batadv_priv *bat_priv,
				 struct list_head *recv_list, const char *mac)
{
	struct batadv_recvlist_node *entry;

	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
	if (!entry)
		return;

	memcpy(entry->mac, mac, ETH_ALEN);
	spin_lock_bh(&bat_priv->vis.list_lock);
	list_add_tail(&entry->list, recv_list);
	spin_unlock_bh(&bat_priv->vis.list_lock);
}

/* returns 1 if this mac is in the recv_list */
static int batadv_recv_list_is_in(struct batadv_priv *bat_priv,
				  const struct list_head *recv_list,
				  const char *mac)
{
	const struct batadv_recvlist_node *entry;

	spin_lock_bh(&bat_priv->vis.list_lock);
	list_for_each_entry(entry, recv_list, list) {
		if (batadv_compare_eth(entry->mac, mac)) {
			spin_unlock_bh(&bat_priv->vis.list_lock);
			return 1;
		}
	}
	spin_unlock_bh(&bat_priv->vis.list_lock);
	return 0;
}

/* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old,
 * broken.. ).	vis hash must be locked outside.  is_new is set when the packet
 * is newer than old entries in the hash.
 */
static struct batadv_vis_info *
batadv_add_packet(struct batadv_priv *bat_priv,
		  struct batadv_vis_packet *vis_packet, int vis_info_len,
		  int *is_new, int make_broadcast)
{
	struct batadv_vis_info *info, *old_info;
	struct batadv_vis_packet *search_packet, *old_packet;
	struct batadv_vis_info search_elem;
	struct batadv_vis_packet *packet;
	struct sk_buff *tmp_skb;
	int hash_added;
	size_t len;
	size_t max_entries;

	*is_new = 0;
	/* sanity check */
	if (!bat_priv->vis.hash)
		return NULL;

	/* see if the packet is already in vis_hash */
	search_elem.skb_packet = dev_alloc_skb(sizeof(*search_packet));
	if (!search_elem.skb_packet)
		return NULL;
	len = sizeof(*search_packet);
	tmp_skb = search_elem.skb_packet;
	search_packet = (struct batadv_vis_packet *)skb_put(tmp_skb, len);

	memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN);
	old_info = batadv_vis_hash_find(bat_priv, &search_elem);
	kfree_skb(search_elem.skb_packet);

	if (old_info) {
		tmp_skb = old_info->skb_packet;
		old_packet = (struct batadv_vis_packet *)tmp_skb->data;
		if (!batadv_seq_after(ntohl(vis_packet->seqno),
				      ntohl(old_packet->seqno))) {
			if (old_packet->seqno == vis_packet->seqno) {
				batadv_recv_list_add(bat_priv,
						     &old_info->recv_list,
						     vis_packet->sender_orig);
				return old_info;
			} else {
				/* newer packet is already in hash. */
				return NULL;
			}
		}
		/* remove old entry */
		batadv_hash_remove(bat_priv->vis.hash, batadv_vis_info_cmp,
				   batadv_vis_info_choose, old_info);
		batadv_send_list_del(old_info);
		kref_put(&old_info->refcount, batadv_free_info);
	}

	info = kmalloc(sizeof(*info), GFP_ATOMIC);
	if (!info)
		return NULL;

	len = sizeof(*packet) + vis_info_len;
	info->skb_packet = dev_alloc_skb(len + ETH_HLEN + NET_IP_ALIGN);
	if (!info->skb_packet) {
		kfree(info);
		return NULL;
	}
	skb_reserve(info->skb_packet, ETH_HLEN + NET_IP_ALIGN);
	packet = (struct batadv_vis_packet *)skb_put(info->skb_packet, len);

	kref_init(&info->refcount);
	INIT_LIST_HEAD(&info->send_list);
	INIT_LIST_HEAD(&info->recv_list);
	info->first_seen = jiffies;
	info->bat_priv = bat_priv;
	memcpy(packet, vis_packet, len);

	/* initialize and add new packet. */
	*is_new = 1;

	/* Make it a broadcast packet, if required */
	if (make_broadcast)
		memcpy(packet->target_orig, batadv_broadcast_addr, ETH_ALEN);

	/* repair if entries is longer than packet. */
	max_entries = vis_info_len / sizeof(struct batadv_vis_info_entry);
	if (packet->entries > max_entries)
		packet->entries = max_entries;

	batadv_recv_list_add(bat_priv, &info->recv_list, packet->sender_orig);

	/* try to add it */
	hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp,
				     batadv_vis_info_choose, info,
				     &info->hash_entry);
	if (hash_added != 0) {
		/* did not work (for some reason) */
		kref_put(&info->refcount, batadv_free_info);
		info = NULL;
	}

	return info;
}

/* handle the server sync packet, forward if needed. */
void batadv_receive_server_sync_packet(struct batadv_priv *bat_priv,
				       struct batadv_vis_packet *vis_packet,
				       int vis_info_len)
{
	struct batadv_vis_info *info;
	int is_new, make_broadcast;
	int vis_server = atomic_read(&bat_priv->vis_mode);

	make_broadcast = (vis_server == BATADV_VIS_TYPE_SERVER_SYNC);

	spin_lock_bh(&bat_priv->vis.hash_lock);
	info = batadv_add_packet(bat_priv, vis_packet, vis_info_len,
				 &is_new, make_broadcast);
	if (!info)
		goto end;

	/* only if we are server ourselves and packet is newer than the one in
	 * hash.
	 */
	if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC && is_new)
		batadv_send_list_add(bat_priv, info);
end:
	spin_unlock_bh(&bat_priv->vis.hash_lock);
}

/* handle an incoming client update packet and schedule forward if needed. */
void batadv_receive_client_update_packet(struct batadv_priv *bat_priv,
					 struct batadv_vis_packet *vis_packet,
					 int vis_info_len)
{
	struct batadv_vis_info *info;
	struct batadv_vis_packet *packet;
	int is_new;
	int vis_server = atomic_read(&bat_priv->vis_mode);
	int are_target = 0;

	/* clients shall not broadcast. */
	if (is_broadcast_ether_addr(vis_packet->target_orig))
		return;

	/* Are we the target for this VIS packet? */
	if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC	&&
	    batadv_is_my_mac(vis_packet->target_orig))
		are_target = 1;

	spin_lock_bh(&bat_priv->vis.hash_lock);
	info = batadv_add_packet(bat_priv, vis_packet, vis_info_len,
				 &is_new, are_target);

	if (!info)
		goto end;
	/* note that outdated packets will be dropped at this point. */

	packet = (struct batadv_vis_packet *)info->skb_packet->data;

	/* send only if we're the target server or ... */
	if (are_target && is_new) {
		packet->vis_type = BATADV_VIS_TYPE_SERVER_SYNC;	/* upgrade! */
		batadv_send_list_add(bat_priv, info);

		/* ... we're not the recipient (and thus need to forward). */
	} else if (!batadv_is_my_mac(packet->target_orig)) {
		batadv_send_list_add(bat_priv, info);
	}

end:
	spin_unlock_bh(&bat_priv->vis.hash_lock);
}

/* Walk the originators and find the VIS server with the best tq. Set the packet
 * address to its address and return the best_tq.
 *
 * Must be called with the originator hash locked
 */
static int batadv_find_best_vis_server(struct batadv_priv *bat_priv,
				       struct batadv_vis_info *info)
{
	struct batadv_hashtable *hash = bat_priv->orig_hash;
	struct batadv_neigh_node *router;
	struct hlist_node *node;
	struct hlist_head *head;
	struct batadv_orig_node *orig_node;
	struct batadv_vis_packet *packet;
	int best_tq = -1;
	uint32_t i;

	packet = (struct batadv_vis_packet *)info->skb_packet->data;

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

		rcu_read_lock();
		hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
			router = batadv_orig_node_get_router(orig_node);
			if (!router)
				continue;

			if ((orig_node->flags & BATADV_VIS_SERVER) &&
			    (router->tq_avg > best_tq)) {
				best_tq = router->tq_avg;
				memcpy(packet->target_orig, orig_node->orig,
				       ETH_ALEN);
			}
			batadv_neigh_node_free_ref(router);
		}
		rcu_read_unlock();
	}

	return best_tq;
}

/* Return true if the vis packet is full. */
static bool batadv_vis_packet_full(const struct batadv_vis_info *info)
{
	const struct batadv_vis_packet *packet;
	size_t num;

	packet = (struct batadv_vis_packet *)info->skb_packet->data;
	num = BATADV_MAX_VIS_PACKET_SIZE / sizeof(struct batadv_vis_info_entry);

	if (num < packet->entries + 1)
		return true;
	return false;
}

/* generates a packet of own vis data,
 * returns 0 on success, -1 if no packet could be generated
 */
static int batadv_generate_vis_packet(struct batadv_priv *bat_priv)
{
	struct batadv_hashtable *hash = bat_priv->orig_hash;
	struct hlist_node *node;
	struct hlist_head *head;
	struct batadv_orig_node *orig_node;
	struct batadv_neigh_node *router;
	struct batadv_vis_info *info = bat_priv->vis.my_info;
	struct batadv_vis_packet *packet;
	struct batadv_vis_info_entry *entry;
	struct batadv_tt_common_entry *tt_common_entry;
	uint8_t *packet_pos;
	int best_tq = -1;
	uint32_t i;

	info->first_seen = jiffies;
	packet = (struct batadv_vis_packet *)info->skb_packet->data;
	packet->vis_type = atomic_read(&bat_priv->vis_mode);

	memcpy(packet->target_orig, batadv_broadcast_addr, ETH_ALEN);
	packet->header.ttl = BATADV_TTL;
	packet->seqno = htonl(ntohl(packet->seqno) + 1);
	packet->entries = 0;
	packet->reserved = 0;
	skb_trim(info->skb_packet, sizeof(*packet));

	if (packet->vis_type == BATADV_VIS_TYPE_CLIENT_UPDATE) {
		best_tq = batadv_find_best_vis_server(bat_priv, info);

		if (best_tq < 0)
			return best_tq;
	}

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

		rcu_read_lock();
		hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
			router = batadv_orig_node_get_router(orig_node);
			if (!router)
				continue;

			if (!batadv_compare_eth(router->addr, orig_node->orig))
				goto next;

			if (router->if_incoming->if_status != BATADV_IF_ACTIVE)
				goto next;

			if (router->tq_avg < 1)
				goto next;

			/* fill one entry into buffer. */
			packet_pos = skb_put(info->skb_packet, sizeof(*entry));
			entry = (struct batadv_vis_info_entry *)packet_pos;
			memcpy(entry->src,
			       router->if_incoming->net_dev->dev_addr,
			       ETH_ALEN);
			memcpy(entry->dest, orig_node->orig, ETH_ALEN);
			entry->quality = router->tq_avg;
			packet->entries++;

next:
			batadv_neigh_node_free_ref(router);

			if (batadv_vis_packet_full(info))
				goto unlock;
		}
		rcu_read_unlock();
	}

	hash = bat_priv->tt.local_hash;

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

		rcu_read_lock();
		hlist_for_each_entry_rcu(tt_common_entry, node, head,
					 hash_entry) {
			packet_pos = skb_put(info->skb_packet, sizeof(*entry));
			entry = (struct batadv_vis_info_entry *)packet_pos;
			memset(entry->src, 0, ETH_ALEN);
			memcpy(entry->dest, tt_common_entry->addr, ETH_ALEN);
			entry->quality = 0; /* 0 means TT */
			packet->entries++;

			if (batadv_vis_packet_full(info))
				goto unlock;
		}
		rcu_read_unlock();
	}

	return 0;

unlock:
	rcu_read_unlock();
	return 0;
}

/* free old vis packets. Must be called with this vis_hash_lock
 * held
 */
static void batadv_purge_vis_packets(struct batadv_priv *bat_priv)
{
	uint32_t i;
	struct batadv_hashtable *hash = bat_priv->vis.hash;
	struct hlist_node *node, *node_tmp;
	struct hlist_head *head;
	struct batadv_vis_info *info;

	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

		hlist_for_each_entry_safe(info, node, node_tmp,
					  head, hash_entry) {
			/* never purge own data. */
			if (info == bat_priv->vis.my_info)
				continue;

			if (batadv_has_timed_out(info->first_seen,
						 BATADV_VIS_TIMEOUT)) {
				hlist_del(node);
				batadv_send_list_del(info);
				kref_put(&info->refcount, batadv_free_info);
			}
		}
	}
}

static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
					struct batadv_vis_info *info)
{
	struct batadv_hashtable *hash = bat_priv->orig_hash;
	struct hlist_node *node;
	struct hlist_head *head;
	struct batadv_orig_node *orig_node;
	struct batadv_vis_packet *packet;
	struct sk_buff *skb;
	uint32_t i;


	packet = (struct batadv_vis_packet *)info->skb_packet->data;

	/* send to all routers in range. */
	for (i = 0; i < hash->size; i++) {
		head = &hash->table[i];

		rcu_read_lock();
		hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) {
			/* if it's a vis server and reachable, send it. */
			if (!(orig_node->flags & BATADV_VIS_SERVER))
				continue;

			/* don't send it if we already received the packet from
			 * this node.
			 */
			if (batadv_recv_list_is_in(bat_priv, &info->recv_list,
						   orig_node->orig))
				continue;

			memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
			skb = skb_clone(info->skb_packet, GFP_ATOMIC);
			if (!skb)
				continue;

			if (!batadv_send_skb_to_orig(skb, orig_node, NULL))
				kfree_skb(skb);
		}
		rcu_read_unlock();
	}
}

static void batadv_unicast_vis_packet(struct batadv_priv *bat_priv,
				      struct batadv_vis_info *info)
{
	struct batadv_orig_node *orig_node;
	struct sk_buff *skb;
	struct batadv_vis_packet *packet;

	packet = (struct batadv_vis_packet *)info->skb_packet->data;

	orig_node = batadv_orig_hash_find(bat_priv, packet->target_orig);
	if (!orig_node)
		goto out;

	skb = skb_clone(info->skb_packet, GFP_ATOMIC);
	if (!skb)
		goto out;

	if (!batadv_send_skb_to_orig(skb, orig_node, NULL))
		kfree_skb(skb);

out:
	if (orig_node)
		batadv_orig_node_free_ref(orig_node);
}

/* only send one vis packet. called from batadv_send_vis_packets() */
static void batadv_send_vis_packet(struct batadv_priv *bat_priv,
				   struct batadv_vis_info *info)
{
	struct batadv_hard_iface *primary_if;
	struct batadv_vis_packet *packet;

	primary_if = batadv_primary_if_get_selected(bat_priv);
	if (!primary_if)
		goto out;

	packet = (struct batadv_vis_packet *)info->skb_packet->data;
	if (packet->header.ttl < 2) {
		pr_debug("Error - can't send vis packet: ttl exceeded\n");
		goto out;
	}

	memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
	packet->header.ttl--;

	if (is_broadcast_ether_addr(packet->target_orig))
		batadv_broadcast_vis_packet(bat_priv, info);
	else
		batadv_unicast_vis_packet(bat_priv, info);
	packet->header.ttl++; /* restore TTL */

out:
	if (primary_if)
		batadv_hardif_free_ref(primary_if);
}

/* called from timer; send (and maybe generate) vis packet. */
static void batadv_send_vis_packets(struct work_struct *work)
{
	struct delayed_work *delayed_work;
	struct batadv_priv *bat_priv;
	struct batadv_priv_vis *priv_vis;
	struct batadv_vis_info *info;

	delayed_work = container_of(work, struct delayed_work, work);
	priv_vis = container_of(delayed_work, struct batadv_priv_vis, work);
	bat_priv = container_of(priv_vis, struct batadv_priv, vis);
	spin_lock_bh(&bat_priv->vis.hash_lock);
	batadv_purge_vis_packets(bat_priv);

	if (batadv_generate_vis_packet(bat_priv) == 0) {
		/* schedule if generation was successful */
		batadv_send_list_add(bat_priv, bat_priv->vis.my_info);
	}

	while (!list_empty(&bat_priv->vis.send_list)) {
		info = list_first_entry(&bat_priv->vis.send_list,
					typeof(*info), send_list);

		kref_get(&info->refcount);
		spin_unlock_bh(&bat_priv->vis.hash_lock);

		batadv_send_vis_packet(bat_priv, info);

		spin_lock_bh(&bat_priv->vis.hash_lock);
		batadv_send_list_del(info);
		kref_put(&info->refcount, batadv_free_info);
	}
	spin_unlock_bh(&bat_priv->vis.hash_lock);
	batadv_start_vis_timer(bat_priv);
}

/* init the vis server. this may only be called when if_list is already
 * initialized (e.g. bat0 is initialized, interfaces have been added)
 */
int batadv_vis_init(struct batadv_priv *bat_priv)
{
	struct batadv_vis_packet *packet;
	int hash_added;
	unsigned int len;
	unsigned long first_seen;
	struct sk_buff *tmp_skb;

	if (bat_priv->vis.hash)
		return 0;

	spin_lock_bh(&bat_priv->vis.hash_lock);

	bat_priv->vis.hash = batadv_hash_new(256);
	if (!bat_priv->vis.hash) {
		pr_err("Can't initialize vis_hash\n");
		goto err;
	}

	bat_priv->vis.my_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
	if (!bat_priv->vis.my_info)
		goto err;

	len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE;
	len += ETH_HLEN + NET_IP_ALIGN;
	bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len);
	if (!bat_priv->vis.my_info->skb_packet)
		goto free_info;

	skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN + NET_IP_ALIGN);
	tmp_skb = bat_priv->vis.my_info->skb_packet;
	packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet));

	/* prefill the vis info */
	first_seen = jiffies - msecs_to_jiffies(BATADV_VIS_INTERVAL);
	bat_priv->vis.my_info->first_seen = first_seen;
	INIT_LIST_HEAD(&bat_priv->vis.my_info->recv_list);
	INIT_LIST_HEAD(&bat_priv->vis.my_info->send_list);
	kref_init(&bat_priv->vis.my_info->refcount);
	bat_priv->vis.my_info->bat_priv = bat_priv;
	packet->header.version = BATADV_COMPAT_VERSION;
	packet->header.packet_type = BATADV_VIS;
	packet->header.ttl = BATADV_TTL;
	packet->seqno = 0;
	packet->reserved = 0;
	packet->entries = 0;

	INIT_LIST_HEAD(&bat_priv->vis.send_list);

	hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp,
				     batadv_vis_info_choose,
				     bat_priv->vis.my_info,
				     &bat_priv->vis.my_info->hash_entry);
	if (hash_added != 0) {
		pr_err("Can't add own vis packet into hash\n");
		/* not in hash, need to remove it manually. */
		kref_put(&bat_priv->vis.my_info->refcount, batadv_free_info);
		goto err;
	}

	spin_unlock_bh(&bat_priv->vis.hash_lock);
	batadv_start_vis_timer(bat_priv);
	return 0;

free_info:
	kfree(bat_priv->vis.my_info);
	bat_priv->vis.my_info = NULL;
err:
	spin_unlock_bh(&bat_priv->vis.hash_lock);
	batadv_vis_quit(bat_priv);
	return -ENOMEM;
}

/* Decrease the reference count on a hash item info */
static void batadv_free_info_ref(struct hlist_node *node, void *arg)
{
	struct batadv_vis_info *info;

	info = container_of(node, struct batadv_vis_info, hash_entry);
	batadv_send_list_del(info);
	kref_put(&info->refcount, batadv_free_info);
}

/* shutdown vis-server */
void batadv_vis_quit(struct batadv_priv *bat_priv)
{
	if (!bat_priv->vis.hash)
		return;

	cancel_delayed_work_sync(&bat_priv->vis.work);

	spin_lock_bh(&bat_priv->vis.hash_lock);
	/* properly remove, kill timers ... */
	batadv_hash_delete(bat_priv->vis.hash, batadv_free_info_ref, NULL);
	bat_priv->vis.hash = NULL;
	bat_priv->vis.my_info = NULL;
	spin_unlock_bh(&bat_priv->vis.hash_lock);
}

/* schedule packets for (re)transmission */
static void batadv_start_vis_timer(struct batadv_priv *bat_priv)
{
	INIT_DELAYED_WORK(&bat_priv->vis.work, batadv_send_vis_packets);
	queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work,
			   msecs_to_jiffies(BATADV_VIS_INTERVAL));
}
