aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/bearer.c
diff options
context:
space:
mode:
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;