/*
 * net/tipc/bearer.c: TIPC bearer code
 * 
 * Copyright (c) 1996-2006, Ericsson AB
 * Copyright (c) 2004-2005, Wind River Systems
 * 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;
}


