aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r--net/tipc/node.c54
1 files changed, 47 insertions, 7 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 0eb1bf850219..9e106d3ed187 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -714,7 +714,6 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id,
714 *slot0 = bearer_id; 714 *slot0 = bearer_id;
715 *slot1 = bearer_id; 715 *slot1 = bearer_id;
716 tipc_node_fsm_evt(n, SELF_ESTABL_CONTACT_EVT); 716 tipc_node_fsm_evt(n, SELF_ESTABL_CONTACT_EVT);
717 n->failover_sent = false;
718 n->action_flags |= TIPC_NOTIFY_NODE_UP; 717 n->action_flags |= TIPC_NOTIFY_NODE_UP;
719 tipc_link_set_active(nl, true); 718 tipc_link_set_active(nl, true);
720 tipc_bcast_add_peer(n->net, nl, xmitq); 719 tipc_bcast_add_peer(n->net, nl, xmitq);
@@ -757,6 +756,45 @@ static void tipc_node_link_up(struct tipc_node *n, int bearer_id,
757} 756}
758 757
759/** 758/**
759 * tipc_node_link_failover() - start failover in case "half-failover"
760 *
761 * This function is only called in a very special situation where link
762 * failover can be already started on peer node but not on this node.
763 * This can happen when e.g.
764 * 1. Both links <1A-2A>, <1B-2B> down
765 * 2. Link endpoint 2A up, but 1A still down (e.g. due to network
766 * disturbance, wrong session, etc.)
767 * 3. Link <1B-2B> up
768 * 4. Link endpoint 2A down (e.g. due to link tolerance timeout)
769 * 5. Node B starts failover onto link <1B-2B>
770 *
771 * ==> Node A does never start link/node failover!
772 *
773 * @n: tipc node structure
774 * @l: link peer endpoint failingover (- can be NULL)
775 * @tnl: tunnel link
776 * @xmitq: queue for messages to be xmited on tnl link later
777 */
778static void tipc_node_link_failover(struct tipc_node *n, struct tipc_link *l,
779 struct tipc_link *tnl,
780 struct sk_buff_head *xmitq)
781{
782 /* Avoid to be "self-failover" that can never end */
783 if (!tipc_link_is_up(tnl))
784 return;
785
786 tipc_link_fsm_evt(tnl, LINK_SYNCH_END_EVT);
787 tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT);
788
789 n->sync_point = tipc_link_rcv_nxt(tnl) + (U16_MAX / 2 - 1);
790 tipc_link_failover_prepare(l, tnl, xmitq);
791
792 if (l)
793 tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT);
794 tipc_node_fsm_evt(n, NODE_FAILOVER_BEGIN_EVT);
795}
796
797/**
760 * __tipc_node_link_down - handle loss of link 798 * __tipc_node_link_down - handle loss of link
761 */ 799 */
762static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id, 800static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
@@ -1675,14 +1713,16 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
1675 tipc_skb_queue_splice_tail_init(tipc_link_inputq(pl), 1713 tipc_skb_queue_splice_tail_init(tipc_link_inputq(pl),
1676 tipc_link_inputq(l)); 1714 tipc_link_inputq(l));
1677 } 1715 }
1716
1678 /* If parallel link was already down, and this happened before 1717 /* If parallel link was already down, and this happened before
1679 * the tunnel link came up, FAILOVER was never sent. Ensure that 1718 * the tunnel link came up, node failover was never started.
1680 * FAILOVER is sent to get peer out of NODE_FAILINGOVER state. 1719 * Ensure that a FAILOVER_MSG is sent to get peer out of
1720 * NODE_FAILINGOVER state, also this node must accept
1721 * TUNNEL_MSGs from peer.
1681 */ 1722 */
1682 if (n->state != NODE_FAILINGOVER && !n->failover_sent) { 1723 if (n->state != NODE_FAILINGOVER)
1683 tipc_link_create_dummy_tnl_msg(l, xmitq); 1724 tipc_node_link_failover(n, pl, l, xmitq);
1684 n->failover_sent = true; 1725
1685 }
1686 /* If pkts arrive out of order, use lowest calculated syncpt */ 1726 /* If pkts arrive out of order, use lowest calculated syncpt */
1687 if (less(syncpt, n->sync_point)) 1727 if (less(syncpt, n->sync_point))
1688 n->sync_point = syncpt; 1728 n->sync_point = syncpt;