diff options
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r-- | net/tipc/node.c | 54 |
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 | */ | ||
778 | static 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 | */ |
762 | static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id, | 800 | static 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; |