diff options
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r-- | net/tipc/node.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c index 6a0680ba98a9..65c2c80cffe7 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -265,7 +265,7 @@ static void tipc_node_timeout(unsigned long data) | |||
265 | tipc_node_calculate_timer(n, l); | 265 | tipc_node_calculate_timer(n, l); |
266 | rc = tipc_link_timeout(l, &xmitq); | 266 | rc = tipc_link_timeout(l, &xmitq); |
267 | if (rc & TIPC_LINK_DOWN_EVT) | 267 | if (rc & TIPC_LINK_DOWN_EVT) |
268 | tipc_link_reset(l); | 268 | tipc_node_link_down(n, bearer_id); |
269 | } | 269 | } |
270 | tipc_node_unlock(n); | 270 | tipc_node_unlock(n); |
271 | maddr = &n->links[bearer_id].maddr; | 271 | maddr = &n->links[bearer_id].maddr; |
@@ -338,10 +338,15 @@ void tipc_node_link_down(struct tipc_node *n, int bearer_id) | |||
338 | struct tipc_link *l, *_l; | 338 | struct tipc_link *l, *_l; |
339 | 339 | ||
340 | l = n->links[bearer_id].link; | 340 | l = n->links[bearer_id].link; |
341 | if (!l || !tipc_link_is_up(l)) | ||
342 | return; | ||
343 | |||
341 | n->working_links--; | 344 | n->working_links--; |
342 | n->action_flags |= TIPC_NOTIFY_LINK_DOWN; | 345 | n->action_flags |= TIPC_NOTIFY_LINK_DOWN; |
343 | n->link_id = l->peer_bearer_id << 16 | l->bearer_id; | 346 | n->link_id = l->peer_bearer_id << 16 | l->bearer_id; |
344 | 347 | ||
348 | tipc_bearer_remove_dest(n->net, l->bearer_id, n->addr); | ||
349 | |||
345 | pr_debug("Lost link <%s> on network plane %c\n", | 350 | pr_debug("Lost link <%s> on network plane %c\n", |
346 | l->name, l->net_plane); | 351 | l->name, l->net_plane); |
347 | 352 | ||
@@ -352,6 +357,8 @@ void tipc_node_link_down(struct tipc_node *n, int bearer_id) | |||
352 | _l = n->links[i].link; | 357 | _l = n->links[i].link; |
353 | if (!_l || !tipc_link_is_up(_l)) | 358 | if (!_l || !tipc_link_is_up(_l)) |
354 | continue; | 359 | continue; |
360 | if (_l == l) | ||
361 | continue; | ||
355 | if (_l->priority < highest) | 362 | if (_l->priority < highest) |
356 | continue; | 363 | continue; |
357 | if (_l->priority > highest) { | 364 | if (_l->priority > highest) { |
@@ -362,9 +369,13 @@ void tipc_node_link_down(struct tipc_node *n, int bearer_id) | |||
362 | } | 369 | } |
363 | *slot1 = i; | 370 | *slot1 = i; |
364 | } | 371 | } |
372 | |||
365 | if (tipc_node_is_up(n)) | 373 | if (tipc_node_is_up(n)) |
366 | tipc_link_failover_send_queue(l); | 374 | tipc_link_failover_send_queue(l); |
367 | else | 375 | |
376 | tipc_link_reset(l); | ||
377 | |||
378 | if (!tipc_node_is_up(n)) | ||
368 | node_lost_contact(n); | 379 | node_lost_contact(n); |
369 | } | 380 | } |
370 | 381 | ||
@@ -403,7 +414,7 @@ bool tipc_node_update_dest(struct tipc_node *n, struct tipc_bearer *b, | |||
403 | } | 414 | } |
404 | memcpy(&l->media_addr, maddr, sizeof(*maddr)); | 415 | memcpy(&l->media_addr, maddr, sizeof(*maddr)); |
405 | memcpy(curr, maddr, sizeof(*maddr)); | 416 | memcpy(curr, maddr, sizeof(*maddr)); |
406 | tipc_link_reset(l); | 417 | tipc_node_link_down(n, b->identity); |
407 | return true; | 418 | return true; |
408 | } | 419 | } |
409 | 420 | ||
@@ -418,7 +429,7 @@ void tipc_node_delete_links(struct net *net, int bearer_id) | |||
418 | tipc_node_lock(n); | 429 | tipc_node_lock(n); |
419 | l = n->links[bearer_id].link; | 430 | l = n->links[bearer_id].link; |
420 | if (l) { | 431 | if (l) { |
421 | tipc_link_reset(l); | 432 | tipc_node_link_down(n, bearer_id); |
422 | n->links[bearer_id].link = NULL; | 433 | n->links[bearer_id].link = NULL; |
423 | n->link_cnt--; | 434 | n->link_cnt--; |
424 | } | 435 | } |
@@ -439,8 +450,9 @@ static void tipc_node_reset_links(struct tipc_node *n) | |||
439 | tipc_addr_string_fill(addr_string, n->addr)); | 450 | tipc_addr_string_fill(addr_string, n->addr)); |
440 | 451 | ||
441 | for (i = 0; i < MAX_BEARERS; i++) { | 452 | for (i = 0; i < MAX_BEARERS; i++) { |
442 | if (n->links[i].link) | 453 | if (!n->links[i].link) |
443 | tipc_link_reset(n->links[i].link); | 454 | continue; |
455 | tipc_node_link_down(n, i); | ||
444 | } | 456 | } |
445 | tipc_node_unlock(n); | 457 | tipc_node_unlock(n); |
446 | } | 458 | } |
@@ -837,7 +849,7 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list, | |||
837 | if (likely(l)) | 849 | if (likely(l)) |
838 | rc = tipc_link_xmit(l, list, &xmitq); | 850 | rc = tipc_link_xmit(l, list, &xmitq); |
839 | if (unlikely(rc == -ENOBUFS)) | 851 | if (unlikely(rc == -ENOBUFS)) |
840 | tipc_link_reset(l); | 852 | tipc_node_link_down(n, bearer_id); |
841 | tipc_node_unlock(n); | 853 | tipc_node_unlock(n); |
842 | tipc_node_put(n); | 854 | tipc_node_put(n); |
843 | } | 855 | } |
@@ -902,7 +914,7 @@ static void tipc_node_tnl_init(struct tipc_node *n, int bearer_id, | |||
902 | 914 | ||
903 | if (msg_type(hdr) == FAILOVER_MSG) { | 915 | if (msg_type(hdr) == FAILOVER_MSG) { |
904 | if (tipc_link_is_up(pl)) { | 916 | if (tipc_link_is_up(pl)) { |
905 | tipc_link_reset(pl); | 917 | tipc_node_link_down(n, pb_id); |
906 | pl->exec_mode = TIPC_LINK_BLOCKED; | 918 | pl->exec_mode = TIPC_LINK_BLOCKED; |
907 | } | 919 | } |
908 | } | 920 | } |
@@ -978,7 +990,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) | |||
978 | if (unlikely(rc & TIPC_LINK_UP_EVT)) | 990 | if (unlikely(rc & TIPC_LINK_UP_EVT)) |
979 | tipc_node_link_up(n, bearer_id); | 991 | tipc_node_link_up(n, bearer_id); |
980 | if (unlikely(rc & TIPC_LINK_DOWN_EVT)) | 992 | if (unlikely(rc & TIPC_LINK_DOWN_EVT)) |
981 | tipc_link_reset(l); | 993 | tipc_node_link_down(n, bearer_id); |
982 | skb = NULL; | 994 | skb = NULL; |
983 | unlock: | 995 | unlock: |
984 | tipc_node_unlock(n); | 996 | tipc_node_unlock(n); |