aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
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
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')
-rw-r--r--net/tipc/bearer.c30
-rw-r--r--net/tipc/discover.c45
-rw-r--r--net/tipc/discover.h8
3 files changed, 42 insertions, 41 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}
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index d2163bd99e59..6acf32a9eef8 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -216,22 +216,6 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr)
216} 216}
217 217
218/** 218/**
219 * tipc_disc_stop_link_req - stop sending periodic link setup requests
220 * @req: ptr to link request structure
221 */
222
223void tipc_disc_stop_link_req(struct link_req *req)
224{
225 if (!req)
226 return;
227
228 k_cancel_timer(&req->timer);
229 k_term_timer(&req->timer);
230 buf_discard(req->buf);
231 kfree(req);
232}
233
234/**
235 * tipc_disc_update_link_req - update frequency of periodic link setup requests 219 * tipc_disc_update_link_req - update frequency of periodic link setup requests
236 * @req: ptr to link request structure 220 * @req: ptr to link request structure
237 */ 221 */
@@ -286,28 +270,27 @@ static void disc_timeout(struct link_req *req)
286} 270}
287 271
288/** 272/**
289 * tipc_disc_init_link_req - start sending periodic link setup requests 273 * tipc_disc_create - create object to send periodic link setup requests
290 * @b_ptr: ptr to bearer issuing requests 274 * @b_ptr: ptr to bearer issuing requests
291 * @dest: destination address for request messages 275 * @dest: destination address for request messages
292 * @dest_domain: network domain to which links can be established 276 * @dest_domain: network domain to which links can be established
293 * 277 *
294 * Returns pointer to link request structure, or NULL if unable to create. 278 * Returns 0 if successful, otherwise -errno.
295 */ 279 */
296 280
297struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr, 281int tipc_disc_create(struct tipc_bearer *b_ptr,
298 const struct tipc_media_addr *dest, 282 struct tipc_media_addr *dest, u32 dest_domain)
299 u32 dest_domain)
300{ 283{
301 struct link_req *req; 284 struct link_req *req;
302 285
303 req = kmalloc(sizeof(*req), GFP_ATOMIC); 286 req = kmalloc(sizeof(*req), GFP_ATOMIC);
304 if (!req) 287 if (!req)
305 return NULL; 288 return -ENOMEM;
306 289
307 req->buf = tipc_disc_init_msg(DSC_REQ_MSG, dest_domain, b_ptr); 290 req->buf = tipc_disc_init_msg(DSC_REQ_MSG, dest_domain, b_ptr);
308 if (!req->buf) { 291 if (!req->buf) {
309 kfree(req); 292 kfree(req);
310 return NULL; 293 return -ENOMSG;
311 } 294 }
312 295
313 memcpy(&req->dest, dest, sizeof(*dest)); 296 memcpy(&req->dest, dest, sizeof(*dest));
@@ -316,6 +299,20 @@ struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr,
316 req->timer_intv = TIPC_LINK_REQ_INIT; 299 req->timer_intv = TIPC_LINK_REQ_INIT;
317 k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req); 300 k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req);
318 k_start_timer(&req->timer, req->timer_intv); 301 k_start_timer(&req->timer, req->timer_intv);
319 return req; 302 b_ptr->link_req = req;
303 return 0;
304}
305
306/**
307 * tipc_disc_delete - destroy object sending periodic link setup requests
308 * @req: ptr to link request structure
309 */
310
311void tipc_disc_delete(struct link_req *req)
312{
313 k_cancel_timer(&req->timer);
314 k_term_timer(&req->timer);
315 buf_discard(req->buf);
316 kfree(req);
320} 317}
321 318
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index e48a167e47b2..d6e44e3dcdbc 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -39,12 +39,10 @@
39 39
40struct link_req; 40struct link_req;
41 41
42struct link_req *tipc_disc_init_link_req(struct tipc_bearer *b_ptr, 42int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest,
43 const struct tipc_media_addr *dest, 43 u32 dest_domain);
44 u32 dest_domain); 44void tipc_disc_delete(struct link_req *req);
45void tipc_disc_update_link_req(struct link_req *req); 45void tipc_disc_update_link_req(struct link_req *req);
46void tipc_disc_stop_link_req(struct link_req *req);
47
48void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr); 46void tipc_disc_recv_msg(struct sk_buff *buf, struct tipc_bearer *b_ptr);
49 47
50#endif 48#endif