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_own_addr) return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED " (cannot change node address once assigned)"); /* * Must temporarily release configuration spinlock while switching into * networking mode as it calls tipc_eth_media_start(), which may sleep. * Releasing the lock is harmless as other locally-issued configuration * commands won't occur until this one completes, and remotely-issued * configuration commands can't be received until a local configuration * command to enable the first bearer is received and processed. */ spin_unlock_bh(&config_lock); tipc_core_start_net(addr); spin_lock_bh(&config_lock); 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_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_own_addr) return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED " (cannot change node address once assigned)"); tipc_core_start_net(addr); return tipc_cfg_reply_none(); }