/*
 * Copyright (C) 2009-2011 B.A.T.M.A.N. contributors:
 *
 * Marek Lindner
 *
 * 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 "gateway_client.h"
#include "gateway_common.h"
#include "hard-interface.h"
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/udp.h>
#include <linux/if_vlan.h>

static void gw_node_free_ref(struct gw_node *gw_node)
{
	if (atomic_dec_and_test(&gw_node->refcount))
		kfree_rcu(gw_node, rcu);
}

void *gw_get_selected(struct bat_priv *bat_priv)
{
	struct gw_node *curr_gateway_tmp;
	struct orig_node *orig_node = NULL;

	rcu_read_lock();
	curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw);
	if (!curr_gateway_tmp)
		goto out;

	orig_node = curr_gateway_tmp->orig_node;
	if (!orig_node)
		goto out;

	if (!atomic_inc_not_zero(&orig_node->refcount))
		orig_node = NULL;

out:
	rcu_read_unlock();
	return orig_node;
}

void gw_deselect(struct bat_priv *bat_priv)
{
	struct gw_node *gw_node;

	spin_lock_bh(&bat_priv->gw_list_lock);
	gw_node = rcu_dereference(bat_priv->curr_gw);
	rcu_assign_pointer(bat_priv->curr_gw, NULL);
	spin_unlock_bh(&bat_priv->gw_list_lock);

	if (gw_node)
		gw_node_free_ref(gw_node);
}

static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node)
{
	struct gw_node *curr_gw_node;

	if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount))
		new_gw_node = NULL;

	spin_lock_bh(&bat_priv->gw_list_lock);
	curr_gw_node = rcu_dereference(bat_priv->curr_gw);
	rcu_assign_pointer(bat_priv->curr_gw, new_gw_node);
	spin_unlock_bh(&bat_priv->gw_list_lock);

	if (curr_gw_node)
		gw_node_free_ref(curr_gw_node);
}

void gw_election(struct bat_priv *bat_priv)
{
	struct hlist_node *node;
	struct gw_node *gw_node, *curr_gw, *curr_gw_tmp = NULL;
	uint8_t max_tq = 0;
	uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
	int down, up;

	/**
	 * The batman daemon checks here if we already passed a full originator
	 * cycle in order to make sure we don't choose the first gateway we
	 * hear about. This check is based on the daemon's uptime which we
	 * don't have.
	 **/
	if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT)
		return;

	rcu_read_lock();
	curr_gw = rcu_dereference(bat_priv->curr_gw);
	if (curr_gw) {
		rcu_read_unlock();
		return;
	}

	if (hlist_empty(&bat_priv->gw_list)) {

		if (curr_gw) {
			rcu_read_unlock();
			bat_dbg(DBG_BATMAN, bat_priv,
				"Removing selected gateway - "
				"no gateway in range\n");
			gw_deselect(bat_priv);
		} else
			rcu_read_unlock();

		return;
	}

	hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
		if (!gw_node->orig_node->router)
			continue;

		if (gw_node->deleted)
			continue;

		switch (atomic_read(&bat_priv->gw_sel_class)) {
		case 1: /* fast connection */
			gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags,
					     &down, &up);

			tmp_gw_factor = (gw_node->orig_node->router->tq_avg *
					 gw_node->orig_node->router->tq_avg *
					 down * 100 * 100) /
					 (TQ_LOCAL_WINDOW_SIZE *
					 TQ_LOCAL_WINDOW_SIZE * 64);

			if ((tmp_gw_factor > max_gw_factor) ||
			    ((tmp_gw_factor == max_gw_factor) &&
			     (gw_node->orig_node->router->tq_avg > max_tq)))
				curr_gw_tmp = gw_node;
			break;

		default: /**
			  * 2:  stable connection (use best statistic)
			  * 3:  fast-switch (use best statistic but change as
			  *     soon as a better gateway appears)
			  * XX: late-switch (use best statistic but change as
			  *     soon as a better gateway appears which has
			  *     $routing_class more tq points)
			  **/
			if (gw_node->orig_node->router->tq_avg > max_tq)
				curr_gw_tmp = gw_node;
			break;
		}

		if (gw_node->orig_node->router->tq_avg > max_tq)
			max_tq = gw_node->orig_node->router->tq_avg;

		if (tmp_gw_factor > max_gw_factor)
			max_gw_factor = tmp_gw_factor;
	}

	if (curr_gw != curr_gw_tmp) {
		if ((curr_gw) && (!curr_gw_tmp))
			bat_dbg(DBG_BATMAN, bat_priv,
				"Removing selected gateway - "
				"no gateway in range\n");
		else if ((!curr_gw) && (curr_gw_tmp))
			bat_dbg(DBG_BATMAN, bat_priv,
				"Adding route to gateway %pM "
				"(gw_flags: %i, tq: %i)\n",
				curr_gw_tmp->orig_node->orig,
				curr_gw_tmp->orig_node->gw_flags,
				curr_gw_tmp->orig_node->router->tq_avg);
		else
			bat_dbg(DBG_BATMAN, bat_priv,
				"Changing route to gateway %pM "
				"(gw_flags: %i, tq: %i)\n",
				curr_gw_tmp->orig_node->orig,
				curr_gw_tmp->orig_node->gw_flags,
				curr_gw_tmp->orig_node->router->tq_avg);

		gw_select(bat_priv, curr_gw_tmp);
	}

	rcu_read_unlock();
}

void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node)
{
	struct gw_node *curr_gateway_tmp;
	uint8_t gw_tq_avg, orig_tq_avg;

	rcu_read_lock();
	curr_gateway_tmp = rcu_dereference(bat_priv->curr_gw);
	if (!curr_gateway_tmp)
		goto out_rcu;

	if (!curr_gateway_tmp->orig_node)
		goto deselect_rcu;

	if (!curr_gateway_tmp->orig_node->router)
		goto deselect_rcu;

	/* this node already is the gateway */
	if (curr_gateway_tmp->orig_node == orig_node)
		goto out_rcu;

	if (!orig_node->router)
		goto out_rcu;

	gw_tq_avg = curr_gateway_tmp->orig_node->router->tq_avg;
	rcu_read_unlock();

	orig_tq_avg = orig_node->router->tq_avg;

	/* the TQ value has to be better */
	if (orig_tq_avg < gw_tq_avg)
		goto out;

	/**
	 * if the routing class is greater than 3 the value tells us how much
	 * greater the TQ value of the new gateway must be
	 **/
	if ((atomic_read(&bat_priv->gw_sel_class) > 3) &&
	    (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class)))
		goto out;

	bat_dbg(DBG_BATMAN, bat_priv,
		"Restarting gateway selection: better gateway found (tq curr: "
		"%i, tq new: %i)\n",
		gw_tq_avg, orig_tq_avg);
	goto deselect;

out_rcu:
	rcu_read_unlock();
	goto out;
deselect_rcu:
	rcu_read_unlock();
deselect:
	gw_deselect(bat_priv);
out:
	return;
}

static void gw_node_add(struct bat_priv *bat_priv,
			struct orig_node *orig_node, uint8_t new_gwflags)
{
	struct gw_node *gw_node;
	int down, up;

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

	memset(gw_node, 0, sizeof(struct gw_node));
	INIT_HLIST_NODE(&gw_node->list);
	gw_node->orig_node = orig_node;
	atomic_set(&gw_node->refcount, 1);

	spin_lock_bh(&bat_priv->gw_list_lock);
	hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list);
	spin_unlock_bh(&bat_priv->gw_list_lock);

	gw_bandwidth_to_kbit(new_gwflags, &down, &up);
	bat_dbg(DBG_BATMAN, bat_priv,
		"Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n",
		orig_node->orig, new_gwflags,
		(down > 2048 ? down / 1024 : down),
		(down > 2048 ? "MBit" : "KBit"),
		(up > 2048 ? up / 1024 : up),
		(up > 2048 ? "MBit" : "KBit"));
}

void gw_node_update(struct bat_priv *bat_priv,
		    struct orig_node *orig_node, uint8_t new_gwflags)
{
	struct hlist_node *node;
	struct gw_node *gw_node;

	rcu_read_lock();
	hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
		if (gw_node->orig_node != orig_node)
			continue;

		bat_dbg(DBG_BATMAN, bat_priv,
			"Gateway class of originator %pM changed from "
			"%i to %i\n",
			orig_node->orig, gw_node->orig_node->gw_flags,
			new_gwflags);

		gw_node->deleted = 0;

		if (new_gwflags == 0) {
			gw_node->deleted = jiffies;
			bat_dbg(DBG_BATMAN, bat_priv,
				"Gateway %pM removed from gateway list\n",
				orig_node->orig);

			if (gw_node == rcu_dereference(bat_priv->curr_gw)) {
				rcu_read_unlock();
				gw_deselect(bat_priv);
				return;
			}
		}

		rcu_read_unlock();
		return;
	}
	rcu_read_unlock();

	if (new_gwflags == 0)
		return;

	gw_node_add(bat_priv, orig_node, new_gwflags);
}

void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node)
{
	return gw_node_update(bat_priv, orig_node, 0);
}

void gw_node_purge(struct bat_priv *bat_priv)
{
	struct gw_node *gw_node;
	struct hlist_node *node, *node_tmp;
	unsigned long timeout = 2 * PURGE_TIMEOUT * HZ;

	spin_lock_bh(&bat_priv->gw_list_lock);

	hlist_for_each_entry_safe(gw_node, node, node_tmp,
				  &bat_priv->gw_list, list) {
		if (((!gw_node->deleted) ||
		     (time_before(jiffies, gw_node->deleted + timeout))) &&
		    atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)
			continue;

		if (rcu_dereference(bat_priv->curr_gw) == gw_node)
			gw_deselect(bat_priv);

		hlist_del_rcu(&gw_node->list);
		gw_node_free_ref(gw_node);
	}


	spin_unlock_bh(&bat_priv->gw_list_lock);
}

static int _write_buffer_text(struct bat_priv *bat_priv,
			      struct seq_file *seq, struct gw_node *gw_node)
{
	struct gw_node *curr_gw;
	int down, up, ret;

	gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up);

	rcu_read_lock();
	curr_gw = rcu_dereference(bat_priv->curr_gw);

	ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n",
		       (curr_gw == gw_node ? "=>" : "  "),
		       gw_node->orig_node->orig,
		       gw_node->orig_node->router->tq_avg,
		       gw_node->orig_node->router->addr,
		       gw_node->orig_node->router->if_incoming->net_dev->name,
		       gw_node->orig_node->gw_flags,
		       (down > 2048 ? down / 1024 : down),
		       (down > 2048 ? "MBit" : "KBit"),
		       (up > 2048 ? up / 1024 : up),
		       (up > 2048 ? "MBit" : "KBit"));

	rcu_read_unlock();
	return ret;
}

int gw_client_seq_print_text(struct seq_file *seq, void *offset)
{
	struct net_device *net_dev = (struct net_device *)seq->private;
	struct bat_priv *bat_priv = netdev_priv(net_dev);
	struct gw_node *gw_node;
	struct hlist_node *node;
	int gw_count = 0;

	if (!bat_priv->primary_if) {

		return seq_printf(seq, "BATMAN mesh %s disabled - please "
				  "specify interfaces to enable it\n",
				  net_dev->name);
	}

	if (bat_priv->primary_if->if_status != IF_ACTIVE) {

		return seq_printf(seq, "BATMAN mesh %s disabled - "
				       "primary interface not active\n",
				       net_dev->name);
	}

	seq_printf(seq, "      %-12s (%s/%i) %17s [%10s]: gw_class ... "
		   "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
		   "Gateway", "#", TQ_MAX_VALUE, "Nexthop",
		   "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR,
		   bat_priv->primary_if->net_dev->name,
		   bat_priv->primary_if->net_dev->dev_addr, net_dev->name);

	rcu_read_lock();
	hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
		if (gw_node->deleted)
			continue;

		if (!gw_node->orig_node->router)
			continue;

		_write_buffer_text(bat_priv, seq, gw_node);
		gw_count++;
	}
	rcu_read_unlock();

	if (gw_count == 0)
		seq_printf(seq, "No gateways in range ...\n");

	return 0;
}

int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
{
	struct ethhdr *ethhdr;
	struct iphdr *iphdr;
	struct ipv6hdr *ipv6hdr;
	struct udphdr *udphdr;
	unsigned int header_len = 0;

	if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF)
		return 0;

	/* check for ethernet header */
	if (!pskb_may_pull(skb, header_len + ETH_HLEN))
		return 0;
	ethhdr = (struct ethhdr *)skb->data;
	header_len += ETH_HLEN;

	/* check for initial vlan header */
	if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
		if (!pskb_may_pull(skb, header_len + VLAN_HLEN))
			return 0;
		ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
		header_len += VLAN_HLEN;
	}

	/* check for ip header */
	switch (ntohs(ethhdr->h_proto)) {
	case ETH_P_IP:
		if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr)))
			return 0;
		iphdr = (struct iphdr *)(skb->data + header_len);
		header_len += iphdr->ihl * 4;

		/* check for udp header */
		if (iphdr->protocol != IPPROTO_UDP)
			return 0;

		break;
	case ETH_P_IPV6:
		if (!pskb_may_pull(skb, header_len + sizeof(struct ipv6hdr)))
			return 0;
		ipv6hdr = (struct ipv6hdr *)(skb->data + header_len);
		header_len += sizeof(struct ipv6hdr);

		/* check for udp header */
		if (ipv6hdr->nexthdr != IPPROTO_UDP)
			return 0;

		break;
	default:
		return 0;
	}

	if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr)))
		return 0;
	udphdr = (struct udphdr *)(skb->data + header_len);
	header_len += sizeof(struct udphdr);

	/* check for bootp port */
	if ((ntohs(ethhdr->h_proto) == ETH_P_IP) &&
	     (ntohs(udphdr->dest) != 67))
		return 0;

	if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) &&
	    (ntohs(udphdr->dest) != 547))
		return 0;

	if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)
		return -1;

	rcu_read_lock();
	if (!rcu_dereference(bat_priv->curr_gw)) {
		rcu_read_unlock();
		return 0;
	}
	rcu_read_unlock();

	return 1;
}
