2006-01-02 19:04:38 +01:00
/*
* net / tipc / config . c : TIPC configuration management code
2007-02-09 23:25:21 +09:00
*
2006-01-11 19:14:19 +01:00
* Copyright ( c ) 2002 - 2006 , Ericsson AB
2013-06-17 10:54:41 -04:00
* Copyright ( c ) 2004 - 2007 , 2010 - 2013 , Wind River Systems
2006-01-02 19:04:38 +01:00
* All rights reserved .
*
2006-01-11 13:30:43 +01:00
* Redistribution and use in source and binary forms , with or without
2006-01-02 19:04:38 +01:00
* modification , are permitted provided that the following conditions are met :
*
2006-01-11 13:30:43 +01:00
* 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 .
2006-01-02 19:04:38 +01:00
*
2006-01-11 13:30:43 +01:00
* 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
2006-01-02 19:04:38 +01:00
* POSSIBILITY OF SUCH DAMAGE .
*/
# include "core.h"
# include "port.h"
# include "name_table.h"
# include "config.h"
2013-06-17 10:54:41 -04:00
# include "server.h"
2006-01-02 19:04:38 +01:00
2012-06-29 00:50:23 -04:00
# define REPLY_TRUNCATED "<truncated>\n"
2013-06-17 10:54:45 -04:00
static DEFINE_MUTEX ( config_mutex ) ;
2013-06-17 10:54:41 -04:00
static struct tipc_server cfgsrv ;
2006-01-02 19:04:38 +01:00
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 */
2006-01-18 00:38:21 +01:00
struct sk_buff * tipc_cfg_reply_alloc ( int payload_size )
2006-01-02 19:04:38 +01:00
{
struct sk_buff * buf ;
buf = alloc_skb ( rep_headroom + payload_size , GFP_ATOMIC ) ;
if ( buf )
skb_reserve ( buf , rep_headroom ) ;
return buf ;
}
2007-02-09 23:25:21 +09:00
int tipc_cfg_append_tlv ( struct sk_buff * buf , int tlv_type ,
2006-01-18 00:38:21 +01:00
void * tlv_data , int tlv_data_size )
2006-01-02 19:04:38 +01:00
{
2007-04-19 20:29:13 -07:00
struct tlv_desc * tlv = ( struct tlv_desc * ) skb_tail_pointer ( buf ) ;
2006-01-02 19:04:38 +01:00
int new_tlv_space = TLV_SPACE ( tlv_data_size ) ;
2010-12-31 18:59:25 +00:00
if ( skb_tailroom ( buf ) < new_tlv_space )
2006-01-02 19:04:38 +01:00
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 ;
}
2010-10-13 13:20:35 +00:00
static struct sk_buff * tipc_cfg_reply_unsigned_type ( u16 tlv_type , u32 value )
2006-01-02 19:04:38 +01:00
{
struct sk_buff * buf ;
2006-11-08 00:19:09 -08:00
__be32 value_net ;
2006-01-02 19:04:38 +01:00
2006-01-18 00:38:21 +01:00
buf = tipc_cfg_reply_alloc ( TLV_SPACE ( sizeof ( value ) ) ) ;
2006-01-02 19:04:38 +01:00
if ( buf ) {
value_net = htonl ( value ) ;
2007-02-09 23:25:21 +09:00
tipc_cfg_append_tlv ( buf , tlv_type , & value_net ,
2006-01-18 00:38:21 +01:00
sizeof ( value_net ) ) ;
2006-01-02 19:04:38 +01:00
}
return buf ;
}
2010-10-13 13:20:35 +00:00
static struct sk_buff * tipc_cfg_reply_unsigned ( u32 value )
{
return tipc_cfg_reply_unsigned_type ( TIPC_TLV_UNSIGNED , value ) ;
}
2006-01-18 00:38:21 +01:00
struct sk_buff * tipc_cfg_reply_string_type ( u16 tlv_type , char * string )
2006-01-02 19:04:38 +01:00
{
struct sk_buff * buf ;
int string_len = strlen ( string ) + 1 ;
2006-01-18 00:38:21 +01:00
buf = tipc_cfg_reply_alloc ( TLV_SPACE ( string_len ) ) ;
2006-01-02 19:04:38 +01:00
if ( buf )
2006-01-18 00:38:21 +01:00
tipc_cfg_append_tlv ( buf , tlv_type , string , string_len ) ;
2006-01-02 19:04:38 +01:00
return buf ;
}
2010-05-11 14:30:08 +00:00
static struct sk_buff * tipc_show_stats ( void )
{
struct sk_buff * buf ;
struct tlv_desc * rep_tlv ;
2012-06-29 00:50:23 -04:00
char * pb ;
int pb_len ;
2010-05-11 14:30:08 +00:00
int str_len ;
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 ( * ( u32 * ) TLV_DATA ( req_tlv_area ) ) ;
if ( value ! = 0 )
return tipc_cfg_reply_error_string ( " unsupported argument " ) ;
2012-06-29 00:50:23 -04:00
buf = tipc_cfg_reply_alloc ( TLV_SPACE ( ULTRA_STRING_MAX_LEN ) ) ;
2010-05-11 14:30:08 +00:00
if ( buf = = NULL )
return NULL ;
rep_tlv = ( struct tlv_desc * ) buf - > data ;
2012-06-29 00:50:23 -04:00
pb = TLV_DATA ( rep_tlv ) ;
pb_len = ULTRA_STRING_MAX_LEN ;
2010-05-11 14:30:08 +00:00
2012-06-29 00:50:23 -04:00
str_len = tipc_snprintf ( pb , pb_len , " TIPC version " TIPC_MOD_VER " \n " ) ;
str_len + = 1 ; /* for "\0" */
2010-05-11 14:30:08 +00:00
skb_put ( buf , TLV_SPACE ( str_len ) ) ;
TLV_SET ( rep_tlv , TIPC_TLV_ULTRA_STRING , NULL , str_len ) ;
return buf ;
}
2006-01-02 19:04:38 +01:00
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 ) )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_error_string ( TIPC_CFG_TLV_ERROR ) ;
2006-01-02 19:04:38 +01:00
args = ( struct tipc_bearer_config * ) TLV_DATA ( req_tlv_area ) ;
if ( tipc_enable_bearer ( args - > name ,
2011-02-28 14:56:15 -05:00
ntohl ( args - > disc_domain ) ,
2006-01-02 19:04:38 +01:00
ntohl ( args - > priority ) ) )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_error_string ( " unable to enable bearer " ) ;
2006-01-02 19:04:38 +01:00
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_none ( ) ;
2006-01-02 19:04:38 +01:00
}
static struct sk_buff * cfg_disable_bearer ( void )
{
if ( ! TLV_CHECK ( req_tlv_area , req_tlv_space , TIPC_TLV_BEARER_NAME ) )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_error_string ( TIPC_CFG_TLV_ERROR ) ;
2006-01-02 19:04:38 +01:00
if ( tipc_disable_bearer ( ( char * ) TLV_DATA ( req_tlv_area ) ) )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_error_string ( " unable to disable bearer " ) ;
2006-01-02 19:04:38 +01:00
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_none ( ) ;
2006-01-02 19:04:38 +01:00
}
static struct sk_buff * cfg_set_own_addr ( void )
{
u32 addr ;
if ( ! TLV_CHECK ( req_tlv_area , req_tlv_space , TIPC_TLV_NET_ADDR ) )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_error_string ( TIPC_CFG_TLV_ERROR ) ;
2006-01-02 19:04:38 +01:00
2006-11-08 00:19:09 -08:00
addr = ntohl ( * ( __be32 * ) TLV_DATA ( req_tlv_area ) ) ;
2006-01-02 19:04:38 +01:00
if ( addr = = tipc_own_addr )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_none ( ) ;
if ( ! tipc_addr_node_valid ( addr ) )
return tipc_cfg_reply_error_string ( TIPC_CFG_INVALID_VALUE
" (node address) " ) ;
2011-11-08 13:48:28 -05:00
if ( tipc_own_addr )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_error_string ( TIPC_CFG_NOT_SUPPORTED
" (cannot change node address once assigned) " ) ;
2008-05-21 14:55:04 -07:00
tipc_core_start_net ( addr ) ;
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_none ( ) ;
2006-01-02 19:04:38 +01:00
}
static struct sk_buff * cfg_set_remote_mng ( void )
{
u32 value ;
if ( ! TLV_CHECK ( req_tlv_area , req_tlv_space , TIPC_TLV_UNSIGNED ) )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_error_string ( TIPC_CFG_TLV_ERROR ) ;
2006-01-02 19:04:38 +01:00
2006-11-08 00:19:09 -08:00
value = ntohl ( * ( __be32 * ) TLV_DATA ( req_tlv_area ) ) ;
2006-01-02 19:04:38 +01:00
tipc_remote_management = ( value ! = 0 ) ;
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_none ( ) ;
2006-01-02 19:04:38 +01:00
}
static struct sk_buff * cfg_set_max_ports ( void )
{
u32 value ;
if ( ! TLV_CHECK ( req_tlv_area , req_tlv_space , TIPC_TLV_UNSIGNED ) )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_error_string ( TIPC_CFG_TLV_ERROR ) ;
2006-11-08 00:19:09 -08:00
value = ntohl ( * ( __be32 * ) TLV_DATA ( req_tlv_area ) ) ;
2006-06-25 23:51:08 -07:00
if ( value = = tipc_max_ports )
return tipc_cfg_reply_none ( ) ;
2012-02-23 15:44:08 -05:00
if ( value < 127 | | value > 65535 )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_error_string ( TIPC_CFG_INVALID_VALUE
" (max ports must be 127-65535) " ) ;
2011-11-08 13:18:59 -05:00
return tipc_cfg_reply_error_string ( TIPC_CFG_NOT_SUPPORTED
" (cannot change max ports while TIPC is active) " ) ;
2006-01-02 19:04:38 +01:00
}
static struct sk_buff * cfg_set_netid ( void )
{
u32 value ;
if ( ! TLV_CHECK ( req_tlv_area , req_tlv_space , TIPC_TLV_UNSIGNED ) )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_error_string ( TIPC_CFG_TLV_ERROR ) ;
2006-11-08 00:19:09 -08:00
value = ntohl ( * ( __be32 * ) TLV_DATA ( req_tlv_area ) ) ;
2006-06-25 23:51:08 -07:00
if ( value = = tipc_net_id )
return tipc_cfg_reply_none ( ) ;
2012-02-23 15:44:08 -05:00
if ( value < 1 | | value > 9999 )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_error_string ( TIPC_CFG_INVALID_VALUE
" (network id must be 1-9999) " ) ;
2011-11-08 13:48:28 -05:00
if ( tipc_own_addr )
2006-01-18 00:38:21 +01:00
return tipc_cfg_reply_error_string ( TIPC_CFG_NOT_SUPPORTED
2006-06-25 23:51:08 -07:00
" (cannot change network id once TIPC has joined a network) " ) ;
tipc_net_id = value ;
return tipc_cfg_reply_none ( ) ;
2006-01-02 19:04:38 +01:00
}
2006-01-18 00:38:21 +01:00
struct sk_buff * tipc_cfg_do_cmd ( u32 orig_node , u16 cmd , const void * request_area ,
int request_space , int reply_headroom )
2006-01-02 19:04:38 +01:00
{
struct sk_buff * rep_tlv_buf ;
2013-06-17 10:54:45 -04:00
mutex_lock ( & config_mutex ) ;
2006-01-02 19:04:38 +01:00
/* 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 */
2012-04-18 09:42:56 -04:00
if ( likely ( in_own_node ( orig_node ) ) ) {
2006-01-02 19:04:38 +01:00
/* command is permitted */
} else if ( cmd > = 0x8000 ) {
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_cfg_reply_error_string ( TIPC_CFG_NOT_SUPPORTED
" (cannot be done remotely) " ) ;
2006-01-02 19:04:38 +01:00
goto exit ;
} else if ( ! tipc_remote_management ) {
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_cfg_reply_error_string ( TIPC_CFG_NO_REMOTE ) ;
2006-01-02 19:04:38 +01:00
goto exit ;
2010-12-31 18:59:32 +00:00
} else if ( cmd > = 0x4000 ) {
2006-01-02 19:04:38 +01:00
u32 domain = 0 ;
2006-01-18 00:38:21 +01:00
if ( ( tipc_nametbl_translate ( TIPC_ZM_SRV , 0 , & domain ) = = 0 ) | |
2006-01-02 19:04:38 +01:00
( domain ! = orig_node ) ) {
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_cfg_reply_error_string ( TIPC_CFG_NOT_ZONE_MSTR ) ;
2006-01-02 19:04:38 +01:00
goto exit ;
}
}
/* Call appropriate processing routine */
switch ( cmd ) {
case TIPC_CMD_NOOP :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_cfg_reply_none ( ) ;
2006-01-02 19:04:38 +01:00
break ;
case TIPC_CMD_GET_NODES :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_node_get_nodes ( req_tlv_area , req_tlv_space ) ;
2006-01-02 19:04:38 +01:00
break ;
case TIPC_CMD_GET_LINKS :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_node_get_links ( req_tlv_area , req_tlv_space ) ;
2006-01-02 19:04:38 +01:00
break ;
case TIPC_CMD_SHOW_LINK_STATS :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_link_cmd_show_stats ( req_tlv_area , req_tlv_space ) ;
2006-01-02 19:04:38 +01:00
break ;
case TIPC_CMD_RESET_LINK_STATS :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_link_cmd_reset_stats ( req_tlv_area , req_tlv_space ) ;
2006-01-02 19:04:38 +01:00
break ;
case TIPC_CMD_SHOW_NAME_TABLE :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_nametbl_get ( req_tlv_area , req_tlv_space ) ;
2006-01-02 19:04:38 +01:00
break ;
case TIPC_CMD_GET_BEARER_NAMES :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_bearer_get_names ( ) ;
2006-01-02 19:04:38 +01:00
break ;
case TIPC_CMD_GET_MEDIA_NAMES :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_media_get_names ( ) ;
2006-01-02 19:04:38 +01:00
break ;
case TIPC_CMD_SHOW_PORTS :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_port_get_ports ( ) ;
2006-01-02 19:04:38 +01:00
break ;
2010-05-11 14:30:08 +00:00
case TIPC_CMD_SHOW_STATS :
rep_tlv_buf = tipc_show_stats ( ) ;
break ;
2006-01-02 19:04:38 +01:00
case TIPC_CMD_SET_LINK_TOL :
case TIPC_CMD_SET_LINK_PRI :
case TIPC_CMD_SET_LINK_WINDOW :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_link_cmd_config ( req_tlv_area , req_tlv_space , cmd ) ;
2006-01-02 19:04:38 +01:00
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_NETID :
rep_tlv_buf = cfg_set_netid ( ) ;
break ;
case TIPC_CMD_GET_REMOTE_MNG :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_cfg_reply_unsigned ( tipc_remote_management ) ;
2006-01-02 19:04:38 +01:00
break ;
case TIPC_CMD_GET_MAX_PORTS :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_cfg_reply_unsigned ( tipc_max_ports ) ;
2006-01-02 19:04:38 +01:00
break ;
case TIPC_CMD_GET_NETID :
2006-01-18 00:38:21 +01:00
rep_tlv_buf = tipc_cfg_reply_unsigned ( tipc_net_id ) ;
2006-01-02 19:04:38 +01:00
break ;
2008-05-21 14:52:30 -07:00
case TIPC_CMD_NOT_NET_ADMIN :
rep_tlv_buf =
tipc_cfg_reply_error_string ( TIPC_CFG_NOT_NET_ADMIN ) ;
break ;
2010-12-31 18:59:16 +00:00
case TIPC_CMD_SET_MAX_ZONES :
case TIPC_CMD_GET_MAX_ZONES :
2010-12-31 18:59:17 +00:00
case TIPC_CMD_SET_MAX_SLAVES :
case TIPC_CMD_GET_MAX_SLAVES :
2010-12-31 18:59:19 +00:00
case TIPC_CMD_SET_MAX_CLUSTERS :
case TIPC_CMD_GET_MAX_CLUSTERS :
2011-02-25 14:22:11 -05:00
case TIPC_CMD_SET_MAX_NODES :
case TIPC_CMD_GET_MAX_NODES :
2012-08-16 12:09:13 +00:00
case TIPC_CMD_SET_MAX_SUBSCR :
case TIPC_CMD_GET_MAX_SUBSCR :
2012-08-16 12:09:14 +00:00
case TIPC_CMD_SET_MAX_PUBL :
case TIPC_CMD_GET_MAX_PUBL :
2012-06-29 00:50:24 -04:00
case TIPC_CMD_SET_LOG_SIZE :
case TIPC_CMD_DUMP_LOG :
2010-12-31 18:59:16 +00:00
rep_tlv_buf = tipc_cfg_reply_error_string ( TIPC_CFG_NOT_SUPPORTED
" (obsolete command) " ) ;
break ;
2006-01-02 19:04:38 +01:00
default :
2006-10-16 22:00:56 -07:00
rep_tlv_buf = tipc_cfg_reply_error_string ( TIPC_CFG_NOT_SUPPORTED
" (unknown command) " ) ;
2006-01-02 19:04:38 +01:00
break ;
}
2012-06-29 00:50:23 -04:00
WARN_ON ( rep_tlv_buf - > len > TLV_SPACE ( ULTRA_STRING_MAX_LEN ) ) ;
/* Append an error message if we cannot return all requested data */
if ( rep_tlv_buf - > len = = TLV_SPACE ( ULTRA_STRING_MAX_LEN ) ) {
if ( * ( rep_tlv_buf - > data + ULTRA_STRING_MAX_LEN ) ! = ' \0 ' )
sprintf ( rep_tlv_buf - > data + rep_tlv_buf - > len -
sizeof ( REPLY_TRUNCATED ) - 1 , REPLY_TRUNCATED ) ;
}
2006-01-02 19:04:38 +01:00
/* Return reply buffer */
exit :
2013-06-17 10:54:45 -04:00
mutex_unlock ( & config_mutex ) ;
2006-01-02 19:04:38 +01:00
return rep_tlv_buf ;
}
2013-06-17 10:54:41 -04:00
static void cfg_conn_msg_event ( int conid , struct sockaddr_tipc * addr ,
void * usr_data , void * buf , size_t len )
2006-01-02 19:04:38 +01:00
{
struct tipc_cfg_msg_hdr * req_hdr ;
struct tipc_cfg_msg_hdr * rep_hdr ;
struct sk_buff * rep_buf ;
2013-06-17 10:54:41 -04:00
int ret ;
2006-01-02 19:04:38 +01:00
/* Validate configuration message header (ignore invalid message) */
2013-06-17 10:54:41 -04:00
req_hdr = ( struct tipc_cfg_msg_hdr * ) buf ;
if ( ( len < sizeof ( * req_hdr ) ) | |
( len ! = TCM_ALIGN ( ntohl ( req_hdr - > tcm_len ) ) ) | |
2006-01-02 19:04:38 +01:00
( ntohs ( req_hdr - > tcm_flags ) ! = TCM_F_REQUEST ) ) {
2012-06-29 00:16:37 -04:00
pr_warn ( " Invalid configuration message discarded \n " ) ;
2006-01-02 19:04:38 +01:00
return ;
}
/* Generate reply for request (if can't, return request) */
2013-06-17 10:54:41 -04:00
rep_buf = tipc_cfg_do_cmd ( addr - > addr . id . node , ntohs ( req_hdr - > tcm_type ) ,
buf + sizeof ( * req_hdr ) ,
len - sizeof ( * req_hdr ) ,
2006-01-18 00:38:21 +01:00
BUF_HEADROOM + MAX_H_SIZE + sizeof ( * rep_hdr ) ) ;
2006-01-02 19:04:38 +01:00
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 ) ;
2013-06-17 10:54:41 -04:00
ret = tipc_conn_sendmsg ( & cfgsrv , conid , addr , rep_buf - > data ,
rep_buf - > len ) ;
if ( ret < 0 )
pr_err ( " Sending cfg reply message failed, no memory \n " ) ;
kfree_skb ( rep_buf ) ;
}
2006-01-02 19:04:38 +01:00
}
2013-06-17 10:54:41 -04:00
static struct sockaddr_tipc cfgsrv_addr __read_mostly = {
. family = AF_TIPC ,
. addrtype = TIPC_ADDR_NAMESEQ ,
. addr . nameseq . type = TIPC_CFG_SRV ,
. addr . nameseq . lower = 0 ,
. addr . nameseq . upper = 0 ,
. scope = TIPC_ZONE_SCOPE
} ;
static struct tipc_server cfgsrv __read_mostly = {
. saddr = & cfgsrv_addr ,
. imp = TIPC_CRITICAL_IMPORTANCE ,
. type = SOCK_RDM ,
. max_rcvbuf_size = 64 * 1024 ,
. name = " cfg_server " ,
. tipc_conn_recvmsg = cfg_conn_msg_event ,
. tipc_conn_new = NULL ,
. tipc_conn_shutdown = NULL
} ;
2006-01-18 00:38:21 +01:00
int tipc_cfg_init ( void )
2006-01-02 19:04:38 +01:00
{
2013-06-17 10:54:41 -04:00
return tipc_server_start ( & cfgsrv ) ;
2006-01-02 19:04:38 +01:00
}
2012-04-26 16:46:29 -04:00
void tipc_cfg_reinit ( void )
{
2013-06-17 10:54:41 -04:00
tipc_server_stop ( & cfgsrv ) ;
2012-04-26 16:46:29 -04:00
2013-06-17 10:54:41 -04:00
cfgsrv_addr . addr . nameseq . lower = tipc_own_addr ;
cfgsrv_addr . addr . nameseq . upper = tipc_own_addr ;
tipc_server_start ( & cfgsrv ) ;
2012-04-26 16:46:29 -04:00
}
2006-01-18 00:38:21 +01:00
void tipc_cfg_stop ( void )
2006-01-02 19:04:38 +01:00
{
2013-06-17 10:54:41 -04:00
tipc_server_stop ( & cfgsrv ) ;
2006-01-02 19:04:38 +01:00
}