Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34747539 authored by Ying Xue's avatar Ying Xue Committed by David S. Miller
Browse files

tipc: make tipc node address support net namespace



If net namespace is supported in tipc, each namespace will be treated
as a separate tipc node. Therefore, every namespace must own its
private tipc node address. This means the "tipc_own_addr" global
variable of node address must be moved to tipc_net structure to
satisfy the requirement. It's turned out that users also can assign
node address for every namespace.

Signed-off-by: default avatarYing Xue <ying.xue@windriver.com>
Tested-by: default avatarTero Aho <Tero.Aho@coriant.com>
Reviewed-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4ac1c8d0
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -36,6 +36,49 @@

#include <linux/kernel.h>
#include "addr.h"
#include "core.h"

/**
 * in_own_cluster - test for cluster inclusion; <0.0.0> always matches
 */
int in_own_cluster(struct net *net, u32 addr)
{
	return in_own_cluster_exact(net, addr) || !addr;
}

int in_own_cluster_exact(struct net *net, u32 addr)
{
	struct tipc_net *tn = net_generic(net, tipc_net_id);

	return !((addr ^ tn->own_addr) >> 12);
}

/**
 * in_own_node - test for node inclusion; <0.0.0> always matches
 */
int in_own_node(struct net *net, u32 addr)
{
	struct tipc_net *tn = net_generic(net, tipc_net_id);

	return (addr == tn->own_addr) || !addr;
}

/**
 * addr_domain - convert 2-bit scope value to equivalent message lookup domain
 *
 * Needed when address of a named message must be looked up a second time
 * after a network hop.
 */
u32 addr_domain(struct net *net, u32 sc)
{
	struct tipc_net *tn = net_generic(net, tipc_net_id);

	if (likely(sc == TIPC_NODE_SCOPE))
		return tn->own_addr;
	if (sc == TIPC_CLUSTER_SCOPE)
		return tipc_cluster_mask(tn->own_addr);
	return tipc_zone_mask(tn->own_addr);
}

/**
 * tipc_addr_domain_valid - validates a network domain address
+6 −38
Original line number Diff line number Diff line
@@ -39,12 +39,12 @@

#include <linux/types.h>
#include <linux/tipc.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>

#define TIPC_ZONE_MASK		0xff000000u
#define TIPC_CLUSTER_MASK	0xfffff000u

extern u32 tipc_own_addr __read_mostly;

static inline u32 tipc_zone_mask(u32 addr)
{
	return addr & TIPC_ZONE_MASK;
@@ -55,42 +55,10 @@ static inline u32 tipc_cluster_mask(u32 addr)
	return addr & TIPC_CLUSTER_MASK;
}

static inline int in_own_cluster_exact(u32 addr)
{
	return !((addr ^ tipc_own_addr) >> 12);
}

/**
 * in_own_node - test for node inclusion; <0.0.0> always matches
 */
static inline int in_own_node(u32 addr)
{
	return (addr == tipc_own_addr) || !addr;
}

/**
 * in_own_cluster - test for cluster inclusion; <0.0.0> always matches
 */
static inline int in_own_cluster(u32 addr)
{
	return in_own_cluster_exact(addr) || !addr;
}

/**
 * addr_domain - convert 2-bit scope value to equivalent message lookup domain
 *
 * Needed when address of a named message must be looked up a second time
 * after a network hop.
 */
static inline u32 addr_domain(u32 sc)
{
	if (likely(sc == TIPC_NODE_SCOPE))
		return tipc_own_addr;
	if (sc == TIPC_CLUSTER_SCOPE)
		return tipc_cluster_mask(tipc_own_addr);
	return tipc_zone_mask(tipc_own_addr);
}

int in_own_cluster(struct net *net, u32 addr);
int in_own_cluster_exact(struct net *net, u32 addr);
int in_own_node(struct net *net, u32 addr);
u32 addr_domain(struct net *net, u32 sc);
int tipc_addr_domain_valid(u32);
int tipc_addr_node_valid(u32 addr);
int tipc_in_scope(u32 domain, u32 addr);
+3 −3
Original line number Diff line number Diff line
@@ -317,7 +317,7 @@ void tipc_bclink_update_link_state(struct net *net, struct tipc_node *n_ptr,
		struct sk_buff *skb = skb_peek(&n_ptr->bclink.deferred_queue);
		u32 to = skb ? buf_seqno(skb) - 1 : n_ptr->bclink.last_sent;

		tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
		tipc_msg_init(net, msg, BCAST_PROTOCOL, STATE_MSG,
			      INT_H_SIZE, n_ptr->addr);
		msg_set_non_seq(msg, 1);
		msg_set_mc_netid(msg, tn->net_id);
@@ -428,7 +428,7 @@ static void bclink_accept_pkt(struct tipc_node *node, u32 seqno)
	 * Unicast an ACK periodically, ensuring that
	 * all nodes in the cluster don't ACK at the same time
	 */
	if (((seqno - tipc_own_addr) % TIPC_MIN_LINK_WIN) == 0) {
	if (((seqno - tn->own_addr) % TIPC_MIN_LINK_WIN) == 0) {
		tipc_link_proto_xmit(node->active_links[node->addr & 1],
				     STATE_MSG, 0, 0, 0, 0, 0);
		tn->bcl->stats.sent_acks++;
@@ -466,7 +466,7 @@ void tipc_bclink_rcv(struct net *net, struct sk_buff *buf)
	if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) {
		if (msg_type(msg) != STATE_MSG)
			goto unlock;
		if (msg_destnode(msg) == tipc_own_addr) {
		if (msg_destnode(msg) == tn->own_addr) {
			tipc_bclink_acknowledge(node, msg_bcast_ack(msg));
			tipc_node_unlock(node);
			tipc_bclink_lock(net);
+7 −6
Original line number Diff line number Diff line
@@ -278,7 +278,7 @@ int tipc_enable_bearer(struct net *net, const char *name, u32 disc_domain,
	u32 i;
	int res = -EINVAL;

	if (!tipc_own_addr) {
	if (!tn->own_addr) {
		pr_warn("Bearer <%s> rejected, not supported in standalone mode\n",
			name);
		return -ENOPROTOOPT;
@@ -288,11 +288,11 @@ int tipc_enable_bearer(struct net *net, const char *name, u32 disc_domain,
		return -EINVAL;
	}
	if (tipc_addr_domain_valid(disc_domain) &&
	    (disc_domain != tipc_own_addr)) {
		if (tipc_in_scope(disc_domain, tipc_own_addr)) {
			disc_domain = tipc_own_addr & TIPC_CLUSTER_MASK;
	    (disc_domain != tn->own_addr)) {
		if (tipc_in_scope(disc_domain, tn->own_addr)) {
			disc_domain = tn->own_addr & TIPC_CLUSTER_MASK;
			res = 0;   /* accept any node in own cluster */
		} else if (in_own_cluster_exact(disc_domain))
		} else if (in_own_cluster_exact(net, disc_domain))
			res = 0;   /* accept specified node in own cluster */
	}
	if (res) {
@@ -817,6 +817,7 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
{
	struct net *net = genl_info_net(info);
	struct tipc_net *tn = net_generic(net, tipc_net_id);
	int err;
	char *bearer;
	struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
@@ -824,7 +825,7 @@ int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
	u32 prio;

	prio = TIPC_MEDIA_LINK_PRI;
	domain = tipc_own_addr & TIPC_CLUSTER_MASK;
	domain = tn->own_addr & TIPC_CLUSTER_MASK;

	if (!info->attrs[TIPC_NLA_BEARER])
		return -EINVAL;
+5 −4
Original line number Diff line number Diff line
@@ -163,18 +163,19 @@ static struct sk_buff *cfg_disable_bearer(struct net *net)

static struct sk_buff *cfg_set_own_addr(struct net *net)
{
	struct tipc_net *tn = net_generic(net, tipc_net_id);
	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)
	if (addr == tn->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)
	if (tn->own_addr)
		return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
						   " (cannot change node address once assigned)");
	if (!tipc_net_start(net, addr))
@@ -196,7 +197,7 @@ static struct sk_buff *cfg_set_netid(struct net *net)
	if (value < 1 || value > 9999)
		return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
						   " (network id must be 1-9999)");
	if (tipc_own_addr)
	if (tn->own_addr)
		return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
			" (cannot change network id once TIPC has joined a network)");
	tn->net_id = value;
@@ -218,7 +219,7 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd,
	rep_headroom = reply_headroom;

	/* Check command authorization */
	if (likely(in_own_node(orig_node))) {
	if (likely(in_own_node(net, orig_node))) {
		/* command is permitted */
	} else {
		rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
Loading