aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/bearer.c
diff options
context:
space:
mode:
authorYing Xue <ying.xue@windriver.com>2015-01-09 02:27:06 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-12 16:24:32 -0500
commit7f9f95d9d9bcdf253c4149a157b096958013eceb (patch)
tree779858049250f786a0b1b2d89482f3cdccd9617f /net/tipc/bearer.c
parentf2f9800d4955a96d92896841d8ba9b04201deaa1 (diff)
tipc: make bearer list support net namespace
Bearer list defined as a global variable is used to store bearer instances. When tipc supports net namespace, bearers created in one namespace must be isolated with others allocated in other namespaces, which requires us that the bearer list(bearer_list) must be moved to tipc_net structure. As a result, a net namespace pointer has to be passed to functions which access the bearer list. 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>
Diffstat (limited to 'net/tipc/bearer.c')
-rw-r--r--net/tipc/bearer.c67
1 files changed, 39 insertions, 28 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index a735c08e9d90..2fe9dcb418d4 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -34,6 +34,7 @@
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37#include <net/sock.h>
37#include "core.h" 38#include "core.h"
38#include "config.h" 39#include "config.h"
39#include "bearer.h" 40#include "bearer.h"
@@ -67,8 +68,6 @@ static const struct nla_policy tipc_nl_media_policy[TIPC_NLA_MEDIA_MAX + 1] = {
67 [TIPC_NLA_MEDIA_PROP] = { .type = NLA_NESTED } 68 [TIPC_NLA_MEDIA_PROP] = { .type = NLA_NESTED }
68}; 69};
69 70
70struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1];
71
72static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr, 71static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr,
73 bool shutting_down); 72 bool shutting_down);
74 73
@@ -191,13 +190,14 @@ static int bearer_name_validate(const char *name,
191/** 190/**
192 * tipc_bearer_find - locates bearer object with matching bearer name 191 * tipc_bearer_find - locates bearer object with matching bearer name
193 */ 192 */
194struct tipc_bearer *tipc_bearer_find(const char *name) 193struct tipc_bearer *tipc_bearer_find(struct net *net, const char *name)
195{ 194{
195 struct tipc_net *tn = net_generic(net, tipc_net_id);
196 struct tipc_bearer *b_ptr; 196 struct tipc_bearer *b_ptr;
197 u32 i; 197 u32 i;
198 198
199 for (i = 0; i < MAX_BEARERS; i++) { 199 for (i = 0; i < MAX_BEARERS; i++) {
200 b_ptr = rtnl_dereference(bearer_list[i]); 200 b_ptr = rtnl_dereference(tn->bearer_list[i]);
201 if (b_ptr && (!strcmp(b_ptr->name, name))) 201 if (b_ptr && (!strcmp(b_ptr->name, name)))
202 return b_ptr; 202 return b_ptr;
203 } 203 }
@@ -207,8 +207,9 @@ struct tipc_bearer *tipc_bearer_find(const char *name)
207/** 207/**
208 * tipc_bearer_get_names - record names of bearers in buffer 208 * tipc_bearer_get_names - record names of bearers in buffer
209 */ 209 */
210struct sk_buff *tipc_bearer_get_names(void) 210struct sk_buff *tipc_bearer_get_names(struct net *net)
211{ 211{
212 struct tipc_net *tn = net_generic(net, tipc_net_id);
212 struct sk_buff *buf; 213 struct sk_buff *buf;
213 struct tipc_bearer *b; 214 struct tipc_bearer *b;
214 int i, j; 215 int i, j;
@@ -219,7 +220,7 @@ struct sk_buff *tipc_bearer_get_names(void)
219 220
220 for (i = 0; media_info_array[i] != NULL; i++) { 221 for (i = 0; media_info_array[i] != NULL; i++) {
221 for (j = 0; j < MAX_BEARERS; j++) { 222 for (j = 0; j < MAX_BEARERS; j++) {
222 b = rtnl_dereference(bearer_list[j]); 223 b = rtnl_dereference(tn->bearer_list[j]);
223 if (!b) 224 if (!b)
224 continue; 225 continue;
225 if (b->media == media_info_array[i]) { 226 if (b->media == media_info_array[i]) {
@@ -232,27 +233,29 @@ struct sk_buff *tipc_bearer_get_names(void)
232 return buf; 233 return buf;
233} 234}
234 235
235void tipc_bearer_add_dest(u32 bearer_id, u32 dest) 236void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest)
236{ 237{
238 struct tipc_net *tn = net_generic(net, tipc_net_id);
237 struct tipc_bearer *b_ptr; 239 struct tipc_bearer *b_ptr;
238 240
239 rcu_read_lock(); 241 rcu_read_lock();
240 b_ptr = rcu_dereference_rtnl(bearer_list[bearer_id]); 242 b_ptr = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
241 if (b_ptr) { 243 if (b_ptr) {
242 tipc_bcbearer_sort(&b_ptr->nodes, dest, true); 244 tipc_bcbearer_sort(net, &b_ptr->nodes, dest, true);
243 tipc_disc_add_dest(b_ptr->link_req); 245 tipc_disc_add_dest(b_ptr->link_req);
244 } 246 }
245 rcu_read_unlock(); 247 rcu_read_unlock();
246} 248}
247 249
248void tipc_bearer_remove_dest(u32 bearer_id, u32 dest) 250void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest)
249{ 251{
252 struct tipc_net *tn = net_generic(net, tipc_net_id);
250 struct tipc_bearer *b_ptr; 253 struct tipc_bearer *b_ptr;
251 254
252 rcu_read_lock(); 255 rcu_read_lock();
253 b_ptr = rcu_dereference_rtnl(bearer_list[bearer_id]); 256 b_ptr = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
254 if (b_ptr) { 257 if (b_ptr) {
255 tipc_bcbearer_sort(&b_ptr->nodes, dest, false); 258 tipc_bcbearer_sort(net, &b_ptr->nodes, dest, false);
256 tipc_disc_remove_dest(b_ptr->link_req); 259 tipc_disc_remove_dest(b_ptr->link_req);
257 } 260 }
258 rcu_read_unlock(); 261 rcu_read_unlock();
@@ -264,6 +267,7 @@ void tipc_bearer_remove_dest(u32 bearer_id, u32 dest)
264int tipc_enable_bearer(struct net *net, const char *name, u32 disc_domain, 267int tipc_enable_bearer(struct net *net, const char *name, u32 disc_domain,
265 u32 priority) 268 u32 priority)
266{ 269{
270 struct tipc_net *tn = net_generic(net, tipc_net_id);
267 struct tipc_bearer *b_ptr; 271 struct tipc_bearer *b_ptr;
268 struct tipc_media *m_ptr; 272 struct tipc_media *m_ptr;
269 struct tipc_bearer_names b_names; 273 struct tipc_bearer_names b_names;
@@ -315,7 +319,7 @@ restart:
315 bearer_id = MAX_BEARERS; 319 bearer_id = MAX_BEARERS;
316 with_this_prio = 1; 320 with_this_prio = 1;
317 for (i = MAX_BEARERS; i-- != 0; ) { 321 for (i = MAX_BEARERS; i-- != 0; ) {
318 b_ptr = rtnl_dereference(bearer_list[i]); 322 b_ptr = rtnl_dereference(tn->bearer_list[i]);
319 if (!b_ptr) { 323 if (!b_ptr) {
320 bearer_id = i; 324 bearer_id = i;
321 continue; 325 continue;
@@ -349,7 +353,7 @@ restart:
349 353
350 strcpy(b_ptr->name, name); 354 strcpy(b_ptr->name, name);
351 b_ptr->media = m_ptr; 355 b_ptr->media = m_ptr;
352 res = m_ptr->enable_media(b_ptr); 356 res = m_ptr->enable_media(net, b_ptr);
353 if (res) { 357 if (res) {
354 pr_warn("Bearer <%s> rejected, enable failure (%d)\n", 358 pr_warn("Bearer <%s> rejected, enable failure (%d)\n",
355 name, -res); 359 name, -res);
@@ -371,7 +375,7 @@ restart:
371 return -EINVAL; 375 return -EINVAL;
372 } 376 }
373 377
374 rcu_assign_pointer(bearer_list[bearer_id], b_ptr); 378 rcu_assign_pointer(tn->bearer_list[bearer_id], b_ptr);
375 379
376 pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", 380 pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
377 name, 381 name,
@@ -398,6 +402,7 @@ static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b_ptr)
398static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr, 402static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr,
399 bool shutting_down) 403 bool shutting_down)
400{ 404{
405 struct tipc_net *tn = net_generic(net, tipc_net_id);
401 u32 i; 406 u32 i;
402 407
403 pr_info("Disabling bearer <%s>\n", b_ptr->name); 408 pr_info("Disabling bearer <%s>\n", b_ptr->name);
@@ -408,8 +413,8 @@ static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr,
408 tipc_disc_delete(b_ptr->link_req); 413 tipc_disc_delete(b_ptr->link_req);
409 414
410 for (i = 0; i < MAX_BEARERS; i++) { 415 for (i = 0; i < MAX_BEARERS; i++) {
411 if (b_ptr == rtnl_dereference(bearer_list[i])) { 416 if (b_ptr == rtnl_dereference(tn->bearer_list[i])) {
412 RCU_INIT_POINTER(bearer_list[i], NULL); 417 RCU_INIT_POINTER(tn->bearer_list[i], NULL);
413 break; 418 break;
414 } 419 }
415 } 420 }
@@ -421,7 +426,7 @@ int tipc_disable_bearer(struct net *net, const char *name)
421 struct tipc_bearer *b_ptr; 426 struct tipc_bearer *b_ptr;
422 int res; 427 int res;
423 428
424 b_ptr = tipc_bearer_find(name); 429 b_ptr = tipc_bearer_find(net, name);
425 if (b_ptr == NULL) { 430 if (b_ptr == NULL) {
426 pr_warn("Attempt to disable unknown bearer <%s>\n", name); 431 pr_warn("Attempt to disable unknown bearer <%s>\n", name);
427 res = -EINVAL; 432 res = -EINVAL;
@@ -432,13 +437,13 @@ int tipc_disable_bearer(struct net *net, const char *name)
432 return res; 437 return res;
433} 438}
434 439
435int tipc_enable_l2_media(struct tipc_bearer *b) 440int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b)
436{ 441{
437 struct net_device *dev; 442 struct net_device *dev;
438 char *driver_name = strchr((const char *)b->name, ':') + 1; 443 char *driver_name = strchr((const char *)b->name, ':') + 1;
439 444
440 /* Find device with specified name */ 445 /* Find device with specified name */
441 dev = dev_get_by_name(&init_net, driver_name); 446 dev = dev_get_by_name(net, driver_name);
442 if (!dev) 447 if (!dev)
443 return -ENODEV; 448 return -ENODEV;
444 449
@@ -514,13 +519,14 @@ int tipc_l2_send_msg(struct sk_buff *buf, struct tipc_bearer *b,
514 * The media send routine must not alter the buffer being passed in 519 * The media send routine must not alter the buffer being passed in
515 * as it may be needed for later retransmission! 520 * as it may be needed for later retransmission!
516 */ 521 */
517void tipc_bearer_send(u32 bearer_id, struct sk_buff *buf, 522void tipc_bearer_send(struct net *net, u32 bearer_id, struct sk_buff *buf,
518 struct tipc_media_addr *dest) 523 struct tipc_media_addr *dest)
519{ 524{
525 struct tipc_net *tn = net_generic(net, tipc_net_id);
520 struct tipc_bearer *b_ptr; 526 struct tipc_bearer *b_ptr;
521 527
522 rcu_read_lock(); 528 rcu_read_lock();
523 b_ptr = rcu_dereference_rtnl(bearer_list[bearer_id]); 529 b_ptr = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
524 if (likely(b_ptr)) 530 if (likely(b_ptr))
525 b_ptr->media->send_msg(buf, b_ptr, dest); 531 b_ptr->media->send_msg(buf, b_ptr, dest);
526 rcu_read_unlock(); 532 rcu_read_unlock();
@@ -630,14 +636,15 @@ void tipc_bearer_cleanup(void)
630 636
631void tipc_bearer_stop(struct net *net) 637void tipc_bearer_stop(struct net *net)
632{ 638{
639 struct tipc_net *tn = net_generic(net, tipc_net_id);
633 struct tipc_bearer *b_ptr; 640 struct tipc_bearer *b_ptr;
634 u32 i; 641 u32 i;
635 642
636 for (i = 0; i < MAX_BEARERS; i++) { 643 for (i = 0; i < MAX_BEARERS; i++) {
637 b_ptr = rtnl_dereference(bearer_list[i]); 644 b_ptr = rtnl_dereference(tn->bearer_list[i]);
638 if (b_ptr) { 645 if (b_ptr) {
639 bearer_disable(net, b_ptr, true); 646 bearer_disable(net, b_ptr, true);
640 bearer_list[i] = NULL; 647 tn->bearer_list[i] = NULL;
641 } 648 }
642 } 649 }
643} 650}
@@ -694,6 +701,8 @@ int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb)
694 int i = cb->args[0]; 701 int i = cb->args[0];
695 struct tipc_bearer *bearer; 702 struct tipc_bearer *bearer;
696 struct tipc_nl_msg msg; 703 struct tipc_nl_msg msg;
704 struct net *net = sock_net(skb->sk);
705 struct tipc_net *tn = net_generic(net, tipc_net_id);
697 706
698 if (i == MAX_BEARERS) 707 if (i == MAX_BEARERS)
699 return 0; 708 return 0;
@@ -704,7 +713,7 @@ int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb)
704 713
705 rtnl_lock(); 714 rtnl_lock();
706 for (i = 0; i < MAX_BEARERS; i++) { 715 for (i = 0; i < MAX_BEARERS; i++) {
707 bearer = rtnl_dereference(bearer_list[i]); 716 bearer = rtnl_dereference(tn->bearer_list[i]);
708 if (!bearer) 717 if (!bearer)
709 continue; 718 continue;
710 719
@@ -726,6 +735,7 @@ int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info)
726 struct tipc_bearer *bearer; 735 struct tipc_bearer *bearer;
727 struct tipc_nl_msg msg; 736 struct tipc_nl_msg msg;
728 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; 737 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
738 struct net *net = genl_info_net(info);
729 739
730 if (!info->attrs[TIPC_NLA_BEARER]) 740 if (!info->attrs[TIPC_NLA_BEARER])
731 return -EINVAL; 741 return -EINVAL;
@@ -749,7 +759,7 @@ int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info)
749 msg.seq = info->snd_seq; 759 msg.seq = info->snd_seq;
750 760
751 rtnl_lock(); 761 rtnl_lock();
752 bearer = tipc_bearer_find(name); 762 bearer = tipc_bearer_find(net, name);
753 if (!bearer) { 763 if (!bearer) {
754 err = -EINVAL; 764 err = -EINVAL;
755 goto err_out; 765 goto err_out;
@@ -791,7 +801,7 @@ int tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
791 name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); 801 name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
792 802
793 rtnl_lock(); 803 rtnl_lock();
794 bearer = tipc_bearer_find(name); 804 bearer = tipc_bearer_find(net, name);
795 if (!bearer) { 805 if (!bearer) {
796 rtnl_unlock(); 806 rtnl_unlock();
797 return -EINVAL; 807 return -EINVAL;
@@ -861,6 +871,7 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
861 char *name; 871 char *name;
862 struct tipc_bearer *b; 872 struct tipc_bearer *b;
863 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; 873 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
874 struct net *net = genl_info_net(info);
864 875
865 if (!info->attrs[TIPC_NLA_BEARER]) 876 if (!info->attrs[TIPC_NLA_BEARER])
866 return -EINVAL; 877 return -EINVAL;
@@ -876,7 +887,7 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
876 name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); 887 name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
877 888
878 rtnl_lock(); 889 rtnl_lock();
879 b = tipc_bearer_find(name); 890 b = tipc_bearer_find(net, name);
880 if (!b) { 891 if (!b) {
881 rtnl_unlock(); 892 rtnl_unlock();
882 return -EINVAL; 893 return -EINVAL;