aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c230
1 files changed, 174 insertions, 56 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 784b24b6d102..c10e18a49b96 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2,7 +2,7 @@
2 * net/tipc/link.c: TIPC link code 2 * net/tipc/link.c: TIPC link code
3 * 3 *
4 * Copyright (c) 1996-2006, Ericsson AB 4 * Copyright (c) 1996-2006, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2006, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -419,7 +419,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
419 419
420 l_ptr = (struct link *)kmalloc(sizeof(*l_ptr), GFP_ATOMIC); 420 l_ptr = (struct link *)kmalloc(sizeof(*l_ptr), GFP_ATOMIC);
421 if (!l_ptr) { 421 if (!l_ptr) {
422 warn("Memory squeeze; Failed to create link\n"); 422 warn("Link creation failed, no memory\n");
423 return NULL; 423 return NULL;
424 } 424 }
425 memset(l_ptr, 0, sizeof(*l_ptr)); 425 memset(l_ptr, 0, sizeof(*l_ptr));
@@ -469,7 +469,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
469 469
470 if (!pb) { 470 if (!pb) {
471 kfree(l_ptr); 471 kfree(l_ptr);
472 warn("Memory squeeze; Failed to create link\n"); 472 warn("Link creation failed, no memory for print buffer\n");
473 return NULL; 473 return NULL;
474 } 474 }
475 tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE); 475 tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE);
@@ -574,7 +574,6 @@ void tipc_link_wakeup_ports(struct link *l_ptr, int all)
574 break; 574 break;
575 list_del_init(&p_ptr->wait_list); 575 list_del_init(&p_ptr->wait_list);
576 p_ptr->congested_link = NULL; 576 p_ptr->congested_link = NULL;
577 assert(p_ptr->wakeup);
578 spin_lock_bh(p_ptr->publ.lock); 577 spin_lock_bh(p_ptr->publ.lock);
579 p_ptr->publ.congested = 0; 578 p_ptr->publ.congested = 0;
580 p_ptr->wakeup(&p_ptr->publ); 579 p_ptr->wakeup(&p_ptr->publ);
@@ -691,6 +690,7 @@ void tipc_link_reset(struct link *l_ptr)
691 struct sk_buff *buf; 690 struct sk_buff *buf;
692 u32 prev_state = l_ptr->state; 691 u32 prev_state = l_ptr->state;
693 u32 checkpoint = l_ptr->next_in_no; 692 u32 checkpoint = l_ptr->next_in_no;
693 int was_active_link = tipc_link_is_active(l_ptr);
694 694
695 msg_set_session(l_ptr->pmsg, msg_session(l_ptr->pmsg) + 1); 695 msg_set_session(l_ptr->pmsg, msg_session(l_ptr->pmsg) + 1);
696 696
@@ -712,7 +712,7 @@ void tipc_link_reset(struct link *l_ptr)
712 tipc_printf(TIPC_CONS, "\nReset link <%s>\n", l_ptr->name); 712 tipc_printf(TIPC_CONS, "\nReset link <%s>\n", l_ptr->name);
713 dbg_link_dump(); 713 dbg_link_dump();
714#endif 714#endif
715 if (tipc_node_has_active_links(l_ptr->owner) && 715 if (was_active_link && tipc_node_has_active_links(l_ptr->owner) &&
716 l_ptr->owner->permit_changeover) { 716 l_ptr->owner->permit_changeover) {
717 l_ptr->reset_checkpoint = checkpoint; 717 l_ptr->reset_checkpoint = checkpoint;
718 l_ptr->exp_msg_count = START_CHANGEOVER; 718 l_ptr->exp_msg_count = START_CHANGEOVER;
@@ -755,7 +755,7 @@ void tipc_link_reset(struct link *l_ptr)
755 755
756static void link_activate(struct link *l_ptr) 756static void link_activate(struct link *l_ptr)
757{ 757{
758 l_ptr->next_in_no = 1; 758 l_ptr->next_in_no = l_ptr->stats.recv_info = 1;
759 tipc_node_link_up(l_ptr->owner, l_ptr); 759 tipc_node_link_up(l_ptr->owner, l_ptr);
760 tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr); 760 tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr);
761 link_send_event(tipc_cfg_link_event, l_ptr, 1); 761 link_send_event(tipc_cfg_link_event, l_ptr, 1);
@@ -820,6 +820,8 @@ static void link_state_event(struct link *l_ptr, unsigned event)
820 break; 820 break;
821 case RESET_MSG: 821 case RESET_MSG:
822 dbg_link("RES -> RR\n"); 822 dbg_link("RES -> RR\n");
823 info("Resetting link <%s>, requested by peer\n",
824 l_ptr->name);
823 tipc_link_reset(l_ptr); 825 tipc_link_reset(l_ptr);
824 l_ptr->state = RESET_RESET; 826 l_ptr->state = RESET_RESET;
825 l_ptr->fsm_msg_cnt = 0; 827 l_ptr->fsm_msg_cnt = 0;
@@ -844,6 +846,8 @@ static void link_state_event(struct link *l_ptr, unsigned event)
844 break; 846 break;
845 case RESET_MSG: 847 case RESET_MSG:
846 dbg_link("RES -> RR\n"); 848 dbg_link("RES -> RR\n");
849 info("Resetting link <%s>, requested by peer "
850 "while probing\n", l_ptr->name);
847 tipc_link_reset(l_ptr); 851 tipc_link_reset(l_ptr);
848 l_ptr->state = RESET_RESET; 852 l_ptr->state = RESET_RESET;
849 l_ptr->fsm_msg_cnt = 0; 853 l_ptr->fsm_msg_cnt = 0;
@@ -875,6 +879,8 @@ static void link_state_event(struct link *l_ptr, unsigned event)
875 } else { /* Link has failed */ 879 } else { /* Link has failed */
876 dbg_link("-> RU (%u probes unanswered)\n", 880 dbg_link("-> RU (%u probes unanswered)\n",
877 l_ptr->fsm_msg_cnt); 881 l_ptr->fsm_msg_cnt);
882 warn("Resetting link <%s>, peer not responding\n",
883 l_ptr->name);
878 tipc_link_reset(l_ptr); 884 tipc_link_reset(l_ptr);
879 l_ptr->state = RESET_UNKNOWN; 885 l_ptr->state = RESET_UNKNOWN;
880 l_ptr->fsm_msg_cnt = 0; 886 l_ptr->fsm_msg_cnt = 0;
@@ -982,17 +988,20 @@ static int link_bundle_buf(struct link *l_ptr,
982 struct tipc_msg *bundler_msg = buf_msg(bundler); 988 struct tipc_msg *bundler_msg = buf_msg(bundler);
983 struct tipc_msg *msg = buf_msg(buf); 989 struct tipc_msg *msg = buf_msg(buf);
984 u32 size = msg_size(msg); 990 u32 size = msg_size(msg);
985 u32 to_pos = align(msg_size(bundler_msg)); 991 u32 bundle_size = msg_size(bundler_msg);
986 u32 rest = link_max_pkt(l_ptr) - to_pos; 992 u32 to_pos = align(bundle_size);
993 u32 pad = to_pos - bundle_size;
987 994
988 if (msg_user(bundler_msg) != MSG_BUNDLER) 995 if (msg_user(bundler_msg) != MSG_BUNDLER)
989 return 0; 996 return 0;
990 if (msg_type(bundler_msg) != OPEN_MSG) 997 if (msg_type(bundler_msg) != OPEN_MSG)
991 return 0; 998 return 0;
992 if (rest < align(size)) 999 if (skb_tailroom(bundler) < (pad + size))
1000 return 0;
1001 if (link_max_pkt(l_ptr) < (to_pos + size))
993 return 0; 1002 return 0;
994 1003
995 skb_put(bundler, (to_pos - msg_size(bundler_msg)) + size); 1004 skb_put(bundler, pad + size);
996 memcpy(bundler->data + to_pos, buf->data, size); 1005 memcpy(bundler->data + to_pos, buf->data, size);
997 msg_set_size(bundler_msg, to_pos + size); 1006 msg_set_size(bundler_msg, to_pos + size);
998 msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1); 1007 msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1);
@@ -1050,7 +1059,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
1050 msg_dbg(msg, "TIPC: Congestion, throwing away\n"); 1059 msg_dbg(msg, "TIPC: Congestion, throwing away\n");
1051 buf_discard(buf); 1060 buf_discard(buf);
1052 if (imp > CONN_MANAGER) { 1061 if (imp > CONN_MANAGER) {
1053 warn("Resetting <%s>, send queue full", l_ptr->name); 1062 warn("Resetting link <%s>, send queue full", l_ptr->name);
1054 tipc_link_reset(l_ptr); 1063 tipc_link_reset(l_ptr);
1055 } 1064 }
1056 return dsz; 1065 return dsz;
@@ -1135,9 +1144,13 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
1135 if (n_ptr) { 1144 if (n_ptr) {
1136 tipc_node_lock(n_ptr); 1145 tipc_node_lock(n_ptr);
1137 l_ptr = n_ptr->active_links[selector & 1]; 1146 l_ptr = n_ptr->active_links[selector & 1];
1138 dbg("tipc_link_send: found link %x for dest %x\n", l_ptr, dest);
1139 if (l_ptr) { 1147 if (l_ptr) {
1148 dbg("tipc_link_send: found link %x for dest %x\n", l_ptr, dest);
1140 res = tipc_link_send_buf(l_ptr, buf); 1149 res = tipc_link_send_buf(l_ptr, buf);
1150 } else {
1151 dbg("Attempt to send msg to unreachable node:\n");
1152 msg_dbg(buf_msg(buf),">>>");
1153 buf_discard(buf);
1141 } 1154 }
1142 tipc_node_unlock(n_ptr); 1155 tipc_node_unlock(n_ptr);
1143 } else { 1156 } else {
@@ -1242,8 +1255,6 @@ int tipc_link_send_sections_fast(struct port *sender,
1242 int res; 1255 int res;
1243 u32 selector = msg_origport(hdr) & 1; 1256 u32 selector = msg_origport(hdr) & 1;
1244 1257
1245 assert(destaddr != tipc_own_addr);
1246
1247again: 1258again:
1248 /* 1259 /*
1249 * Try building message using port's max_pkt hint. 1260 * Try building message using port's max_pkt hint.
@@ -1604,40 +1615,121 @@ void tipc_link_push_queue(struct link *l_ptr)
1604 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); 1615 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
1605} 1616}
1606 1617
1618static void link_reset_all(unsigned long addr)
1619{
1620 struct node *n_ptr;
1621 char addr_string[16];
1622 u32 i;
1623
1624 read_lock_bh(&tipc_net_lock);
1625 n_ptr = tipc_node_find((u32)addr);
1626 if (!n_ptr) {
1627 read_unlock_bh(&tipc_net_lock);
1628 return; /* node no longer exists */
1629 }
1630
1631 tipc_node_lock(n_ptr);
1632
1633 warn("Resetting all links to %s\n",
1634 addr_string_fill(addr_string, n_ptr->addr));
1635
1636 for (i = 0; i < MAX_BEARERS; i++) {
1637 if (n_ptr->links[i]) {
1638 link_print(n_ptr->links[i], TIPC_OUTPUT,
1639 "Resetting link\n");
1640 tipc_link_reset(n_ptr->links[i]);
1641 }
1642 }
1643
1644 tipc_node_unlock(n_ptr);
1645 read_unlock_bh(&tipc_net_lock);
1646}
1647
1648static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
1649{
1650 struct tipc_msg *msg = buf_msg(buf);
1651
1652 warn("Retransmission failure on link <%s>\n", l_ptr->name);
1653 tipc_msg_print(TIPC_OUTPUT, msg, ">RETR-FAIL>");
1654
1655 if (l_ptr->addr) {
1656
1657 /* Handle failure on standard link */
1658
1659 link_print(l_ptr, TIPC_OUTPUT, "Resetting link\n");
1660 tipc_link_reset(l_ptr);
1661
1662 } else {
1663
1664 /* Handle failure on broadcast link */
1665
1666 struct node *n_ptr;
1667 char addr_string[16];
1668
1669 tipc_printf(TIPC_OUTPUT, "Msg seq number: %u, ", msg_seqno(msg));
1670 tipc_printf(TIPC_OUTPUT, "Outstanding acks: %u\n", (u32)TIPC_SKB_CB(buf)->handle);
1671
1672 n_ptr = l_ptr->owner->next;
1673 tipc_node_lock(n_ptr);
1674
1675 addr_string_fill(addr_string, n_ptr->addr);
1676 tipc_printf(TIPC_OUTPUT, "Multicast link info for %s\n", addr_string);
1677 tipc_printf(TIPC_OUTPUT, "Supported: %d, ", n_ptr->bclink.supported);
1678 tipc_printf(TIPC_OUTPUT, "Acked: %u\n", n_ptr->bclink.acked);
1679 tipc_printf(TIPC_OUTPUT, "Last in: %u, ", n_ptr->bclink.last_in);
1680 tipc_printf(TIPC_OUTPUT, "Gap after: %u, ", n_ptr->bclink.gap_after);
1681 tipc_printf(TIPC_OUTPUT, "Gap to: %u\n", n_ptr->bclink.gap_to);
1682 tipc_printf(TIPC_OUTPUT, "Nack sync: %u\n\n", n_ptr->bclink.nack_sync);
1683
1684 tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr);
1685
1686 tipc_node_unlock(n_ptr);
1687
1688 l_ptr->stale_count = 0;
1689 }
1690}
1691
1607void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf, 1692void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf,
1608 u32 retransmits) 1693 u32 retransmits)
1609{ 1694{
1610 struct tipc_msg *msg; 1695 struct tipc_msg *msg;
1611 1696
1697 if (!buf)
1698 return;
1699
1700 msg = buf_msg(buf);
1701
1612 dbg("Retransmitting %u in link %x\n", retransmits, l_ptr); 1702 dbg("Retransmitting %u in link %x\n", retransmits, l_ptr);
1613 1703
1614 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr) && buf && !skb_cloned(buf)) { 1704 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
1615 msg_dbg(buf_msg(buf), ">NO_RETR->BCONG>"); 1705 if (!skb_cloned(buf)) {
1616 dbg_print_link(l_ptr, " "); 1706 msg_dbg(msg, ">NO_RETR->BCONG>");
1617 l_ptr->retransm_queue_head = msg_seqno(buf_msg(buf)); 1707 dbg_print_link(l_ptr, " ");
1618 l_ptr->retransm_queue_size = retransmits; 1708 l_ptr->retransm_queue_head = msg_seqno(msg);
1619 return; 1709 l_ptr->retransm_queue_size = retransmits;
1710 return;
1711 } else {
1712 /* Don't retransmit if driver already has the buffer */
1713 }
1714 } else {
1715 /* Detect repeated retransmit failures on uncongested bearer */
1716
1717 if (l_ptr->last_retransmitted == msg_seqno(msg)) {
1718 if (++l_ptr->stale_count > 100) {
1719 link_retransmit_failure(l_ptr, buf);
1720 return;
1721 }
1722 } else {
1723 l_ptr->last_retransmitted = msg_seqno(msg);
1724 l_ptr->stale_count = 1;
1725 }
1620 } 1726 }
1727
1621 while (retransmits && (buf != l_ptr->next_out) && buf && !skb_cloned(buf)) { 1728 while (retransmits && (buf != l_ptr->next_out) && buf && !skb_cloned(buf)) {
1622 msg = buf_msg(buf); 1729 msg = buf_msg(buf);
1623 msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); 1730 msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
1624 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); 1731 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
1625 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 1732 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
1626 /* Catch if retransmissions fail repeatedly: */
1627 if (l_ptr->last_retransmitted == msg_seqno(msg)) {
1628 if (++l_ptr->stale_count > 100) {
1629 tipc_msg_print(TIPC_CONS, buf_msg(buf), ">RETR>");
1630 info("...Retransmitted %u times\n",
1631 l_ptr->stale_count);
1632 link_print(l_ptr, TIPC_CONS, "Resetting Link\n");
1633 tipc_link_reset(l_ptr);
1634 break;
1635 }
1636 } else {
1637 l_ptr->stale_count = 0;
1638 }
1639 l_ptr->last_retransmitted = msg_seqno(msg);
1640
1641 msg_dbg(buf_msg(buf), ">RETR>"); 1733 msg_dbg(buf_msg(buf), ">RETR>");
1642 buf = buf->next; 1734 buf = buf->next;
1643 retransmits--; 1735 retransmits--;
@@ -1650,6 +1742,7 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf,
1650 return; 1742 return;
1651 } 1743 }
1652 } 1744 }
1745
1653 l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; 1746 l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0;
1654} 1747}
1655 1748
@@ -1720,6 +1813,11 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1720 link_recv_non_seq(buf); 1813 link_recv_non_seq(buf);
1721 continue; 1814 continue;
1722 } 1815 }
1816
1817 if (unlikely(!msg_short(msg) &&
1818 (msg_destnode(msg) != tipc_own_addr)))
1819 goto cont;
1820
1723 n_ptr = tipc_node_find(msg_prevnode(msg)); 1821 n_ptr = tipc_node_find(msg_prevnode(msg));
1724 if (unlikely(!n_ptr)) 1822 if (unlikely(!n_ptr))
1725 goto cont; 1823 goto cont;
@@ -2140,7 +2238,7 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
2140 2238
2141 if (msg_linkprio(msg) && 2239 if (msg_linkprio(msg) &&
2142 (msg_linkprio(msg) != l_ptr->priority)) { 2240 (msg_linkprio(msg) != l_ptr->priority)) {
2143 warn("Changing prio <%s>: %u->%u\n", 2241 warn("Resetting link <%s>, priority change %u->%u\n",
2144 l_ptr->name, l_ptr->priority, msg_linkprio(msg)); 2242 l_ptr->name, l_ptr->priority, msg_linkprio(msg));
2145 l_ptr->priority = msg_linkprio(msg); 2243 l_ptr->priority = msg_linkprio(msg);
2146 tipc_link_reset(l_ptr); /* Enforce change to take effect */ 2244 tipc_link_reset(l_ptr); /* Enforce change to take effect */
@@ -2209,17 +2307,22 @@ void tipc_link_tunnel(struct link *l_ptr,
2209 u32 length = msg_size(msg); 2307 u32 length = msg_size(msg);
2210 2308
2211 tunnel = l_ptr->owner->active_links[selector & 1]; 2309 tunnel = l_ptr->owner->active_links[selector & 1];
2212 if (!tipc_link_is_up(tunnel)) 2310 if (!tipc_link_is_up(tunnel)) {
2311 warn("Link changeover error, "
2312 "tunnel link no longer available\n");
2213 return; 2313 return;
2314 }
2214 msg_set_size(tunnel_hdr, length + INT_H_SIZE); 2315 msg_set_size(tunnel_hdr, length + INT_H_SIZE);
2215 buf = buf_acquire(length + INT_H_SIZE); 2316 buf = buf_acquire(length + INT_H_SIZE);
2216 if (!buf) 2317 if (!buf) {
2318 warn("Link changeover error, "
2319 "unable to send tunnel msg\n");
2217 return; 2320 return;
2321 }
2218 memcpy(buf->data, (unchar *)tunnel_hdr, INT_H_SIZE); 2322 memcpy(buf->data, (unchar *)tunnel_hdr, INT_H_SIZE);
2219 memcpy(buf->data + INT_H_SIZE, (unchar *)msg, length); 2323 memcpy(buf->data + INT_H_SIZE, (unchar *)msg, length);
2220 dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane); 2324 dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane);
2221 msg_dbg(buf_msg(buf), ">SEND>"); 2325 msg_dbg(buf_msg(buf), ">SEND>");
2222 assert(tunnel);
2223 tipc_link_send_buf(tunnel, buf); 2326 tipc_link_send_buf(tunnel, buf);
2224} 2327}
2225 2328
@@ -2235,23 +2338,27 @@ void tipc_link_changeover(struct link *l_ptr)
2235 u32 msgcount = l_ptr->out_queue_size; 2338 u32 msgcount = l_ptr->out_queue_size;
2236 struct sk_buff *crs = l_ptr->first_out; 2339 struct sk_buff *crs = l_ptr->first_out;
2237 struct link *tunnel = l_ptr->owner->active_links[0]; 2340 struct link *tunnel = l_ptr->owner->active_links[0];
2238 int split_bundles = tipc_node_has_redundant_links(l_ptr->owner);
2239 struct tipc_msg tunnel_hdr; 2341 struct tipc_msg tunnel_hdr;
2342 int split_bundles;
2240 2343
2241 if (!tunnel) 2344 if (!tunnel)
2242 return; 2345 return;
2243 2346
2244 if (!l_ptr->owner->permit_changeover) 2347 if (!l_ptr->owner->permit_changeover) {
2348 warn("Link changeover error, "
2349 "peer did not permit changeover\n");
2245 return; 2350 return;
2351 }
2246 2352
2247 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, 2353 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL,
2248 ORIGINAL_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); 2354 ORIGINAL_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr);
2249 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); 2355 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
2250 msg_set_msgcnt(&tunnel_hdr, msgcount); 2356 msg_set_msgcnt(&tunnel_hdr, msgcount);
2357 dbg("Link changeover requires %u tunnel messages\n", msgcount);
2358
2251 if (!l_ptr->first_out) { 2359 if (!l_ptr->first_out) {
2252 struct sk_buff *buf; 2360 struct sk_buff *buf;
2253 2361
2254 assert(!msgcount);
2255 buf = buf_acquire(INT_H_SIZE); 2362 buf = buf_acquire(INT_H_SIZE);
2256 if (buf) { 2363 if (buf) {
2257 memcpy(buf->data, (unchar *)&tunnel_hdr, INT_H_SIZE); 2364 memcpy(buf->data, (unchar *)&tunnel_hdr, INT_H_SIZE);
@@ -2261,10 +2368,15 @@ void tipc_link_changeover(struct link *l_ptr)
2261 msg_dbg(&tunnel_hdr, "EMPTY>SEND>"); 2368 msg_dbg(&tunnel_hdr, "EMPTY>SEND>");
2262 tipc_link_send_buf(tunnel, buf); 2369 tipc_link_send_buf(tunnel, buf);
2263 } else { 2370 } else {
2264 warn("Memory squeeze; link changeover failed\n"); 2371 warn("Link changeover error, "
2372 "unable to send changeover msg\n");
2265 } 2373 }
2266 return; 2374 return;
2267 } 2375 }
2376
2377 split_bundles = (l_ptr->owner->active_links[0] !=
2378 l_ptr->owner->active_links[1]);
2379
2268 while (crs) { 2380 while (crs) {
2269 struct tipc_msg *msg = buf_msg(crs); 2381 struct tipc_msg *msg = buf_msg(crs);
2270 2382
@@ -2310,7 +2422,8 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel)
2310 msg_set_size(&tunnel_hdr, length + INT_H_SIZE); 2422 msg_set_size(&tunnel_hdr, length + INT_H_SIZE);
2311 outbuf = buf_acquire(length + INT_H_SIZE); 2423 outbuf = buf_acquire(length + INT_H_SIZE);
2312 if (outbuf == NULL) { 2424 if (outbuf == NULL) {
2313 warn("Memory squeeze; buffer duplication failed\n"); 2425 warn("Link changeover error, "
2426 "unable to send duplicate msg\n");
2314 return; 2427 return;
2315 } 2428 }
2316 memcpy(outbuf->data, (unchar *)&tunnel_hdr, INT_H_SIZE); 2429 memcpy(outbuf->data, (unchar *)&tunnel_hdr, INT_H_SIZE);
@@ -2364,11 +2477,15 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2364 u32 msg_count = msg_msgcnt(tunnel_msg); 2477 u32 msg_count = msg_msgcnt(tunnel_msg);
2365 2478
2366 dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)]; 2479 dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)];
2367 assert(dest_link != *l_ptr);
2368 if (!dest_link) { 2480 if (!dest_link) {
2369 msg_dbg(tunnel_msg, "NOLINK/<REC<"); 2481 msg_dbg(tunnel_msg, "NOLINK/<REC<");
2370 goto exit; 2482 goto exit;
2371 } 2483 }
2484 if (dest_link == *l_ptr) {
2485 err("Unexpected changeover message on link <%s>\n",
2486 (*l_ptr)->name);
2487 goto exit;
2488 }
2372 dbg("%c<-%c:", dest_link->b_ptr->net_plane, 2489 dbg("%c<-%c:", dest_link->b_ptr->net_plane,
2373 (*l_ptr)->b_ptr->net_plane); 2490 (*l_ptr)->b_ptr->net_plane);
2374 *l_ptr = dest_link; 2491 *l_ptr = dest_link;
@@ -2381,7 +2498,7 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2381 } 2498 }
2382 *buf = buf_extract(tunnel_buf,INT_H_SIZE); 2499 *buf = buf_extract(tunnel_buf,INT_H_SIZE);
2383 if (*buf == NULL) { 2500 if (*buf == NULL) {
2384 warn("Memory squeeze; failed to extract msg\n"); 2501 warn("Link changeover error, duplicate msg dropped\n");
2385 goto exit; 2502 goto exit;
2386 } 2503 }
2387 msg_dbg(tunnel_msg, "TNL<REC<"); 2504 msg_dbg(tunnel_msg, "TNL<REC<");
@@ -2393,13 +2510,17 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2393 2510
2394 if (tipc_link_is_up(dest_link)) { 2511 if (tipc_link_is_up(dest_link)) {
2395 msg_dbg(tunnel_msg, "UP/FIRST/<REC<"); 2512 msg_dbg(tunnel_msg, "UP/FIRST/<REC<");
2513 info("Resetting link <%s>, changeover initiated by peer\n",
2514 dest_link->name);
2396 tipc_link_reset(dest_link); 2515 tipc_link_reset(dest_link);
2397 dest_link->exp_msg_count = msg_count; 2516 dest_link->exp_msg_count = msg_count;
2517 dbg("Expecting %u tunnelled messages\n", msg_count);
2398 if (!msg_count) 2518 if (!msg_count)
2399 goto exit; 2519 goto exit;
2400 } else if (dest_link->exp_msg_count == START_CHANGEOVER) { 2520 } else if (dest_link->exp_msg_count == START_CHANGEOVER) {
2401 msg_dbg(tunnel_msg, "BLK/FIRST/<REC<"); 2521 msg_dbg(tunnel_msg, "BLK/FIRST/<REC<");
2402 dest_link->exp_msg_count = msg_count; 2522 dest_link->exp_msg_count = msg_count;
2523 dbg("Expecting %u tunnelled messages\n", msg_count);
2403 if (!msg_count) 2524 if (!msg_count)
2404 goto exit; 2525 goto exit;
2405 } 2526 }
@@ -2407,6 +2528,8 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2407 /* Receive original message */ 2528 /* Receive original message */
2408 2529
2409 if (dest_link->exp_msg_count == 0) { 2530 if (dest_link->exp_msg_count == 0) {
2531 warn("Link switchover error, "
2532 "got too many tunnelled messages\n");
2410 msg_dbg(tunnel_msg, "OVERDUE/DROP/<REC<"); 2533 msg_dbg(tunnel_msg, "OVERDUE/DROP/<REC<");
2411 dbg_print_link(dest_link, "LINK:"); 2534 dbg_print_link(dest_link, "LINK:");
2412 goto exit; 2535 goto exit;
@@ -2422,7 +2545,7 @@ static int link_recv_changeover_msg(struct link **l_ptr,
2422 buf_discard(tunnel_buf); 2545 buf_discard(tunnel_buf);
2423 return 1; 2546 return 1;
2424 } else { 2547 } else {
2425 warn("Memory squeeze; dropped incoming msg\n"); 2548 warn("Link changeover error, original msg dropped\n");
2426 } 2549 }
2427 } 2550 }
2428exit: 2551exit:
@@ -2444,13 +2567,8 @@ void tipc_link_recv_bundle(struct sk_buff *buf)
2444 while (msgcount--) { 2567 while (msgcount--) {
2445 obuf = buf_extract(buf, pos); 2568 obuf = buf_extract(buf, pos);
2446 if (obuf == NULL) { 2569 if (obuf == NULL) {
2447 char addr_string[16]; 2570 warn("Link unable to unbundle message(s)\n");
2448 2571 break;
2449 warn("Buffer allocation failure;\n");
2450 warn(" incoming message(s) from %s lost\n",
2451 addr_string_fill(addr_string,
2452 msg_orignode(buf_msg(buf))));
2453 return;
2454 }; 2572 };
2455 pos += align(msg_size(buf_msg(obuf))); 2573 pos += align(msg_size(buf_msg(obuf)));
2456 msg_dbg(buf_msg(obuf), " /"); 2574 msg_dbg(buf_msg(obuf), " /");
@@ -2508,7 +2626,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf)
2508 } 2626 }
2509 fragm = buf_acquire(fragm_sz + INT_H_SIZE); 2627 fragm = buf_acquire(fragm_sz + INT_H_SIZE);
2510 if (fragm == NULL) { 2628 if (fragm == NULL) {
2511 warn("Memory squeeze; failed to fragment msg\n"); 2629 warn("Link unable to fragment message\n");
2512 dsz = -ENOMEM; 2630 dsz = -ENOMEM;
2513 goto exit; 2631 goto exit;
2514 } 2632 }
@@ -2623,7 +2741,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2623 set_fragm_size(pbuf,fragm_sz); 2741 set_fragm_size(pbuf,fragm_sz);
2624 set_expected_frags(pbuf,exp_fragm_cnt - 1); 2742 set_expected_frags(pbuf,exp_fragm_cnt - 1);
2625 } else { 2743 } else {
2626 warn("Memory squeeze; got no defragmenting buffer\n"); 2744 warn("Link unable to reassemble fragmented message\n");
2627 } 2745 }
2628 buf_discard(fbuf); 2746 buf_discard(fbuf);
2629 return 0; 2747 return 0;