diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/addr.h | 2 | ||||
-rw-r--r-- | net/tipc/bcast.c | 24 | ||||
-rw-r--r-- | net/tipc/bcast.h | 4 | ||||
-rw-r--r-- | net/tipc/bearer.c | 25 | ||||
-rw-r--r-- | net/tipc/bearer.h | 4 | ||||
-rw-r--r-- | net/tipc/config.c | 21 | ||||
-rw-r--r-- | net/tipc/core.c | 4 | ||||
-rw-r--r-- | net/tipc/core.h | 9 | ||||
-rw-r--r-- | net/tipc/discover.c | 4 | ||||
-rw-r--r-- | net/tipc/link.c | 107 | ||||
-rw-r--r-- | net/tipc/link.h | 24 | ||||
-rw-r--r-- | net/tipc/name_distr.c | 57 | ||||
-rw-r--r-- | net/tipc/name_distr.h | 10 | ||||
-rw-r--r-- | net/tipc/name_table.c | 16 | ||||
-rw-r--r-- | net/tipc/name_table.h | 8 | ||||
-rw-r--r-- | net/tipc/net.c | 11 | ||||
-rw-r--r-- | net/tipc/net.h | 2 | ||||
-rw-r--r-- | net/tipc/node.c | 130 | ||||
-rw-r--r-- | net/tipc/node.h | 35 | ||||
-rw-r--r-- | net/tipc/socket.c | 72 | ||||
-rw-r--r-- | net/tipc/socket.h | 4 |
21 files changed, 329 insertions, 244 deletions
diff --git a/net/tipc/addr.h b/net/tipc/addr.h index 60b00ab93d74..3e1f18e29f1e 100644 --- a/net/tipc/addr.h +++ b/net/tipc/addr.h @@ -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; diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index f98231138916..816c0e49319f 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -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); } /** @@ -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; @@ -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; @@ -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); @@ -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; @@ -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; } @@ -532,7 +532,7 @@ receive: 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) { @@ -542,7 +542,7 @@ receive: 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)) @@ -563,7 +563,7 @@ receive: 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); diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h index a5fd22438aed..fd0d17a76493 100644 --- a/net/tipc/bcast.h +++ b/net/tipc/bcast.h @@ -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 diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index cdd30337dc5e..a735c08e9d90 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -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 @@ -364,7 +365,7 @@ restart: 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; @@ -384,7 +385,7 @@ restart: 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; } @@ -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); @@ -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; @@ -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; @@ -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; @@ -626,7 +628,7 @@ 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; @@ -634,7 +636,7 @@ void tipc_bearer_stop(void) 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; } } @@ -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; @@ -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; diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 43f683aebbbe..91a8eeea309c 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -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 @@ -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); diff --git a/net/tipc/config.c b/net/tipc/config.c index 28d4272803c4..cf2d417ad488 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -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(); @@ -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); @@ -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); diff --git a/net/tipc/core.c b/net/tipc/core.c index a2302480d8cf..7b8443938caf 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -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 = { @@ -144,7 +147,6 @@ out_pernet: static void __exit tipc_exit(void) { unregister_pernet_subsys(&tipc_net_ops); - tipc_net_stop(); tipc_bearer_cleanup(); tipc_netlink_stop(); tipc_subscr_stop(); diff --git a/net/tipc/core.h b/net/tipc/core.h index 106e8150c3a6..4fb113397e7b 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -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, ...); @@ -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 diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 246a23788ded..f0fd8b449aef 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -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; diff --git a/net/tipc/link.c b/net/tipc/link.c index 248813cb6d68..f6505652742e 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -114,7 +114,8 @@ static void link_reset_statistics(struct tipc_link *l_ptr); static void link_print(struct tipc_link *l_ptr, const char *str); static void tipc_link_sync_xmit(struct tipc_link *l); static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf); -static int tipc_link_input(struct tipc_link *l, struct sk_buff *buf); +static int tipc_link_input(struct net *net, struct tipc_link *l, + struct sk_buff *buf); static int tipc_link_prepare_input(struct net *net, struct tipc_link *l, struct sk_buff **buf); @@ -310,13 +311,15 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, return l_ptr; } -void tipc_link_delete_list(unsigned int bearer_id, bool shutting_down) +void tipc_link_delete_list(struct net *net, unsigned int bearer_id, + bool shutting_down) { + struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_link *l_ptr; struct tipc_node *n_ptr; rcu_read_lock(); - list_for_each_entry_rcu(n_ptr, &tipc_node_list, list) { + list_for_each_entry_rcu(n_ptr, &tn->node_list, list) { tipc_node_lock(n_ptr); l_ptr = n_ptr->links[bearer_id]; if (l_ptr) { @@ -451,13 +454,14 @@ void tipc_link_reset(struct tipc_link *l_ptr) link_reset_statistics(l_ptr); } -void tipc_link_reset_list(unsigned int bearer_id) +void tipc_link_reset_list(struct net *net, unsigned int bearer_id) { + struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_link *l_ptr; struct tipc_node *n_ptr; rcu_read_lock(); - list_for_each_entry_rcu(n_ptr, &tipc_node_list, list) { + list_for_each_entry_rcu(n_ptr, &tn->node_list, list) { tipc_node_lock(n_ptr); l_ptr = n_ptr->links[bearer_id]; if (l_ptr) @@ -773,16 +777,18 @@ static int __tipc_link_xmit_skb(struct tipc_link *link, struct sk_buff *skb) return __tipc_link_xmit(link, &head); } -int tipc_link_xmit_skb(struct sk_buff *skb, u32 dnode, u32 selector) +int tipc_link_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode, + u32 selector) { struct sk_buff_head head; skb2list(skb, &head); - return tipc_link_xmit(&head, dnode, selector); + return tipc_link_xmit(net, &head, dnode, selector); } /** * tipc_link_xmit() is the general link level function for message sending + * @net: the applicable net namespace * @list: chain of buffers containing message * @dsz: amount of user data to be sent * @dnode: address of destination node @@ -790,13 +796,14 @@ int tipc_link_xmit_skb(struct sk_buff *skb, u32 dnode, u32 selector) * Consumes the buffer chain, except when returning -ELINKCONG * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE */ -int tipc_link_xmit(struct sk_buff_head *list, u32 dnode, u32 selector) +int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode, + u32 selector) { struct tipc_link *link = NULL; struct tipc_node *node; int rc = -EHOSTUNREACH; - node = tipc_node_find(dnode); + node = tipc_node_find(net, dnode); if (node) { tipc_node_lock(node); link = node->active_links[selector & 1]; @@ -813,7 +820,7 @@ int tipc_link_xmit(struct sk_buff_head *list, u32 dnode, u32 selector) * buffer, we just need to dequeue one SKB buffer from the * head list. */ - return tipc_sk_rcv(__skb_dequeue(list)); + return tipc_sk_rcv(net, __skb_dequeue(list)); } __skb_queue_purge(list); @@ -1066,7 +1073,7 @@ static int link_recv_buf_validate(struct sk_buff *buf) /** * tipc_rcv - process TIPC packets/messages arriving from off-node - * @net: net namespace handler + * @net: the applicable net namespace * @skb: TIPC packet * @b_ptr: pointer to bearer message arrived on * @@ -1112,7 +1119,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr) goto discard; /* Locate neighboring node that sent message */ - n_ptr = tipc_node_find(msg_prevnode(msg)); + n_ptr = tipc_node_find(net, msg_prevnode(msg)); if (unlikely(!n_ptr)) goto discard; tipc_node_lock(n_ptr); @@ -1203,7 +1210,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr) } tipc_node_unlock(n_ptr); - if (tipc_link_input(l_ptr, skb) != 0) + if (tipc_link_input(net, l_ptr, skb) != 0) goto discard; continue; unlock_discard: @@ -1263,7 +1270,8 @@ static int tipc_link_prepare_input(struct net *net, struct tipc_link *l, /** * tipc_link_input - Deliver message too higher layers */ -static int tipc_link_input(struct tipc_link *l, struct sk_buff *buf) +static int tipc_link_input(struct net *net, struct tipc_link *l, + struct sk_buff *buf) { struct tipc_msg *msg = buf_msg(buf); int res = 0; @@ -1274,13 +1282,13 @@ static int tipc_link_input(struct tipc_link *l, struct sk_buff *buf) case TIPC_HIGH_IMPORTANCE: case TIPC_CRITICAL_IMPORTANCE: case CONN_MANAGER: - tipc_sk_rcv(buf); + tipc_sk_rcv(net, buf); break; case NAME_DISTRIBUTOR: - tipc_named_rcv(buf); + tipc_named_rcv(net, buf); break; case MSG_BUNDLER: - tipc_link_bundle_rcv(buf); + tipc_link_bundle_rcv(net, buf); break; default: res = -EINVAL; @@ -1855,7 +1863,7 @@ exit: /* * Bundler functionality: */ -void tipc_link_bundle_rcv(struct sk_buff *buf) +void tipc_link_bundle_rcv(struct net *net, struct sk_buff *buf) { u32 msgcount = msg_msgcnt(buf_msg(buf)); u32 pos = INT_H_SIZE; @@ -1872,13 +1880,13 @@ void tipc_link_bundle_rcv(struct sk_buff *buf) pos += align(msg_size(omsg)); if (msg_isdata(omsg)) { if (unlikely(msg_type(omsg) == TIPC_MCAST_MSG)) - tipc_sk_mcast_rcv(obuf); + tipc_sk_mcast_rcv(net, obuf); else - tipc_sk_rcv(obuf); + tipc_sk_rcv(net, obuf); } else if (msg_user(omsg) == CONN_MANAGER) { - tipc_sk_rcv(obuf); + tipc_sk_rcv(net, obuf); } else if (msg_user(omsg) == NAME_DISTRIBUTOR) { - tipc_named_rcv(obuf); + tipc_named_rcv(net, obuf); } else { pr_warn("Illegal bundled msg: %u\n", msg_user(omsg)); kfree_skb(obuf); @@ -1919,14 +1927,17 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window) } /* tipc_link_find_owner - locate owner node of link by link's name + * @net: the applicable net namespace * @name: pointer to link name string * @bearer_id: pointer to index in 'node->links' array where the link was found. * * Returns pointer to node owning the link, or 0 if no matching link is found. */ -static struct tipc_node *tipc_link_find_owner(const char *link_name, +static struct tipc_node *tipc_link_find_owner(struct net *net, + const char *link_name, unsigned int *bearer_id) { + struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_link *l_ptr; struct tipc_node *n_ptr; struct tipc_node *found_node = NULL; @@ -1934,7 +1945,7 @@ static struct tipc_node *tipc_link_find_owner(const char *link_name, *bearer_id = 0; rcu_read_lock(); - list_for_each_entry_rcu(n_ptr, &tipc_node_list, list) { + list_for_each_entry_rcu(n_ptr, &tn->node_list, list) { tipc_node_lock(n_ptr); for (i = 0; i < MAX_BEARERS; i++) { l_ptr = n_ptr->links[i]; @@ -1978,6 +1989,7 @@ static int link_value_is_valid(u16 cmd, u32 new_value) /** * link_cmd_set_value - change priority/tolerance/window for link/bearer/media + * @net: the applicable net namespace * @name: ptr to link, bearer, or media name * @new_value: new value of link, bearer, or media setting * @cmd: which link, bearer, or media attribute to set (TIPC_CMD_SET_LINK_*) @@ -1986,7 +1998,8 @@ static int link_value_is_valid(u16 cmd, u32 new_value) * * Returns 0 if value updated and negative value on error. */ -static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd) +static int link_cmd_set_value(struct net *net, const char *name, u32 new_value, + u16 cmd) { struct tipc_node *node; struct tipc_link *l_ptr; @@ -1995,7 +2008,7 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd) int bearer_id; int res = 0; - node = tipc_link_find_owner(name, &bearer_id); + node = tipc_link_find_owner(net, name, &bearer_id); if (node) { tipc_node_lock(node); l_ptr = node->links[bearer_id]; @@ -2063,8 +2076,8 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd) return res; } -struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space, - u16 cmd) +struct sk_buff *tipc_link_cmd_config(struct net *net, const void *req_tlv_area, + int req_tlv_space, u16 cmd) { struct tipc_link_config *args; u32 new_value; @@ -2088,7 +2101,7 @@ struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space " (cannot change setting on broadcast link)"); } - res = link_cmd_set_value(args->name, new_value, cmd); + res = link_cmd_set_value(net, args->name, new_value, cmd); if (res) return tipc_cfg_reply_error_string("cannot change link setting"); @@ -2106,7 +2119,9 @@ static void link_reset_statistics(struct tipc_link *l_ptr) l_ptr->stats.recv_info = l_ptr->next_in_no; } -struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_space) +struct sk_buff *tipc_link_cmd_reset_stats(struct net *net, + const void *req_tlv_area, + int req_tlv_space) { char *link_name; struct tipc_link *l_ptr; @@ -2122,7 +2137,7 @@ struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_ return tipc_cfg_reply_error_string("link not found"); return tipc_cfg_reply_none(); } - node = tipc_link_find_owner(link_name, &bearer_id); + node = tipc_link_find_owner(net, link_name, &bearer_id); if (!node) return tipc_cfg_reply_error_string("link not found"); @@ -2147,13 +2162,15 @@ static u32 percent(u32 count, u32 total) /** * tipc_link_stats - print link statistics + * @net: the applicable net namespace * @name: link name * @buf: print buffer area * @buf_size: size of print buffer area * * Returns length of print buffer data string (or 0 if error) */ -static int tipc_link_stats(const char *name, char *buf, const u32 buf_size) +static int tipc_link_stats(struct net *net, const char *name, char *buf, + const u32 buf_size) { struct tipc_link *l; struct tipc_stats *s; @@ -2166,7 +2183,7 @@ static int tipc_link_stats(const char *name, char *buf, const u32 buf_size) if (!strcmp(name, tipc_bclink_name)) return tipc_bclink_stats(buf, buf_size); - node = tipc_link_find_owner(name, &bearer_id); + node = tipc_link_find_owner(net, name, &bearer_id); if (!node) return 0; @@ -2243,7 +2260,9 @@ static int tipc_link_stats(const char *name, char *buf, const u32 buf_size) return ret; } -struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space) +struct sk_buff *tipc_link_cmd_show_stats(struct net *net, + const void *req_tlv_area, + int req_tlv_space) { struct sk_buff *buf; struct tlv_desc *rep_tlv; @@ -2261,7 +2280,7 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s rep_tlv = (struct tlv_desc *)buf->data; pb = TLV_DATA(rep_tlv); pb_len = ULTRA_STRING_MAX_LEN; - str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area), + str_len = tipc_link_stats(net, (char *)TLV_DATA(req_tlv_area), pb, pb_len); if (!str_len) { kfree_skb(buf); @@ -2343,6 +2362,7 @@ int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info) struct tipc_link *link; struct tipc_node *node; struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1]; + struct net *net = genl_info_net(info); if (!info->attrs[TIPC_NLA_LINK]) return -EINVAL; @@ -2358,7 +2378,7 @@ int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info) name = nla_data(attrs[TIPC_NLA_LINK_NAME]); - node = tipc_link_find_owner(name, &bearer_id); + node = tipc_link_find_owner(net, name, &bearer_id); if (!node) return -EINVAL; @@ -2567,6 +2587,8 @@ static int __tipc_nl_add_node_links(struct tipc_nl_msg *msg, int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb) { + struct net *net = sock_net(skb->sk); + struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_node *node; struct tipc_nl_msg msg; u32 prev_node = cb->args[0]; @@ -2584,7 +2606,7 @@ int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb) rcu_read_lock(); if (prev_node) { - node = tipc_node_find(prev_node); + node = tipc_node_find(net, prev_node); if (!node) { /* We never set seq or call nl_dump_check_consistent() * this means that setting prev_seq here will cause the @@ -2596,7 +2618,8 @@ int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb) goto out; } - list_for_each_entry_continue_rcu(node, &tipc_node_list, list) { + list_for_each_entry_continue_rcu(node, &tn->node_list, + list) { tipc_node_lock(node); err = __tipc_nl_add_node_links(&msg, node, &prev_link); tipc_node_unlock(node); @@ -2610,7 +2633,7 @@ int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb) if (err) goto out; - list_for_each_entry_rcu(node, &tipc_node_list, list) { + list_for_each_entry_rcu(node, &tn->node_list, list) { tipc_node_lock(node); err = __tipc_nl_add_node_links(&msg, node, &prev_link); tipc_node_unlock(node); @@ -2633,6 +2656,7 @@ out: int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info) { + struct net *net = genl_info_net(info); struct sk_buff *ans_skb; struct tipc_nl_msg msg; struct tipc_link *link; @@ -2645,7 +2669,7 @@ int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info) return -EINVAL; name = nla_data(info->attrs[TIPC_NLA_LINK_NAME]); - node = tipc_link_find_owner(name, &bearer_id); + node = tipc_link_find_owner(net, name, &bearer_id); if (!node) return -EINVAL; @@ -2687,6 +2711,7 @@ int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info) struct tipc_link *link; struct tipc_node *node; struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1]; + struct net *net = genl_info_net(info); if (!info->attrs[TIPC_NLA_LINK]) return -EINVAL; @@ -2709,7 +2734,7 @@ int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info) return 0; } - node = tipc_link_find_owner(link_name, &bearer_id); + node = tipc_link_find_owner(net, link_name, &bearer_id); if (!node) return -EINVAL; diff --git a/net/tipc/link.h b/net/tipc/link.h index 692268dca4b9..380e27ee0f70 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -200,27 +200,31 @@ struct tipc_port; struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, struct tipc_bearer *b_ptr, const struct tipc_media_addr *media_addr); -void tipc_link_delete_list(unsigned int bearer_id, bool shutting_down); +void tipc_link_delete_list(struct net *net, unsigned int bearer_id, + bool shutting_down); void tipc_link_failover_send_queue(struct tipc_link *l_ptr); void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr, struct tipc_link *dest); void tipc_link_reset_fragments(struct tipc_link *l_ptr); int tipc_link_is_up(struct tipc_link *l_ptr); int tipc_link_is_active(struct tipc_link *l_ptr); void tipc_link_purge_queues(struct tipc_link *l_ptr); -struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, - int req_tlv_space, - u16 cmd); -struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, +struct sk_buff *tipc_link_cmd_config(struct net *net, const void *req_tlv_area, + int req_tlv_space, u16 cmd); +struct sk_buff *tipc_link_cmd_show_stats(struct net *net, + const void *req_tlv_area, int req_tlv_space); -struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, +struct sk_buff *tipc_link_cmd_reset_stats(struct net *net, + const void *req_tlv_area, int req_tlv_space); void tipc_link_reset_all(struct tipc_node *node); void tipc_link_reset(struct tipc_link *l_ptr); -void tipc_link_reset_list(unsigned int bearer_id); -int tipc_link_xmit_skb(struct sk_buff *skb, u32 dest, u32 selector); -int tipc_link_xmit(struct sk_buff_head *list, u32 dest, u32 selector); +void tipc_link_reset_list(struct net *net, unsigned int bearer_id); +int tipc_link_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest, + u32 selector); +int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dest, + u32 selector); int __tipc_link_xmit(struct tipc_link *link, struct sk_buff_head *list); -void tipc_link_bundle_rcv(struct sk_buff *buf); +void tipc_link_bundle_rcv(struct net *net, struct sk_buff *buf); void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int prob, u32 gap, u32 tolerance, u32 priority, u32 acked_mtu); void tipc_link_push_packets(struct tipc_link *l_ptr); |