Skip to content

Commit

Permalink
tipc: make tipc node table aware of net namespace
Browse files Browse the repository at this point in the history
Global variables associated with node table are below:
- node table list (node_htable)
- node hash table list (tipc_node_list)
- node table lock (node_list_lock)
- node number counter (tipc_num_nodes)
- node link number counter (tipc_num_links)

To make node table support namespace, above global variables must be
moved to tipc_net structure in order to keep secret for different
namespaces. As a consequence, these variables are allocated and
initialized when namespace is created, and deallocated when namespace
is destroyed. After the change, functions associated with these
variables have to utilize a namespace pointer to access them. So
adding namespace pointer as a parameter of these functions is the
major change made in the commit.

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 David S. Miller committed Jan 12, 2015
1 parent c93d3ba commit f2f9800
Show file tree
Hide file tree
Showing 21 changed files with 329 additions and 244 deletions.
2 changes: 2 additions & 0 deletions net/tipc/addr.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#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 Down
24 changes: 12 additions & 12 deletions net/tipc/bcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,12 @@ static void bclink_retransmit_pkt(u32 after, u32 to)
*
* Called with no locks taken
*/
void tipc_bclink_wakeup_users(void)
void tipc_bclink_wakeup_users(struct net *net)
{
struct sk_buff *skb;

while ((skb = skb_dequeue(&bclink->link.waiting_sks)))
tipc_sk_rcv(skb);

tipc_sk_rcv(net, skb);
}

/**
Expand Down Expand Up @@ -385,9 +384,9 @@ void tipc_bclink_update_link_state(struct net *net, struct tipc_node *n_ptr,
* Delay any upcoming NACK by this node if another node has already
* requested the first message this node is going to ask for.
*/
static void bclink_peek_nack(struct tipc_msg *msg)
static void bclink_peek_nack(struct net *net, struct tipc_msg *msg)
{
struct tipc_node *n_ptr = tipc_node_find(msg_destnode(msg));
struct tipc_node *n_ptr = tipc_node_find(net, msg_destnode(msg));

if (unlikely(!n_ptr))
return;
Expand All @@ -404,11 +403,12 @@ static void bclink_peek_nack(struct tipc_msg *msg)

/* tipc_bclink_xmit - broadcast buffer chain to all nodes in cluster
* and to identified node local sockets
* @net: the applicable net namespace
* @list: chain of buffers containing message
* Consumes the buffer chain, except when returning -ELINKCONG
* Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
*/
int tipc_bclink_xmit(struct sk_buff_head *list)
int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list)
{
int rc = 0;
int bc = 0;
Expand Down Expand Up @@ -443,7 +443,7 @@ int tipc_bclink_xmit(struct sk_buff_head *list)

/* Deliver message clone */
if (likely(!rc))
tipc_sk_mcast_rcv(skb);
tipc_sk_mcast_rcv(net, skb);
else
kfree_skb(skb);

Expand Down Expand Up @@ -491,7 +491,7 @@ void tipc_bclink_rcv(struct net *net, struct sk_buff *buf)
if (msg_mc_netid(msg) != tn->net_id)
goto exit;

node = tipc_node_find(msg_prevnode(msg));
node = tipc_node_find(net, msg_prevnode(msg));
if (unlikely(!node))
goto exit;

Expand All @@ -514,7 +514,7 @@ void tipc_bclink_rcv(struct net *net, struct sk_buff *buf)
tipc_bclink_unlock();
} else {
tipc_node_unlock(node);
bclink_peek_nack(msg);
bclink_peek_nack(net, msg);
}
goto exit;
}
Expand All @@ -532,7 +532,7 @@ void tipc_bclink_rcv(struct net *net, struct sk_buff *buf)
tipc_bclink_unlock();
tipc_node_unlock(node);
if (likely(msg_mcast(msg)))
tipc_sk_mcast_rcv(buf);
tipc_sk_mcast_rcv(net, buf);
else
kfree_skb(buf);
} else if (msg_user(msg) == MSG_BUNDLER) {
Expand All @@ -542,7 +542,7 @@ void tipc_bclink_rcv(struct net *net, struct sk_buff *buf)
bcl->stats.recv_bundled += msg_msgcnt(msg);
tipc_bclink_unlock();
tipc_node_unlock(node);
tipc_link_bundle_rcv(buf);
tipc_link_bundle_rcv(net, buf);
} else if (msg_user(msg) == MSG_FRAGMENTER) {
tipc_buf_append(&node->bclink.reasm_buf, &buf);
if (unlikely(!buf && !node->bclink.reasm_buf))
Expand All @@ -563,7 +563,7 @@ void tipc_bclink_rcv(struct net *net, struct sk_buff *buf)
bclink_accept_pkt(node, seqno);
tipc_bclink_unlock();
tipc_node_unlock(node);
tipc_named_rcv(buf);
tipc_named_rcv(net, buf);
} else {
tipc_bclink_lock();
bclink_accept_pkt(node, seqno);
Expand Down
4 changes: 2 additions & 2 deletions net/tipc/bcast.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ int tipc_bclink_reset_stats(void);
int tipc_bclink_set_queue_limits(u32 limit);
void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action);
uint tipc_bclink_get_mtu(void);
int tipc_bclink_xmit(struct sk_buff_head *list);
void tipc_bclink_wakeup_users(void);
int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list);
void tipc_bclink_wakeup_users(struct net *net);
int tipc_nl_add_bc_link(struct tipc_nl_msg *msg);

#endif
25 changes: 14 additions & 11 deletions net/tipc/bearer.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ static const struct nla_policy tipc_nl_media_policy[TIPC_NLA_MEDIA_MAX + 1] = {

struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1];

static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down);
static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr,
bool shutting_down);

/**
* tipc_media_find - locates specified media object by name
Expand Down Expand Up @@ -364,7 +365,7 @@ int tipc_enable_bearer(struct net *net, const char *name, u32 disc_domain,

res = tipc_disc_create(net, b_ptr, &b_ptr->bcast_addr);
if (res) {
bearer_disable(b_ptr, false);
bearer_disable(net, b_ptr, false);
pr_warn("Bearer <%s> rejected, discovery object creation failed\n",
name);
return -EINVAL;
Expand All @@ -384,7 +385,7 @@ int tipc_enable_bearer(struct net *net, const char *name, u32 disc_domain,
static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b_ptr)
{
pr_info("Resetting bearer <%s>\n", b_ptr->name);
tipc_link_reset_list(b_ptr->identity);
tipc_link_reset_list(net, b_ptr->identity);
tipc_disc_reset(net, b_ptr);
return 0;
}
Expand All @@ -394,14 +395,15 @@ static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b_ptr)
*
* Note: This routine assumes caller holds RTNL lock.
*/
static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down)
static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr,
bool shutting_down)
{
u32 i;

pr_info("Disabling bearer <%s>\n", b_ptr->name);
b_ptr->media->disable_media(b_ptr);

tipc_link_delete_list(b_ptr->identity, shutting_down);
tipc_link_delete_list(net, b_ptr->identity, shutting_down);
if (b_ptr->link_req)
tipc_disc_delete(b_ptr->link_req);

Expand All @@ -414,7 +416,7 @@ static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down)
kfree_rcu(b_ptr, rcu);
}

int tipc_disable_bearer(const char *name)
int tipc_disable_bearer(struct net *net, const char *name)
{
struct tipc_bearer *b_ptr;
int res;
Expand All @@ -424,7 +426,7 @@ int tipc_disable_bearer(const char *name)
pr_warn("Attempt to disable unknown bearer <%s>\n", name);
res = -EINVAL;
} else {
bearer_disable(b_ptr, false);
bearer_disable(net, b_ptr, false);
res = 0;
}
return res;
Expand Down Expand Up @@ -593,7 +595,7 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
break;
case NETDEV_UNREGISTER:
case NETDEV_CHANGENAME:
bearer_disable(b_ptr, false);
bearer_disable(dev_net(dev), b_ptr, false);
break;
}
return NOTIFY_OK;
Expand Down Expand Up @@ -626,15 +628,15 @@ void tipc_bearer_cleanup(void)
dev_remove_pack(&tipc_packet_type);
}

void tipc_bearer_stop(void)
void tipc_bearer_stop(struct net *net)
{
struct tipc_bearer *b_ptr;
u32 i;

for (i = 0; i < MAX_BEARERS; i++) {
b_ptr = rtnl_dereference(bearer_list[i]);
if (b_ptr) {
bearer_disable(b_ptr, true);
bearer_disable(net, b_ptr, true);
bearer_list[i] = NULL;
}
}
Expand Down Expand Up @@ -772,6 +774,7 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
char *name;
struct tipc_bearer *bearer;
struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
struct net *net = genl_info_net(info);

if (!info->attrs[TIPC_NLA_BEARER])
return -EINVAL;
Expand All @@ -794,7 +797,7 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
}

bearer_disable(bearer, false);
bearer_disable(net, bearer, false);
rtnl_unlock();

return 0;
Expand Down
4 changes: 2 additions & 2 deletions net/tipc/bearer.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ extern struct tipc_bearer __rcu *bearer_list[];
void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr);
int tipc_enable_bearer(struct net *net, const char *bearer_name,
u32 disc_domain, u32 priority);
int tipc_disable_bearer(const char *name);
int tipc_disable_bearer(struct net *net, const char *name);

/*
* Routines made available to TIPC by supported media types
Expand Down Expand Up @@ -205,7 +205,7 @@ struct tipc_bearer *tipc_bearer_find(const char *name);
struct tipc_media *tipc_media_find(const char *name);
int tipc_bearer_setup(void);
void tipc_bearer_cleanup(void);
void tipc_bearer_stop(void);
void tipc_bearer_stop(struct net *net);
void tipc_bearer_send(u32 bearer_id, struct sk_buff *buf,
struct tipc_media_addr *dest);

Expand Down
21 changes: 13 additions & 8 deletions net/tipc/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,12 @@ static struct sk_buff *cfg_enable_bearer(struct net *net)
return tipc_cfg_reply_none();
}

static struct sk_buff *cfg_disable_bearer(void)
static struct sk_buff *cfg_disable_bearer(struct net *net)
{
if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_NAME))
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);

if (tipc_disable_bearer((char *)TLV_DATA(req_tlv_area)))
if (tipc_disable_bearer(net, (char *)TLV_DATA(req_tlv_area)))
return tipc_cfg_reply_error_string("unable to disable bearer");

return tipc_cfg_reply_none();
Expand Down Expand Up @@ -232,16 +232,20 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd,
rep_tlv_buf = tipc_cfg_reply_none();
break;
case TIPC_CMD_GET_NODES:
rep_tlv_buf = tipc_node_get_nodes(req_tlv_area, req_tlv_space);
rep_tlv_buf = tipc_node_get_nodes(net, req_tlv_area,
req_tlv_space);
break;
case TIPC_CMD_GET_LINKS:
rep_tlv_buf = tipc_node_get_links(req_tlv_area, req_tlv_space);
rep_tlv_buf = tipc_node_get_links(net, req_tlv_area,
req_tlv_space);
break;
case TIPC_CMD_SHOW_LINK_STATS:
rep_tlv_buf = tipc_link_cmd_show_stats(req_tlv_area, req_tlv_space);
rep_tlv_buf = tipc_link_cmd_show_stats(net, req_tlv_area,
req_tlv_space);
break;
case TIPC_CMD_RESET_LINK_STATS:
rep_tlv_buf = tipc_link_cmd_reset_stats(req_tlv_area, req_tlv_space);
rep_tlv_buf = tipc_link_cmd_reset_stats(net, req_tlv_area,
req_tlv_space);
break;
case TIPC_CMD_SHOW_NAME_TABLE:
rep_tlv_buf = tipc_nametbl_get(req_tlv_area, req_tlv_space);
Expand All @@ -261,13 +265,14 @@ struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd,
case TIPC_CMD_SET_LINK_TOL:
case TIPC_CMD_SET_LINK_PRI:
case TIPC_CMD_SET_LINK_WINDOW:
rep_tlv_buf = tipc_link_cmd_config(req_tlv_area, req_tlv_space, cmd);
rep_tlv_buf = tipc_link_cmd_config(net, req_tlv_area,
req_tlv_space, cmd);
break;
case TIPC_CMD_ENABLE_BEARER:
rep_tlv_buf = cfg_enable_bearer(net);
break;
case TIPC_CMD_DISABLE_BEARER:
rep_tlv_buf = cfg_disable_bearer();
rep_tlv_buf = cfg_disable_bearer(net);
break;
case TIPC_CMD_SET_NODE_ADDR:
rep_tlv_buf = cfg_set_own_addr(net);
Expand Down
4 changes: 3 additions & 1 deletion net/tipc/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,15 @@ static int __net_init tipc_init_net(struct net *net)
struct tipc_net *tn = net_generic(net, tipc_net_id);

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

return 0;
}

static void __net_exit tipc_exit_net(struct net *net)
{
tipc_net_stop(net);
}

static struct pernet_operations tipc_net_ops = {
Expand Down Expand Up @@ -144,7 +147,6 @@ static int __init tipc_init(void)
static void __exit tipc_exit(void)
{
unregister_pernet_subsys(&tipc_net_ops);
tipc_net_stop();
tipc_bearer_cleanup();
tipc_netlink_stop();
tipc_subscr_stop();
Expand Down
9 changes: 9 additions & 0 deletions net/tipc/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
#include <linux/etherdevice.h>
#include <net/netns/generic.h>

#include "node.h"

#define TIPC_MOD_VER "2.0.0"

int tipc_snprintf(char *buf, int len, const char *fmt, ...);
Expand All @@ -78,6 +80,13 @@ extern int tipc_random __read_mostly;

struct tipc_net {
int net_id;

/* Node table and node list */
spinlock_t node_list_lock;
struct hlist_head node_htable[NODE_HTABLE_SIZE];
struct list_head node_list;
u32 num_nodes;
u32 num_links;
};

#ifdef CONFIG_SYSCTL
Expand Down
4 changes: 2 additions & 2 deletions net/tipc/discover.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *buf,
return;

/* Locate, or if necessary, create, node: */
node = tipc_node_find(onode);
node = tipc_node_find(net, onode);
if (!node)
node = tipc_node_create(onode);
node = tipc_node_create(net, onode);
if (!node)
return;

Expand Down
Loading

0 comments on commit f2f9800

Please sign in to comment.