⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 config.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * net/tipc/config.c: TIPC configuration management code * * Copyright (c) 2002-2006, Ericsson AB * Copyright (c) 2004-2006, 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 DEFINE_SPINLOCK(config_lock);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 tipc_cfg_link_event(u32 addr, char *name, int up){	/* TIPC DOESN'T HANDLE LINK EVENT SUBSCRIPTIONS AT THE MOMENT */}struct sk_buff *tipc_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 tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,			void *tlv_data, int tlv_data_size){	struct tlv_desc *tlv = (struct tlv_desc *)skb_tail_pointer(buf);	int new_tlv_space = TLV_SPACE(tlv_data_size);	if (skb_tailroom(buf) < new_tlv_space) {		dbg("tipc_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 *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value){	struct sk_buff *buf;	__be32 value_net;	buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(value)));	if (buf) {		value_net = htonl(value);		tipc_cfg_append_tlv(buf, tlv_type, &value_net,				    sizeof(value_net));	}	return buf;}struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string){	struct sk_buff *buf;	int string_len = strlen(string) + 1;	buf = tipc_cfg_reply_alloc(TLV_SPACE(string_len));	if (buf)		tipc_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 = 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);	tipc_cfg_respond(msg_sect, 2u, orig);}#endifstatic 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 tipc_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 tipc_cfg_reply_error_string("unable to enable bearer");	return tipc_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 tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);	if (tipc_disable_bearer((char *)TLV_DATA(req_tlv_area)))		return tipc_cfg_reply_error_string("unable to disable bearer");	return tipc_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 tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);	addr = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));	if (addr == tipc_own_addr)		return tipc_cfg_reply_none();	if (!tipc_addr_node_valid(addr))		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE						   " (node address)");	if (tipc_mode == TIPC_NET_MODE)		return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED						   " (cannot change node address once assigned)");	tipc_own_addr = addr;	/*	 * Must release all spinlocks before calling start_net() because	 * Linux version of TIPC calls eth_media_start() which calls	 * register_netdevice_notifier() which may block!	 *	 * Temporarily releasing the lock should be harmless for non-Linux TIPC,	 * but Linux version of eth_media_start() should really be reworked	 * so that it can be called with spinlocks held.	 */	spin_unlock_bh(&config_lock);	tipc_core_start_net();	spin_lock_bh(&config_lock);	return tipc_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 tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);	value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));	tipc_remote_management = (value != 0);	return tipc_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 tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);	value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));	if (value != delimit(value, 1, 65535))		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE						   " (max publications must be 1-65535)");	tipc_max_publications = value;	return tipc_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 tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);	value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));	if (value != delimit(value, 1, 65535))		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE						   " (max subscriptions must be 1-65535");	tipc_max_subscriptions = value;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -