/*
 * net/tipc/bearer.c: TIPC bearer code
 * 
 * Copyright (c) 2003-2005, Ericsson Research Canada
 * Copyright (c) 2004-2005, Wind River Systems
 * Copyright (c) 2005-2006, Ericsson AB
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the names of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "core.h"
#include "config.h"
#include "dbg.h"
#include "bearer.h"
#include "link.h"
#include "port.h"
#include "discover.h"
#include "bcast.h"

#define MAX_ADDR_STR 32

static struct media *media_list = 0;
static u32 media_count = 0;

struct bearer *bearers = 0;

/**
 * media_name_valid - validate media name
 * 
 * Returns 1 if media name is valid, otherwise 0.
 */

static int media_name_valid(const char *name)
{
	u32 len;

	len = strlen(name);
	if ((len + 1) > TIPC_MAX_MEDIA_NAME)
		return 0;
	return (strspn(name, tipc_alphabet) == len);
}

/**
 * media_find - locates specified media object by name
 */

static struct media *media_find(const char *name)
{
	struct media *m_ptr;
	u32 i;

	for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) {
		if (!strcmp(m_ptr->name, name))
			return m_ptr;
	}
	return 0;
}

/**
 * tipc_register_media - register a media type
 * 
 * Bearers for this media type must be activated separately at a later stage.
 */

int  tipc_register_media(u32 media_type,
			 char *name, 
			 int (*enable)(struct tipc_bearer *), 
			 void (*disable)(struct tipc_bearer *), 
			 int (*send_msg)(struct sk_buff *, 
					 struct tipc_bearer *,
					 struct tipc_media_addr *), 
			 char *(*addr2str)(struct tipc_media_addr *a,
					   char *str_buf, int str_size),
			 struct tipc_media_addr *bcast_addr,
			 const u32 bearer_priority,
			 const u32 link_tolerance,  /* [ms] */
			 const u32 send_window_limit)
{
	struct media *m_ptr;
	u32 media_id;
	u32 i;
	int res = -EINVAL;

	write_lock_bh(&net_lock);
	if (!media_list)
		goto exit;

	if (!media_name_valid(name)) {
		warn("Media registration error: illegal name <%s>\n", name);
		goto exit;
	}
	if (!bcast_addr) {
		warn("Media registration error: no broadcast address supplied\n");
		goto exit;
	}
	if (bearer_priority >= TIPC_NUM_LINK_PRI) {
		warn("Media registration error: priority %u\n", bearer_priority);
		goto exit;
	}
	if ((link_tolerance < TIPC_MIN_LINK_TOL) || 
	    (link_tolerance > TIPC_MAX_LINK_TOL)) {
		warn("Media registration error: tolerance %u\n", link_tolerance);
		goto exit;
	}

	media_id = media_count++;
	if (media_id >= MAX_MEDIA) {
		warn("Attempt to register more than %u media\n", MAX_MEDIA);
		media_count--;
		goto exit;
	}
	for (i = 0; i < media_id; i++) {
		if (media_list[i].type_id == media_type) {
			warn("Attempt to register second media with type %u\n", 
			     media_type);
			media_count--;
			goto exit;
		}
		if (!strcmp(name, media_list[i].name)) {
			warn("Attempt to re-register media name <%s>\n", name);
			media_count--;
			goto exit;
		}
	}

	m_ptr = &media_list[media_id];
	m_ptr->type_id = media_type;
	m_ptr->send_msg = send_msg;
	m_ptr->enable_bearer = enable;
	m_ptr->disable_bearer = disable;
	m_ptr->addr2str = addr2str;
	memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr));
	m_ptr->bcast = 1;
	strcpy(m_ptr->name, name);
	m_ptr->priority = bearer_priority;
	m_ptr->tolerance = link_tolerance;
	m_ptr->window = send_window_limit;
	dbg("Media <%s> registered\n", name);
	res = 0;
exit:
	write_unlock_bh(&net_lock);
	return res;
}

/**
 * media_addr_printf - record media address in print buffer
 */

void media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a)
{
	struct media *m_ptr;
	u32 media_type;
	u32 i;

	media_type = ntohl(a->type);
	for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) {
		if (m_ptr->type_id == media_type)
			break;
	}

	if ((i < media_count) && (m_ptr->addr2str != NULL)) {
		char addr_str[MAX_ADDR_STR];

		tipc_printf(pb, "%s(%s) ", m_ptr->name, 
			    m_ptr->addr2str(a, addr_str, sizeof(addr_str)));
	} else {
		unchar *addr = (unchar *)&a->dev_addr;

		tipc_printf(pb, "UNKNOWN(%u):", media_type);
		for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) {
			tipc_printf(pb, "%02x ", addr[i]);
		}
	}
}

/**
 * media_get_names - record names of registered media in buffer
 */

struct sk_buff *media_get_names(void)
{
	struct sk_buff *buf;
	struct media *m_ptr;
	int i;

	buf = cfg_reply_alloc(MAX_MEDIA * TLV_SPACE(TIPC_MAX_MEDIA_NAME));
	if (!buf)
		return NULL;

	read_lock_bh(&net_lock);
	for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) {
		cfg_append_tlv(buf, TIPC_TLV_MEDIA_NAME, m_ptr->name, 
			       strlen(m_ptr->name) + 1);
	}
	read_unlock_bh(&net_lock);
	return buf;
}

/**
 * bearer_name_validate - validate & (optionally) deconstruct bearer name
 * @name - ptr to bearer name string
 * @name_parts - ptr to area for bearer name components (or NULL if not needed)
 * 
 * Returns 1 if bearer name is valid, otherwise 0.
 */

static int bearer_name_validate(const char *name, 
				struct bearer_name *name_parts)
{
	char name_copy[TIPC_MAX_BEARER_NAME];
	char *media_name;
	char *if_name;
	u32 media_len;
	u32 if_len;

	/* copy bearer name & ensure length is OK */

	name_copy[TIPC_MAX_BEARER_NAME - 1] = 0;
	/* need above in case non-Posix strncpy() doesn't pad with nulls */
	strncpy(name_copy, name, TIPC_MAX_BEARER_NAME);
	if (name_copy[TIPC_MAX_BEARER_NAME - 1] != 0)
		return 0;

	/* ensure all component parts of bearer name are present */

	media_name = name_copy;
	if ((if_name = strchr(media_name, ':')) == NULL)
		return 0;
	*(if_name++) = 0;
	media_len = if_name - media_name;
	if_len = strlen(if_name) + 1;

	/* validate component parts of bearer name */

	if ((media_len <= 1) || (media_len > TIPC_MAX_MEDIA_NAME) || 
	    (if_len <= 1) || (if_len > TIPC_MAX_IF_NAME) || 
	    (strspn(media_name, tipc_alphabet) != (media_len - 1)) ||
	    (strspn(if_name, tipc_alphabet) != (if_len - 1)))
		return 0;

	/* return bearer name components, if necessary */

	if (name_parts) {
		strcpy(name_parts->media_name, media_name);
		strcpy(name_parts->if_name, if_name);
	}
	return 1;
}

/**
 * bearer_find - locates bearer object with matching bearer name
 */

static struct bearer *bearer_find(const char *name)
{
	struct bearer *b_ptr;
	u32 i;

	for (i = 0, b_ptr = bearers; i < MAX_BEARERS; i++, b_ptr++) {
		if (b_ptr->active && (!strcmp(b_ptr->publ.name, name)))
			return b_ptr;
	}
	return 0;
}

/**
 * bearer_find - locates bearer object with matching interface name
 */

struct bearer *bearer_find_interface(const char *if_name)
{
	struct bearer *b_ptr;
	char *b_if_name;
	u32 i;

	for (i = 0, b_ptr = bearers; i < MAX_BEARERS; i++, b_ptr++) {
		if (!b_ptr->active)
			continue;
		b_if_name = strchr(b_ptr->publ.name, ':') + 1;
		if (!strcmp(b_if_name, if_name))
			return b_ptr;
	}
	return 0;
}

/**
 * bearer_get_names - record names of bearers in buffer
 */

struct sk_buff *bearer_get_names(void)
{
	struct sk_buff *buf;
	struct media *m_ptr;
	struct bearer *b_ptr;
	int i, j;

	buf = cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME));
	if (!buf)
		return NULL;

	read_lock_bh(&net_lock);
	for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) {
		for (j = 0; j < MAX_BEARERS; j++) {
			b_ptr = &bearers[j];
			if (b_ptr->active && (b_ptr->media == m_ptr)) {
				cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME, 
					       b_ptr->publ.name, 
					       strlen(b_ptr->publ.name) + 1);
			}
		}
	}
	read_unlock_bh(&net_lock);
	return buf;
}

void bearer_add_dest(struct bearer *b_ptr, u32 dest)
{
	nmap_add(&b_ptr->nodes, dest);
	disc_update_link_req(b_ptr->link_req);
	bcbearer_sort();
}

void bearer_remove_dest(struct bearer *b_ptr, u32 dest)
{
	nmap_remove(&b_ptr->nodes, dest);
	disc_update_link_req(b_ptr->link_req);
	bcbearer_sort();
}

/*
 * bearer_push(): Resolve bearer congestion. Force the waiting
 * links to push out their unsent packets, one packet per link
 * per iteration, until all packets are gone or congestion reoccurs.
 * 'net_lock' is read_locked when this function is called
 * bearer.lock must be taken before calling
 * Returns binary true(1) ore false(0)
 */
static int bearer_push(struct bearer *b_ptr)
{
	u32 res = TIPC_OK;
	struct link *ln, *tln;

	if (b_ptr->publ.blocked)
		return 0;

	while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) {
		list_for_each_entry_safe(ln, tln, &b_ptr->cong_links, link_list) {
			res = link_push_packet(ln);
			if (res == PUSH_FAILED)
				break;
			if (res == PUSH_FINISHED)
				list_move_tail(&ln->link_list, &b_ptr->links);
		}
	}
	return list_empty(&b_ptr->cong_links);
}

void bearer_lock_push(struct bearer *b_ptr)
{
	int res;

	spin_lock_bh(&b_ptr->publ.lock);
	res = bearer_push(b_ptr);
	spin_unlock_bh(&b_ptr->publ.lock);
	if (res)
		bcbearer_push();
}


/*
 * Interrupt enabling new requests after bearer congestion or blocking:    
 * See bearer_send().   
 */
void tipc_continue(struct tipc_bearer *tb_ptr)
{
	struct bearer *b_ptr = (struct bearer *)tb_ptr;

	spin_lock_bh(&b_ptr->publ.lock);
	b_ptr->continue_count++;
	if (!list_empty(&b_ptr->cong_links))
		k_signal((Handler)bearer_lock_push, (unsigned long)b_ptr);
	b_ptr->publ.blocked = 0;
	spin_unlock_bh(&b_ptr->publ.lock);
}

/*
 * Schedule link for sending of messages after the bearer 
 * has been deblocked by 'continue()'. This method is called 
 * when somebody tries to send a message via this link while 
 * the bearer is congested. 'net_lock' is in read_lock here
 * bearer.lock is busy
 */

static void bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_ptr)
{
	list_move_tail(&l_ptr->link_list, &b_ptr->cong_links);
}

/*
 * Schedule link for sending of messages after the bearer 
 * has been deblocked by 'continue()'. This method is called 
 * when somebody tries to send a message via this link while 
 * the bearer is congested. 'net_lock' is in read_lock here,
 * bearer.lock is free
 */

void bearer_schedule(struct bearer *b_ptr, struct link *l_ptr)
{
	spin_lock_bh(&b_ptr->publ.lock);
	bearer_schedule_unlocked(b_ptr, l_ptr);
	spin_unlock_bh(&b_ptr->publ.lock);
}


/*
 * bearer_resolve_congestion(): Check if there is bearer congestion,
 * and if there is, try to resolve it before returning.
 * 'net_lock' is read_locked when this function is called
 */
int bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr)
{
	int res = 1;

	if (list_empty(&b_ptr->cong_links))
		return 1;
	spin_lock_bh(&b_ptr->publ.lock);
	if (!bearer_push(b_ptr)) {
		bearer_schedule_unlocked(b_ptr, l_ptr);
		res = 0;
	}
	spin_unlock_bh(&b_ptr->publ.lock);
	return res;
}


/**
 * tipc_enable_bearer - enable bearer with the given name
 */              

int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority)
{
	struct bearer *b_ptr;
	struct media *m_ptr;
	struct bearer_name b_name;
	char addr_string[16];
	u32 bearer_id;
	u32 with_this_prio;
	u32 i;
	int res = -EINVAL;

	if (tipc_mode != TIPC_NET_MODE)
		return -ENOPROTOOPT;
	if (!bearer_name_validate(name, &b_name) ||
	    !addr_domain_valid(bcast_scope) ||
	    !in_scope(bcast_scope, tipc_own_addr) ||
	    (priority > TIPC_NUM_LINK_PRI))
		return -EINVAL;

	write_lock_bh(&net_lock);
	if (!bearers)
		goto failed;

	m_ptr = media_find(b_name.media_name);
	if (!m_ptr) {
		warn("No media <%s>\n", b_name.media_name);
		goto failed;
	}
	if (priority == TIPC_NUM_LINK_PRI)
		priority = m_ptr->priority;

restart:
	bearer_id = MAX_BEARERS;
	with_this_prio = 1;
	for (i = MAX_BEARERS; i-- != 0; ) {
		if (!bearers[i].active) {
			bearer_id = i;
			continue;
		}
		if (!strcmp(name, bearers[i].publ.name)) {
			warn("Bearer <%s> already enabled\n", name);
			goto failed;
		}
		if ((bearers[i].priority == priority) &&
		    (++with_this_prio > 2)) {
			if (priority-- == 0) {
				warn("Third bearer <%s> with priority %u, unable to lower to %u\n",
				     name, priority + 1, priority);
				goto failed;
			}
			warn("Third bearer <%s> with priority %u, lowering to %u\n",
			     name, priority + 1, priority);
			goto restart;
		}
	}
	if (bearer_id >= MAX_BEARERS) {
		warn("Attempt to enable more than %d bearers\n", MAX_BEARERS);
		goto failed;
	}

	b_ptr = &bearers[bearer_id];
	memset(b_ptr, 0, sizeof(struct bearer));

	strcpy(b_ptr->publ.name, name);
	res = m_ptr->enable_bearer(&b_ptr->publ);
	if (res) {
		warn("Failed to enable bearer <%s>\n", name);
		goto failed;
	}

	b_ptr->identity = bearer_id;
	b_ptr->media = m_ptr;
	b_ptr->net_plane = bearer_id + 'A';
	b_ptr->active = 1;
	b_ptr->detect_scope = bcast_scope;
	b_ptr->priority = priority;
	INIT_LIST_HEAD(&b_ptr->cong_links);
	INIT_LIST_HEAD(&b_ptr->links);
	if (m_ptr->bcast) {
		b_ptr->link_req = disc_init_link_req(b_ptr, &m_ptr->bcast_addr,
						     bcast_scope, 2);
	}
	b_ptr->publ.lock = SPIN_LOCK_UNLOCKED;
	write_unlock_bh(&net_lock);
	info("Enabled bearer <%s>, discovery domain %s\n",
	     name, addr_string_fill(addr_string, bcast_scope));
	return 0;
failed:
	write_unlock_bh(&net_lock);
	return res;
}

/**
 * tipc_block_bearer(): Block the bearer with the given name,
 *                      and reset all its links
 */

int tipc_block_bearer(const char *name)
{
	struct bearer *b_ptr = 0;
	struct link *l_ptr;
	struct link *temp_l_ptr;

	if (tipc_mode != TIPC_NET_MODE)
		return -ENOPROTOOPT;

	read_lock_bh(&net_lock);
	b_ptr = bearer_find(name);
	if (!b_ptr) {
		warn("Attempt to block unknown bearer <%s>\n", name);
		read_unlock_bh(&net_lock);
		return -EINVAL;
	}

	spin_lock_bh(&b_ptr->publ.lock);
	b_ptr->publ.blocked = 1;
	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
		struct node *n_ptr = l_ptr->owner;

		spin_lock_bh(&n_ptr->lock);
		link_reset(l_ptr);
		spin_unlock_bh(&n_ptr->lock);
	}
	spin_unlock_bh(&b_ptr->publ.lock);
	read_unlock_bh(&net_lock);
	info("Blocked bearer <%s>\n", name);
	return TIPC_OK;
}

/**
 * bearer_disable -
 * 
 * Note: This routine assumes caller holds net_lock.
 */

static int bearer_disable(const char *name)
{
	struct bearer *b_ptr;
	struct link *l_ptr;
	struct link *temp_l_ptr;

	if (tipc_mode != TIPC_NET_MODE)
		return -ENOPROTOOPT;

	b_ptr = bearer_find(name);
	if (!b_ptr) {
		warn("Attempt to disable unknown bearer <%s>\n", name);
		return -EINVAL;
	}

	disc_stop_link_req(b_ptr->link_req);
	spin_lock_bh(&b_ptr->publ.lock);
	b_ptr->link_req = NULL;
	b_ptr->publ.blocked = 1;
	if (b_ptr->media->disable_bearer) {
		spin_unlock_bh(&b_ptr->publ.lock);
		write_unlock_bh(&net_lock);
		b_ptr->media->disable_bearer(&b_ptr->publ);
		write_lock_bh(&net_lock);
		spin_lock_bh(&b_ptr->publ.lock);
	}
	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
		link_delete(l_ptr);
	}
	spin_unlock_bh(&b_ptr->publ.lock);
	info("Disabled bearer <%s>\n", name);
	memset(b_ptr, 0, sizeof(struct bearer));
	return TIPC_OK;
}

int tipc_disable_bearer(const char *name)
{
	int res;

	write_lock_bh(&net_lock);
	res = bearer_disable(name);
	write_unlock_bh(&net_lock);
	return res;
}



int bearer_init(void)
{
	int res;

	write_lock_bh(&net_lock);
	bearers = kmalloc(MAX_BEARERS * sizeof(struct bearer), GFP_ATOMIC);
	media_list = kmalloc(MAX_MEDIA * sizeof(struct media), GFP_ATOMIC);
	if (bearers && media_list) {
		memset(bearers, 0, MAX_BEARERS * sizeof(struct bearer));
		memset(media_list, 0, MAX_MEDIA * sizeof(struct media));
		res = TIPC_OK;
	} else {
		kfree(bearers);
		kfree(media_list);
		bearers = 0;
		media_list = 0;
		res = -ENOMEM;
	}
	write_unlock_bh(&net_lock);
	return res;
}

void bearer_stop(void)
{
	u32 i;

	if (!bearers)
		return;

	for (i = 0; i < MAX_BEARERS; i++) {
		if (bearers[i].active)
			bearers[i].publ.blocked = 1;
	}
	for (i = 0; i < MAX_BEARERS; i++) {
		if (bearers[i].active)
			bearer_disable(bearers[i].publ.name);
	}
	kfree(bearers);
	kfree(media_list);
	bearers = 0;
	media_list = 0;
	media_count = 0;
}


