Skip to content

Commit

Permalink
[TIPC]: Disallow config operations that aren't supported in certain m…
Browse files Browse the repository at this point in the history
…odes.

This change provides user-friendly feedback when TIPC is unable to perform
certain configuration operations that don't work properly in certain modes.
(In particular, any reconfiguration request that would temporarily take TIPC
from network mode to standalone mode, or from standalone mode to not running
mode, is disallowed.)

Signed-off-by: Allan Stephens <[email protected]>
Signed-off-by: Per Liden <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
ajstephens authored and davem330 committed Jun 26, 2006
1 parent c33d53b commit e100ae9
Showing 1 changed file with 38 additions and 45 deletions.
83 changes: 38 additions & 45 deletions net/tipc/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,22 @@ static struct sk_buff *cfg_set_own_addr(void)
if (!tipc_addr_node_valid(addr))
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (node address)");
if (tipc_own_addr)
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_stop_net();
tipc_own_addr = addr;
tipc_core_start_net();
spin_lock_bh(&config_lock);
return tipc_cfg_reply_none();
Expand Down Expand Up @@ -350,50 +359,21 @@ static struct sk_buff *cfg_set_max_subscriptions(void)

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 tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
value = *(u32 *)TLV_DATA(req_tlv_area);
value = ntohl(value);
if (value == tipc_max_ports)
return tipc_cfg_reply_none();
if (value != delimit(value, 127, 65535))
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (max ports must be 127-65535)");

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

if (atomic_read(&tipc_user_count) > 2)
if (tipc_mode != TIPC_NOT_RUNNING)
return tipc_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)
tipc_core_stop_net();
tipc_core_stop();
" (cannot change max ports while TIPC is active)");
tipc_max_ports = value;
tipc_core_start();
if (orig_mode == TIPC_NET_MODE)
tipc_core_start_net();
spin_lock_bh(&config_lock);
return tipc_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)
tipc_core_stop_net();
*parameter = value;
if (orig_mode == TIPC_NET_MODE)
tipc_core_start_net();
}

return tipc_cfg_reply_none();
}

Expand All @@ -405,10 +385,16 @@ static struct sk_buff *cfg_set_max_zones(void)
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
value = *(u32 *)TLV_DATA(req_tlv_area);
value = ntohl(value);
if (value == tipc_max_zones)
return tipc_cfg_reply_none();
if (value != delimit(value, 1, 255))
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (max zones must be 1-255)");
return set_net_max(value, &tipc_max_zones);
if (tipc_mode == TIPC_NET_MODE)
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (cannot change max zones once TIPC has joined a network)");
tipc_max_zones = value;
return tipc_cfg_reply_none();
}

static struct sk_buff *cfg_set_max_clusters(void)
Expand All @@ -419,8 +405,8 @@ static struct sk_buff *cfg_set_max_clusters(void)
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
value = *(u32 *)TLV_DATA(req_tlv_area);
value = ntohl(value);
if (value != 1)
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
if (value != delimit(value, 1, 1))
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (max clusters fixed at 1)");
return tipc_cfg_reply_none();
}
Expand All @@ -433,10 +419,16 @@ static struct sk_buff *cfg_set_max_nodes(void)
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
value = *(u32 *)TLV_DATA(req_tlv_area);
value = ntohl(value);
if (value == tipc_max_nodes)
return tipc_cfg_reply_none();
if (value != delimit(value, 8, 2047))
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (max nodes must be 8-2047)");
return set_net_max(value, &tipc_max_nodes);
if (tipc_mode == TIPC_NET_MODE)
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (cannot change max nodes once TIPC has joined a network)");
tipc_max_nodes = value;
return tipc_cfg_reply_none();
}

static struct sk_buff *cfg_set_max_slaves(void)
Expand All @@ -461,15 +453,16 @@ static struct sk_buff *cfg_set_netid(void)
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
value = *(u32 *)TLV_DATA(req_tlv_area);
value = ntohl(value);
if (value == tipc_net_id)
return tipc_cfg_reply_none();
if (value != delimit(value, 1, 9999))
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (network id must be 1-9999)");

if (tipc_own_addr)
if (tipc_mode == TIPC_NET_MODE)
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (cannot change network id once part of network)");

return set_net_max(value, &tipc_net_id);
" (cannot change network id once TIPC has joined a network)");
tipc_net_id = value;
return tipc_cfg_reply_none();
}

struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area,
Expand Down

0 comments on commit e100ae9

Please sign in to comment.