aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/bearer.c
diff options
context:
space:
mode:
authorAllan Stephens <Allan.Stephens@windriver.com>2011-04-21 14:58:26 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2011-05-10 16:03:59 -0400
commit3a777ff8b14456e15991c9fcc225943453dc3a75 (patch)
tree50f2b2ca5c9a2a4a1df107da4db00611ae938f32 /net/tipc/bearer.c
parentdc63d91eb1cf74233c68b0058dcd477f5d019d02 (diff)
tipc: Enhance handling of discovery object creation failures
Modifies bearer creation and deletion code to improve handling of scenarios when a neighbor discovery object cannot be created. The creation routine now aborts the creation of a bearer if its discovery object cannot be created, and deletes the newly created bearer, rather than failing quietly and leaving an unusable bearer hanging around. Since the exit via the goto label really isn't a definitive failure in all cases, relabel it appropriately. Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Diffstat (limited to 'net/tipc/bearer.c')
-rw-r--r--net/tipc/bearer.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index f7c29af4ab81..5fcd1c1214fd 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -46,6 +46,8 @@ static u32 media_count;
46 46
47struct tipc_bearer tipc_bearers[MAX_BEARERS]; 47struct tipc_bearer tipc_bearers[MAX_BEARERS];
48 48
49static 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 *
@@ -518,7 +520,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
518 if (!m_ptr) { 520 if (!m_ptr) {
519 warn("Bearer <%s> rejected, media <%s> not registered\n", name, 521 warn("Bearer <%s> rejected, media <%s> not registered\n", name,
520 b_name.media_name); 522 b_name.media_name);
521 goto failed; 523 goto exit;
522 } 524 }
523 525
524 if (priority == TIPC_MEDIA_LINK_PRI) 526 if (priority == TIPC_MEDIA_LINK_PRI)
@@ -534,14 +536,14 @@ restart:
534 } 536 }
535 if (!strcmp(name, tipc_bearers[i].name)) { 537 if (!strcmp(name, tipc_bearers[i].name)) {
536 warn("Bearer <%s> rejected, already enabled\n", name); 538 warn("Bearer <%s> rejected, already enabled\n", name);
537 goto failed; 539 goto exit;
538 } 540 }
539 if ((tipc_bearers[i].priority == priority) && 541 if ((tipc_bearers[i].priority == priority) &&
540 (++with_this_prio > 2)) { 542 (++with_this_prio > 2)) {
541 if (priority-- == 0) { 543 if (priority-- == 0) {
542 warn("Bearer <%s> rejected, duplicate priority\n", 544 warn("Bearer <%s> rejected, duplicate priority\n",
543 name); 545 name);
544 goto failed; 546 goto exit;
545 } 547 }
546 warn("Bearer <%s> priority adjustment required %u->%u\n", 548 warn("Bearer <%s> priority adjustment required %u->%u\n",
547 name, priority + 1, priority); 549 name, priority + 1, priority);
@@ -551,7 +553,7 @@ restart:
551 if (bearer_id >= MAX_BEARERS) { 553 if (bearer_id >= MAX_BEARERS) {
552 warn("Bearer <%s> rejected, bearer limit reached (%u)\n", 554 warn("Bearer <%s> rejected, bearer limit reached (%u)\n",
553 name, MAX_BEARERS); 555 name, MAX_BEARERS);
554 goto failed; 556 goto exit;
555 } 557 }
556 558
557 b_ptr = &tipc_bearers[bearer_id]; 559 b_ptr = &tipc_bearers[bearer_id];
@@ -559,7 +561,7 @@ restart:
559 res = m_ptr->enable_bearer(b_ptr); 561 res = m_ptr->enable_bearer(b_ptr);
560 if (res) { 562 if (res) {
561 warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res); 563 warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res);
562 goto failed; 564 goto exit;
563 } 565 }
564 566
565 b_ptr->identity = bearer_id; 567 b_ptr->identity = bearer_id;
@@ -569,14 +571,18 @@ restart:
569 b_ptr->priority = priority; 571 b_ptr->priority = priority;
570 INIT_LIST_HEAD(&b_ptr->cong_links); 572 INIT_LIST_HEAD(&b_ptr->cong_links);
571 INIT_LIST_HEAD(&b_ptr->links); 573 INIT_LIST_HEAD(&b_ptr->links);
572 b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr,
573 disc_domain);
574 spin_lock_init(&b_ptr->lock); 574 spin_lock_init(&b_ptr->lock);
575 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 }
576 info("Enabled bearer <%s>, discovery domain %s, priority %u\n", 583 info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
577 name, tipc_addr_string_fill(addr_string, disc_domain), priority); 584 name, tipc_addr_string_fill(addr_string, disc_domain), priority);
578 return 0; 585exit:
579failed:
580 write_unlock_bh(&tipc_net_lock); 586 write_unlock_bh(&tipc_net_lock);
581 return res; 587 return res;
582} 588}
@@ -627,14 +633,14 @@ static void bearer_disable(struct tipc_bearer *b_ptr)
627 struct link *temp_l_ptr; 633 struct link *temp_l_ptr;
628 634
629 info("Disabling bearer <%s>\n", b_ptr->name); 635 info("Disabling bearer <%s>\n", b_ptr->name);
630 tipc_disc_stop_link_req(b_ptr->link_req);
631 spin_lock_bh(&b_ptr->lock); 636 spin_lock_bh(&b_ptr->lock);
632 b_ptr->link_req = NULL;
633 b_ptr->blocked = 1; 637 b_ptr->blocked = 1;
634 b_ptr->media->disable_bearer(b_ptr); 638 b_ptr->media->disable_bearer(b_ptr);
635 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) {
636 tipc_link_delete(l_ptr); 640 tipc_link_delete(l_ptr);
637 } 641 }
642 if (b_ptr->link_req)
643 tipc_disc_delete(b_ptr->link_req);
638 spin_unlock_bh(&b_ptr->lock); 644 spin_unlock_bh(&b_ptr->lock);
639 memset(b_ptr, 0, sizeof(struct tipc_bearer)); 645 memset(b_ptr, 0, sizeof(struct tipc_bearer));
640} 646}