/*
 * net/tipc/config.c: TIPC configuration management code
 * 
 * Copyright (c) 2002-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 "dbg.h"
#include "bearer.h"
#include "port.h"
#include "link.h"
#include "zone.h"
#include "addr.h"
#include "name_table.h"
#include "node.h"
#include "config.h"
#include "discover.h"

struct subscr_data {
	char usr_handle[8];
	u32 domain;
	u32 port_ref;
	struct list_head subd_list;
};

struct manager {
	u32 user_ref;
	u32 port_ref;
	u32 subscr_ref;
	u32 link_subscriptions;
	struct list_head link_subscribers;
};

static struct manager mng = { 0};

static spinlock_t config_lock = SPIN_LOCK_UNLOCKED;

static const void *req_tlv_area;	/* request message TLV area */
static int req_tlv_space;		/* request message TLV area size */
static int rep_headroom;		/* reply message headroom to use */


void cfg_link_event(u32 addr, char *name, int up)
{
	/* TIPC DOESN'T HANDLE LINK EVENT SUBSCRIPTIONS AT THE MOMENT */
}


struct sk_buff *cfg_reply_alloc(int payload_size)
{
	struct sk_buff *buf;

	buf = alloc_skb(rep_headroom + payload_size, GFP_ATOMIC);
	if (buf)
		skb_reserve(buf, rep_headroom);
	return buf;
}

int cfg_append_tlv(struct sk_buff *buf, int tlv_type, 
		   void *tlv_data, int tlv_data_size)
{
	struct tlv_desc *tlv = (struct tlv_desc *)buf->tail;
	int new_tlv_space = TLV_SPACE(tlv_data_size);

	if (skb_tailroom(buf) < new_tlv_space) {
		dbg("cfg_append_tlv unable to append TLV\n");
		return 0;
	}
	skb_put(buf, new_tlv_space);
	tlv->tlv_type = htons(tlv_type);
	tlv->tlv_len  = htons(TLV_LENGTH(tlv_data_size));
	if (tlv_data_size && tlv_data)
		memcpy(TLV_DATA(tlv), tlv_data, tlv_data_size);
	return 1;
}

struct sk_buff *cfg_reply_unsigned_type(u16 tlv_type, u32 value)
{
	struct sk_buff *buf;
	u32 value_net;

	buf = cfg_reply_alloc(TLV_SPACE(sizeof(value)));
	if (buf) {
		value_net = htonl(value);
		cfg_append_tlv(buf, tlv_type, &value_net, 
			       sizeof(value_net));
	}
	return buf;
}

struct sk_buff *cfg_reply_string_type(u16 tlv_type, char *string)
{
	struct sk_buff *buf;
	int string_len = strlen(string) + 1;

	buf = cfg_reply_alloc(TLV_SPACE(string_len));
	if (buf)
		cfg_append_tlv(buf, tlv_type, string, string_len);
	return buf;
}




#if 0

/* Now obsolete code for handling commands not yet implemented the new way */

int tipc_cfg_cmd(const struct tipc_cmd_msg * msg,
		 char *data,
		 u32 sz,
		 u32 *ret_size,
		 struct tipc_portid *orig)
{
	int rv = -EINVAL;
	u32 cmd = msg->cmd;

	*ret_size = 0;
	switch (cmd) {
	case TIPC_REMOVE_LINK:
	case TIPC_CMD_BLOCK_LINK:
	case TIPC_CMD_UNBLOCK_LINK:
		if (!cfg_check_connection(orig))
			rv = link_control(msg->argv.link_name, msg->cmd, 0);
		break;
	case TIPC_ESTABLISH:
		{
			int connected;

			tipc_isconnected(mng.conn_port_ref, &connected);
			if (connected || !orig) {
				rv = TIPC_FAILURE;
				break;
			}
			rv = tipc_connect2port(mng.conn_port_ref, orig);
			if (rv == TIPC_OK)
				orig = 0;
			break;
		}
	case TIPC_GET_PEER_ADDRESS:
		*ret_size = link_peer_addr(msg->argv.link_name, data, sz);
		break;
	case TIPC_GET_ROUTES:
		rv = TIPC_OK;
		break;
	default: {}
	}
	if (*ret_size)
		rv = TIPC_OK;
	return rv;
}

static void cfg_cmd_event(struct tipc_cmd_msg *msg,
			  char *data,
			  u32 sz,        
			  struct tipc_portid const *orig)
{
	int rv = -EINVAL;
	struct tipc_cmd_result_msg rmsg;
	struct iovec msg_sect[2];
	int *arg;

	msg->cmd = ntohl(msg->cmd);

	cfg_prepare_res_msg(msg->cmd, msg->usr_handle, rv, &rmsg, msg_sect, 
			    data, 0);
	if (ntohl(msg->magic) != TIPC_MAGIC)
		goto exit;

	switch (msg->cmd) {
	case TIPC_CREATE_LINK:
		if (!cfg_check_connection(orig))
			rv = disc_create_link(&msg->argv.create_link);
		break;
	case TIPC_LINK_SUBSCRIBE:
		{
			struct subscr_data *sub;

			if (mng.link_subscriptions > 64)
				break;
			sub = (struct subscr_data *)kmalloc(sizeof(*sub),
							    GFP_ATOMIC);
			if (sub == NULL) {
				warn("Memory squeeze; dropped remote link subscription\n");
				break;
			}
			INIT_LIST_HEAD(&sub->subd_list);
			tipc_createport(mng.user_ref,
					(void *)sub,
					TIPC_HIGH_IMPORTANCE,
					0,
					0,
					(tipc_conn_shutdown_event)cfg_linksubscr_cancel,
					0,
					0,
					(tipc_conn_msg_event)cfg_linksubscr_cancel,
					0,
					&sub->port_ref);
			if (!sub->port_ref) {
				kfree(sub);
				break;
			}
			memcpy(sub->usr_handle,msg->usr_handle,
			       sizeof(sub->usr_handle));
			sub->domain = msg->argv.domain;
			list_add_tail(&sub->subd_list, &mng.link_subscribers);
			tipc_connect2port(sub->port_ref, orig);
			rmsg.retval = TIPC_OK;
			tipc_send(sub->port_ref, 2u, msg_sect);
			mng.link_subscriptions++;
			return;
		}
	default:
		rv = tipc_cfg_cmd(msg, data, sz, (u32 *)&msg_sect[1].iov_len, orig);
	}
	exit:
	rmsg.result_len = htonl(msg_sect[1].iov_len);
	rmsg.retval = htonl(rv);
	cfg_respond(msg_sect, 2u, orig);
}
#endif

static struct sk_buff *cfg_enable_bearer(void)
{
	struct tipc_bearer_config *args;

	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_CONFIG))
		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);

	args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area);
	if (tipc_enable_bearer(args->name,
			       ntohl(args->detect_scope),
			       ntohl(args->priority)))
		return cfg_reply_error_string("unable to enable bearer");

	return cfg_reply_none();
}

static struct sk_buff *cfg_disable_bearer(void)
{
	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_NAME))
		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);

	if (tipc_disable_bearer((char *)TLV_DATA(req_tlv_area)))
		return cfg_reply_error_string("unable to disable bearer");

	return cfg_reply_none();
}

static struct sk_buff *cfg_set_own_addr(void)
{
	u32 addr;

	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);

	addr = *(u32 *)TLV_DATA(req_tlv_area);
	addr = ntohl(addr);
	if (addr == tipc_own_addr)
		return cfg_reply_none();
	if (!addr_node_valid(addr))
		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
					      " (node address)");
	if (tipc_own_addr)
		return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
					      " (cannot change node address once assigned)");

	spin_unlock_bh(&config_lock);
	stop_net();
	tipc_own_addr = addr;
	start_net();
	spin_lock_bh(&config_lock);
	return cfg_reply_none();
}

static struct sk_buff *cfg_set_remote_mng(void)
{
	u32 value;

	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);

	value = *(u32 *)TLV_DATA(req_tlv_area);
	value = ntohl(value);
	tipc_remote_management = (value != 0);
	return cfg_reply_none();
}

static struct sk_buff *cfg_set_max_publications(void)
{
	u32 value;

	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);

	value = *(u32 *)TLV_DATA(req_tlv_area);
	value = ntohl(value);
	if (value != delimit(value, 1, 65535))
		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
					      " (max publications must be 1-65535)");
	tipc_max_publications = value;
	return cfg_reply_none();
}

static struct sk_buff *cfg_set_max_subscriptions(void)
{
	u32 value;

	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);

	value = *(u32 *)TLV_DATA(req_tlv_area);
	value = ntohl(value);
	if (value != delimit(value, 1, 65535))
		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
					      " (max subscriptions must be 1-65535");
	tipc_max_subscriptions = value;
	return cfg_reply_none();
}

static struct sk_buff *cfg_set_max_ports(void)
{
	int orig_mode;
	u32 value;

	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
	value = *(u32 *)TLV_DATA(req_tlv_area);
	value = ntohl(value);
	if (value != delimit(value, 127, 65535))
		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
					      " (max ports must be 127-65535)");

	if (value == tipc_max_ports)
		return cfg_reply_none();

	if (atomic_read(&tipc_user_count) > 2)
		return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
					      " (cannot change max ports while TIPC users exist)");

	spin_unlock_bh(&config_lock);
	orig_mode = tipc_get_mode();
	if (orig_mode == TIPC_NET_MODE)
		stop_net();
	stop_core();
	tipc_max_ports = value;
	start_core();
	if (orig_mode == TIPC_NET_MODE)
		start_net();
	spin_lock_bh(&config_lock);
	return cfg_reply_none();
}

static struct sk_buff *set_net_max(int value, int *parameter)
{
	int orig_mode;

	if (value != *parameter) {
		orig_mode = tipc_get_mode();
		if (orig_mode == TIPC_NET_MODE)
			stop_net();
		*parameter = value;
		if (orig_mode == TIPC_NET_MODE)
			start_net();
	}

	return cfg_reply_none();
}

static struct sk_buff *cfg_set_max_zones(void)
{
	u32 value;

	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
	value = *(u32 *)TLV_DATA(req_tlv_area);
	value = ntohl(value);
	if (value != delimit(value, 1, 255))
		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
					      " (max zones must be 1-255)");
	return set_net_max(value, &tipc_max_zones);
}

static struct sk_buff *cfg_set_max_clusters(void)
{
	u32 value;

	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
	value = *(u32 *)TLV_DATA(req_tlv_area);
	value = ntohl(value);
	if (value != 1)
		return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
					      " (max clusters fixed at 1)");
	return cfg_reply_none();
}

static struct sk_buff *cfg_set_max_nodes(void)
{
	u32 value;

	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
	value = *(u32 *)TLV_DATA(req_tlv_area);
	value = ntohl(value);
	if (value != delimit(value, 8, 2047))
		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
					      " (max nodes must be 8-2047)");
	return set_net_max(value, &tipc_max_nodes);
}

static struct sk_buff *cfg_set_max_slaves(void)
{
	u32 value;

	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
	value = *(u32 *)TLV_DATA(req_tlv_area);
	value = ntohl(value);
	if (value != 0)
		return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
					      " (max secondary nodes fixed at 0)");
	return cfg_reply_none();
}

static struct sk_buff *cfg_set_netid(void)
{
	u32 value;

	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
		return cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
	value = *(u32 *)TLV_DATA(req_tlv_area);
	value = ntohl(value);
	if (value != delimit(value, 1, 9999))
		return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
					      " (network id must be 1-9999)");

	if (tipc_own_addr)
		return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
					      " (cannot change network id once part of network)");
	
	return set_net_max(value, &tipc_net_id);
}

struct sk_buff *cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area,
			   int request_space, int reply_headroom)
{
	struct sk_buff *rep_tlv_buf;

	spin_lock_bh(&config_lock);

	/* Save request and reply details in a well-known location */

	req_tlv_area = request_area;
	req_tlv_space = request_space;
	rep_headroom = reply_headroom;

	/* Check command authorization */

	if (likely(orig_node == tipc_own_addr)) {
		/* command is permitted */
	} else if (cmd >= 0x8000) {
		rep_tlv_buf = cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
						     " (cannot be done remotely)");
		goto exit;
	} else if (!tipc_remote_management) {
		rep_tlv_buf = cfg_reply_error_string(TIPC_CFG_NO_REMOTE);
		goto exit;
	}
	else if (cmd >= 0x4000) {
		u32 domain = 0;

		if ((nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) ||
		    (domain != orig_node)) {
			rep_tlv_buf = cfg_reply_error_string(TIPC_CFG_NOT_ZONE_MSTR);
			goto exit;
		}
	}

	/* Call appropriate processing routine */

	switch (cmd) {
	case TIPC_CMD_NOOP:
		rep_tlv_buf = cfg_reply_none();
		break;
	case TIPC_CMD_GET_NODES:
		rep_tlv_buf = node_get_nodes(req_tlv_area, req_tlv_space);
		break;
	case TIPC_CMD_GET_LINKS:
		rep_tlv_buf = node_get_links(req_tlv_area, req_tlv_space);
		break;
	case TIPC_CMD_SHOW_LINK_STATS:
		rep_tlv_buf = link_cmd_show_stats(req_tlv_area, req_tlv_space);
		break;
	case TIPC_CMD_RESET_LINK_STATS:
		rep_tlv_buf = link_cmd_reset_stats(req_tlv_area, req_tlv_space);
		break;
	case TIPC_CMD_SHOW_NAME_TABLE:
		rep_tlv_buf = nametbl_get(req_tlv_area, req_tlv_space);
		break;
	case TIPC_CMD_GET_BEARER_NAMES:
		rep_tlv_buf = bearer_get_names();
		break;
	case TIPC_CMD_GET_MEDIA_NAMES:
		rep_tlv_buf = media_get_names();
		break;
	case TIPC_CMD_SHOW_PORTS:
		rep_tlv_buf = port_get_ports();
		break;
#if 0
	case TIPC_CMD_SHOW_PORT_STATS:
		rep_tlv_buf = port_show_stats(req_tlv_area, req_tlv_space);
		break;
	case TIPC_CMD_RESET_PORT_STATS:
		rep_tlv_buf = cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED);
		break;
#endif
	case TIPC_CMD_SET_LOG_SIZE:
		rep_tlv_buf = log_resize(req_tlv_area, req_tlv_space);
		break;
	case TIPC_CMD_DUMP_LOG:
		rep_tlv_buf = log_dump();
		break;
	case TIPC_CMD_SET_LINK_TOL:
	case TIPC_CMD_SET_LINK_PRI:
	case TIPC_CMD_SET_LINK_WINDOW:
		rep_tlv_buf = link_cmd_config(req_tlv_area, req_tlv_space, cmd);
		break;
	case TIPC_CMD_ENABLE_BEARER:
		rep_tlv_buf = cfg_enable_bearer();
		break;
	case TIPC_CMD_DISABLE_BEARER:
		rep_tlv_buf = cfg_disable_bearer();
		break;
	case TIPC_CMD_SET_NODE_ADDR:
		rep_tlv_buf = cfg_set_own_addr();
		break;
	case TIPC_CMD_SET_REMOTE_MNG:
		rep_tlv_buf = cfg_set_remote_mng();
		break;
	case TIPC_CMD_SET_MAX_PORTS:
		rep_tlv_buf = cfg_set_max_ports();
		break;
	case TIPC_CMD_SET_MAX_PUBL:
		rep_tlv_buf = cfg_set_max_publications();
		break;
	case TIPC_CMD_SET_MAX_SUBSCR:
		rep_tlv_buf = cfg_set_max_subscriptions();
		break;
	case TIPC_CMD_SET_MAX_ZONES:
		rep_tlv_buf = cfg_set_max_zones();
		break;
	case TIPC_CMD_SET_MAX_CLUSTERS:
		rep_tlv_buf = cfg_set_max_clusters();
		break;
	case TIPC_CMD_SET_MAX_NODES:
		rep_tlv_buf = cfg_set_max_nodes();
		break;
	case TIPC_CMD_SET_MAX_SLAVES:
		rep_tlv_buf = cfg_set_max_slaves();
		break;
	case TIPC_CMD_SET_NETID:
		rep_tlv_buf = cfg_set_netid();
		break;
	case TIPC_CMD_GET_REMOTE_MNG:
		rep_tlv_buf = cfg_reply_unsigned(tipc_remote_management);
		break;
	case TIPC_CMD_GET_MAX_PORTS:
		rep_tlv_buf = cfg_reply_unsigned(tipc_max_ports);
		break;
	case TIPC_CMD_GET_MAX_PUBL:
		rep_tlv_buf = cfg_reply_unsigned(tipc_max_publications);
		break;
	case TIPC_CMD_GET_MAX_SUBSCR:
		rep_tlv_buf = cfg_reply_unsigned(tipc_max_subscriptions);
		break;
	case TIPC_CMD_GET_MAX_ZONES:
		rep_tlv_buf = cfg_reply_unsigned(tipc_max_zones);
		break;
	case TIPC_CMD_GET_MAX_CLUSTERS:
		rep_tlv_buf = cfg_reply_unsigned(tipc_max_clusters);
		break;
	case TIPC_CMD_GET_MAX_NODES:
		rep_tlv_buf = cfg_reply_unsigned(tipc_max_nodes);
		break;
	case TIPC_CMD_GET_MAX_SLAVES:
		rep_tlv_buf = cfg_reply_unsigned(tipc_max_slaves);
		break;
	case TIPC_CMD_GET_NETID:
		rep_tlv_buf = cfg_reply_unsigned(tipc_net_id);
		break;
	default:
		rep_tlv_buf = NULL;
		break;
	}

	/* Return reply buffer */
exit:
	spin_unlock_bh(&config_lock);
	return rep_tlv_buf;
}

static void cfg_named_msg_event(void *userdata,
				u32 port_ref,
				struct sk_buff **buf,
				const unchar *msg,
				u32 size,
				u32 importance, 
				struct tipc_portid const *orig,
				struct tipc_name_seq const *dest)
{
	struct tipc_cfg_msg_hdr *req_hdr;
	struct tipc_cfg_msg_hdr *rep_hdr;
	struct sk_buff *rep_buf;

	/* Validate configuration message header (ignore invalid message) */

	req_hdr = (struct tipc_cfg_msg_hdr *)msg;
	if ((size < sizeof(*req_hdr)) ||
	    (size != TCM_ALIGN(ntohl(req_hdr->tcm_len))) ||
	    (ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) {
		warn("discarded invalid configuration message\n");
		return;
	}

	/* Generate reply for request (if can't, return request) */

	rep_buf = cfg_do_cmd(orig->node,
			     ntohs(req_hdr->tcm_type), 
			     msg + sizeof(*req_hdr),
			     size - sizeof(*req_hdr),
			     BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr));
	if (rep_buf) {
		skb_push(rep_buf, sizeof(*rep_hdr));
		rep_hdr = (struct tipc_cfg_msg_hdr *)rep_buf->data;
		memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr));
		rep_hdr->tcm_len = htonl(rep_buf->len);
		rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST);
	} else {
		rep_buf = *buf;
		*buf = NULL;
	}

	/* NEED TO ADD CODE TO HANDLE FAILED SEND (SUCH AS CONGESTION) */
	tipc_send_buf2port(port_ref, orig, rep_buf, rep_buf->len);
}

int cfg_init(void)
{
	struct tipc_name_seq seq;
	int res;

	memset(&mng, 0, sizeof(mng));
	INIT_LIST_HEAD(&mng.link_subscribers);

	res = tipc_attach(&mng.user_ref, 0, 0);
	if (res)
		goto failed;

	res = tipc_createport(mng.user_ref, 0, TIPC_CRITICAL_IMPORTANCE,
			      NULL, NULL, NULL,
			      NULL, cfg_named_msg_event, NULL,
			      NULL, &mng.port_ref);
	if (res)
		goto failed;

	seq.type = TIPC_CFG_SRV;
	seq.lower = seq.upper = tipc_own_addr;
	res = nametbl_publish_rsv(mng.port_ref, TIPC_ZONE_SCOPE, &seq);
	if (res)
		goto failed;

	return 0;

failed:
	err("Unable to create configuration service\n");
	tipc_detach(mng.user_ref);
	mng.user_ref = 0;
	return res;
}

void cfg_stop(void)
{
	if (mng.user_ref) {
		tipc_detach(mng.user_ref);
		mng.user_ref = 0;
	}
}
