diff options
Diffstat (limited to 'net/tipc/bearer.c')
-rw-r--r-- | net/tipc/bearer.c | 67 |
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 | ||
70 | struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1]; | ||
71 | |||
72 | static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr, | 71 | static 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 | */ |
194 | struct tipc_bearer *tipc_bearer_find(const char *name) | 193 | struct 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 | */ |
210 | struct sk_buff *tipc_bearer_get_names(void) | 210 | struct 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 | ||
235 | void tipc_bearer_add_dest(u32 bearer_id, u32 dest) | 236 | void 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 | ||
248 | void tipc_bearer_remove_dest(u32 bearer_id, u32 dest) | 250 | void 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) | |||
264 | int tipc_enable_bearer(struct net *net, const char *name, u32 disc_domain, | 267 | int 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) | |||
398 | static void bearer_disable(struct net *net, struct tipc_bearer *b_ptr, | 402 | static 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 | ||
435 | int tipc_enable_l2_media(struct tipc_bearer *b) | 440 | int 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 | */ |
517 | void tipc_bearer_send(u32 bearer_id, struct sk_buff *buf, | 522 | void 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 | ||
631 | void tipc_bearer_stop(struct net *net) | 637 | void 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; |