Skip to content

Commit

Permalink
tipc: make tipc node address support net namespace
Browse files Browse the repository at this point in the history
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: Ying Xue <ying.xue@windriver.com>
Tested-by: Tero Aho <Tero.Aho@coriant.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
ying-xue authored and davem330 committed Jan 12, 2015
1 parent 4ac1c8d commit 3474753
Show file tree
Hide file tree
Showing 17 changed files with 246 additions and 194 deletions.
43 changes: 43 additions & 0 deletions net/tipc/addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
44 changes: 6 additions & 38 deletions net/tipc/addr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions net/tipc/bcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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++;
Expand Down Expand Up @@ -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);
Expand Down
13 changes: 7 additions & 6 deletions net/tipc/bearer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -817,14 +817,15 @@ 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];
u32 domain;
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;
Expand Down
9 changes: 5 additions & 4 deletions net/tipc/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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;
Expand All @@ -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
Expand Down
4 changes: 1 addition & 3 deletions net/tipc/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
int tipc_random __read_mostly;

/* configurable TIPC parameters */
u32 tipc_own_addr __read_mostly;
int tipc_net_id __read_mostly;
int sysctl_tipc_rmem[3] __read_mostly; /* min/default/max */

Expand All @@ -58,6 +57,7 @@ static int __net_init tipc_init_net(struct net *net)
int err;

tn->net_id = 4711;
tn->own_addr = 0;
INIT_LIST_HEAD(&tn->node_list);
spin_lock_init(&tn->node_list_lock);

Expand Down Expand Up @@ -96,8 +96,6 @@ static int __init tipc_init(void)

pr_info("Activated (version " TIPC_MOD_VER ")\n");

tipc_own_addr = 0;

sysctl_tipc_rmem[0] = TIPC_CONN_OVERLOAD_LIMIT >> 4 <<
TIPC_LOW_IMPORTANCE;
sysctl_tipc_rmem[1] = TIPC_CONN_OVERLOAD_LIMIT >> 4 <<
Expand Down
5 changes: 1 addition & 4 deletions net/tipc/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,6 @@

int tipc_snprintf(char *buf, int len, const char *fmt, ...);

/*
* Global configuration variables
*/
extern u32 tipc_own_addr __read_mostly;
extern int tipc_net_id __read_mostly;
extern int sysctl_tipc_rmem[3] __read_mostly;
extern int sysctl_tipc_named_timeout __read_mostly;
Expand All @@ -86,6 +82,7 @@ extern int sysctl_tipc_named_timeout __read_mostly;
extern int tipc_random __read_mostly;

struct tipc_net {
u32 own_addr;
int net_id;

/* Node table and node list */
Expand Down
8 changes: 4 additions & 4 deletions net/tipc/discover.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ static void tipc_disc_init_msg(struct net *net, struct sk_buff *buf, u32 type,
u32 dest_domain = b_ptr->domain;

msg = buf_msg(buf);
tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
tipc_msg_init(net, msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
msg_set_non_seq(msg, 1);
msg_set_node_sig(msg, tipc_random);
msg_set_dest_domain(msg, dest_domain);
Expand Down Expand Up @@ -153,12 +153,12 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *buf,
if (!tipc_addr_node_valid(onode))
return;

if (in_own_node(onode)) {
if (in_own_node(net, onode)) {
if (memcmp(&maddr, &bearer->addr, sizeof(maddr)))
disc_dupl_alert(bearer, tipc_own_addr, &maddr);
disc_dupl_alert(bearer, tn->own_addr, &maddr);
return;
}
if (!tipc_in_scope(ddom, tipc_own_addr))
if (!tipc_in_scope(ddom, tn->own_addr))
return;
if (!tipc_in_scope(bearer->domain, onode))
return;
Expand Down
Loading

0 comments on commit 3474753

Please sign in to comment.