diff options
Diffstat (limited to 'net/tipc/bearer.c')
-rw-r--r-- | net/tipc/bearer.c | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 411719feb803..85209eadfae6 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -46,6 +46,8 @@ static u32 media_count; | |||
46 | 46 | ||
47 | struct tipc_bearer tipc_bearers[MAX_BEARERS]; | 47 | struct tipc_bearer tipc_bearers[MAX_BEARERS]; |
48 | 48 | ||
49 | static void bearer_disable(struct tipc_bearer *b_ptr); | ||
50 | |||
49 | /** | 51 | /** |
50 | * media_name_valid - validate media name | 52 | * media_name_valid - validate media name |
51 | * | 53 | * |
@@ -342,15 +344,15 @@ struct sk_buff *tipc_bearer_get_names(void) | |||
342 | void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest) | 344 | void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest) |
343 | { | 345 | { |
344 | tipc_nmap_add(&b_ptr->nodes, dest); | 346 | tipc_nmap_add(&b_ptr->nodes, dest); |
345 | tipc_disc_update_link_req(b_ptr->link_req); | ||
346 | tipc_bcbearer_sort(); | 347 | tipc_bcbearer_sort(); |
348 | tipc_disc_add_dest(b_ptr->link_req); | ||
347 | } | 349 | } |
348 | 350 | ||
349 | void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest) | 351 | void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest) |
350 | { | 352 | { |
351 | tipc_nmap_remove(&b_ptr->nodes, dest); | 353 | tipc_nmap_remove(&b_ptr->nodes, dest); |
352 | tipc_disc_update_link_req(b_ptr->link_req); | ||
353 | tipc_bcbearer_sort(); | 354 | tipc_bcbearer_sort(); |
355 | tipc_disc_remove_dest(b_ptr->link_req); | ||
354 | } | 356 | } |
355 | 357 | ||
356 | /* | 358 | /* |
@@ -493,8 +495,15 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) | |||
493 | warn("Bearer <%s> rejected, illegal name\n", name); | 495 | warn("Bearer <%s> rejected, illegal name\n", name); |
494 | return -EINVAL; | 496 | return -EINVAL; |
495 | } | 497 | } |
496 | if (!tipc_addr_domain_valid(disc_domain) || | 498 | if (tipc_addr_domain_valid(disc_domain) && |
497 | !tipc_in_scope(disc_domain, tipc_own_addr)) { | 499 | (disc_domain != tipc_own_addr)) { |
500 | if (tipc_in_scope(disc_domain, tipc_own_addr)) { | ||
501 | disc_domain = tipc_own_addr & TIPC_CLUSTER_MASK; | ||
502 | res = 0; /* accept any node in own cluster */ | ||
503 | } else if (in_own_cluster(disc_domain)) | ||
504 | res = 0; /* accept specified node in own cluster */ | ||
505 | } | ||
506 | if (res) { | ||
498 | warn("Bearer <%s> rejected, illegal discovery domain\n", name); | 507 | warn("Bearer <%s> rejected, illegal discovery domain\n", name); |
499 | return -EINVAL; | 508 | return -EINVAL; |
500 | } | 509 | } |
@@ -511,7 +520,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) | |||
511 | if (!m_ptr) { | 520 | if (!m_ptr) { |
512 | warn("Bearer <%s> rejected, media <%s> not registered\n", name, | 521 | warn("Bearer <%s> rejected, media <%s> not registered\n", name, |
513 | b_name.media_name); | 522 | b_name.media_name); |
514 | goto failed; | 523 | goto exit; |
515 | } | 524 | } |
516 | 525 | ||
517 | if (priority == TIPC_MEDIA_LINK_PRI) | 526 | if (priority == TIPC_MEDIA_LINK_PRI) |
@@ -527,14 +536,14 @@ restart: | |||
527 | } | 536 | } |
528 | if (!strcmp(name, tipc_bearers[i].name)) { | 537 | if (!strcmp(name, tipc_bearers[i].name)) { |
529 | warn("Bearer <%s> rejected, already enabled\n", name); | 538 | warn("Bearer <%s> rejected, already enabled\n", name); |
530 | goto failed; | 539 | goto exit; |
531 | } | 540 | } |
532 | if ((tipc_bearers[i].priority == priority) && | 541 | if ((tipc_bearers[i].priority == priority) && |
533 | (++with_this_prio > 2)) { | 542 | (++with_this_prio > 2)) { |
534 | if (priority-- == 0) { | 543 | if (priority-- == 0) { |
535 | warn("Bearer <%s> rejected, duplicate priority\n", | 544 | warn("Bearer <%s> rejected, duplicate priority\n", |
536 | name); | 545 | name); |
537 | goto failed; | 546 | goto exit; |
538 | } | 547 | } |
539 | warn("Bearer <%s> priority adjustment required %u->%u\n", | 548 | warn("Bearer <%s> priority adjustment required %u->%u\n", |
540 | name, priority + 1, priority); | 549 | name, priority + 1, priority); |
@@ -544,7 +553,7 @@ restart: | |||
544 | if (bearer_id >= MAX_BEARERS) { | 553 | if (bearer_id >= MAX_BEARERS) { |
545 | warn("Bearer <%s> rejected, bearer limit reached (%u)\n", | 554 | warn("Bearer <%s> rejected, bearer limit reached (%u)\n", |
546 | name, MAX_BEARERS); | 555 | name, MAX_BEARERS); |
547 | goto failed; | 556 | goto exit; |
548 | } | 557 | } |
549 | 558 | ||
550 | b_ptr = &tipc_bearers[bearer_id]; | 559 | b_ptr = &tipc_bearers[bearer_id]; |
@@ -552,7 +561,7 @@ restart: | |||
552 | res = m_ptr->enable_bearer(b_ptr); | 561 | res = m_ptr->enable_bearer(b_ptr); |
553 | if (res) { | 562 | if (res) { |
554 | warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res); | 563 | warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res); |
555 | goto failed; | 564 | goto exit; |
556 | } | 565 | } |
557 | 566 | ||
558 | b_ptr->identity = bearer_id; | 567 | b_ptr->identity = bearer_id; |
@@ -562,14 +571,18 @@ restart: | |||
562 | b_ptr->priority = priority; | 571 | b_ptr->priority = priority; |
563 | INIT_LIST_HEAD(&b_ptr->cong_links); | 572 | INIT_LIST_HEAD(&b_ptr->cong_links); |
564 | INIT_LIST_HEAD(&b_ptr->links); | 573 | INIT_LIST_HEAD(&b_ptr->links); |
565 | b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr, | ||
566 | disc_domain); | ||
567 | spin_lock_init(&b_ptr->lock); | 574 | spin_lock_init(&b_ptr->lock); |
568 | write_unlock_bh(&tipc_net_lock); | 575 | |
576 | res = tipc_disc_create(b_ptr, &m_ptr->bcast_addr, disc_domain); | ||
577 | if (res) { | ||
578 | bearer_disable(b_ptr); | ||
579 | warn("Bearer <%s> rejected, discovery object creation failed\n", | ||
580 | name); | ||
581 | goto exit; | ||
582 | } | ||
569 | info("Enabled bearer <%s>, discovery domain %s, priority %u\n", | 583 | info("Enabled bearer <%s>, discovery domain %s, priority %u\n", |
570 | name, tipc_addr_string_fill(addr_string, disc_domain), priority); | 584 | name, tipc_addr_string_fill(addr_string, disc_domain), priority); |
571 | return 0; | 585 | exit: |
572 | failed: | ||
573 | write_unlock_bh(&tipc_net_lock); | 586 | write_unlock_bh(&tipc_net_lock); |
574 | return res; | 587 | return res; |
575 | } | 588 | } |
@@ -620,14 +633,14 @@ static void bearer_disable(struct tipc_bearer *b_ptr) | |||
620 | struct link *temp_l_ptr; | 633 | struct link *temp_l_ptr; |
621 | 634 | ||
622 | info("Disabling bearer <%s>\n", b_ptr->name); | 635 | info("Disabling bearer <%s>\n", b_ptr->name); |
623 | tipc_disc_stop_link_req(b_ptr->link_req); | ||
624 | spin_lock_bh(&b_ptr->lock); | 636 | spin_lock_bh(&b_ptr->lock); |
625 | b_ptr->link_req = NULL; | ||
626 | b_ptr->blocked = 1; | 637 | b_ptr->blocked = 1; |
627 | b_ptr->media->disable_bearer(b_ptr); | 638 | b_ptr->media->disable_bearer(b_ptr); |
628 | list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { | 639 | list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { |
629 | tipc_link_delete(l_ptr); | 640 | tipc_link_delete(l_ptr); |
630 | } | 641 | } |
642 | if (b_ptr->link_req) | ||
643 | tipc_disc_delete(b_ptr->link_req); | ||
631 | spin_unlock_bh(&b_ptr->lock); | 644 | spin_unlock_bh(&b_ptr->lock); |
632 | memset(b_ptr, 0, sizeof(struct tipc_bearer)); | 645 | memset(b_ptr, 0, sizeof(struct tipc_bearer)); |
633 | } | 646 | } |