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