aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2016-04-15 13:33:03 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-15 16:09:05 -0400
commit634696b197411e7a95b346d6e5c21841f29fcedd (patch)
treee3d95ec3b87c17d197d297fd245e1e27ed6ae3ca /net/tipc
parent25fb0b6c73122a4718cf218a164e468b11449a2d (diff)
tipc: guarantee peer bearer id exchange after reboot
When a link endpoint is going down locally, e.g., because its interface is being stopped, it will spontaneously send out a RESET message to its peer, informing it about this fact. This saves the peer from detecting the failure via probing, and hence gives both speedier and less resource consuming failure detection on the peer side. According to the link FSM, a receiver of a RESET message, ignoring the reason for it, must now consider the sender ready to come back up, and starts periodically sending out ACTIVATE messages to the peer in order to re-establish the link. Also, according to the FSM, the receiver of an ACTIVATE message can now go directly to state ESTABLISHED and start sending regular traffic packets. This is a well-proven and robust FSM. However, in the case of a reboot, there is a small possibilty that link endpoint on the rebooted node may have been re-created with a new bearer identity between the moment it sent its (pre-boot) RESET and the moment it receives the ACTIVATE from the peer. The new bearer identity cannot be known by the peer according to this scenario, since traffic headers don't convey such information. This is a problem, because both endpoints need to know the correct value of the peer's bearer id at any moment in time in order to be able to produce correct link events for their users. The only way to guarantee this is to enforce a full setup message exchange (RESET + ACTIVATE) even after the reboot, since those messages carry the bearer idientity in their header. In this commit we do this by introducing and setting a "stopping" bit in the header of the spontaneously generated RESET messages, informing the peer that the sender will not be immediately ready to re-establish the link. A receiver seeing this bit must act as if this were a locally detected connectivity failure, and hence has to go through a full two- way setup message exchange before any link can be re-established. Although never reported, this problem seems to have always been around. This protocol addition is fully backwards compatible. Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/link.c10
-rw-r--r--net/tipc/msg.h10
2 files changed, 19 insertions, 1 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 7d2bb3e70baa..8b98fafc88a4 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1140,11 +1140,17 @@ int tipc_link_build_ack_msg(struct tipc_link *l, struct sk_buff_head *xmitq)
1140void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq) 1140void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq)
1141{ 1141{
1142 int mtyp = RESET_MSG; 1142 int mtyp = RESET_MSG;
1143 struct sk_buff *skb;
1143 1144
1144 if (l->state == LINK_ESTABLISHING) 1145 if (l->state == LINK_ESTABLISHING)
1145 mtyp = ACTIVATE_MSG; 1146 mtyp = ACTIVATE_MSG;
1146 1147
1147 tipc_link_build_proto_msg(l, mtyp, 0, 0, 0, 0, xmitq); 1148 tipc_link_build_proto_msg(l, mtyp, 0, 0, 0, 0, xmitq);
1149
1150 /* Inform peer that this endpoint is going down if applicable */
1151 skb = skb_peek_tail(xmitq);
1152 if (skb && (l->state == LINK_RESET))
1153 msg_set_peer_stopping(buf_msg(skb), 1);
1148} 1154}
1149 1155
1150/* tipc_link_build_nack_msg: prepare link nack message for transmission 1156/* tipc_link_build_nack_msg: prepare link nack message for transmission
@@ -1411,7 +1417,9 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1411 l->priority = peers_prio; 1417 l->priority = peers_prio;
1412 1418
1413 /* ACTIVATE_MSG serves as PEER_RESET if link is already down */ 1419 /* ACTIVATE_MSG serves as PEER_RESET if link is already down */
1414 if ((mtyp == RESET_MSG) || !link_is_up(l)) 1420 if (msg_peer_stopping(hdr))
1421 rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
1422 else if ((mtyp == RESET_MSG) || !link_is_up(l))
1415 rc = tipc_link_fsm_evt(l, LINK_PEER_RESET_EVT); 1423 rc = tipc_link_fsm_evt(l, LINK_PEER_RESET_EVT);
1416 1424
1417 /* ACTIVATE_MSG takes up link if it was already locally reset */ 1425 /* ACTIVATE_MSG takes up link if it was already locally reset */
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index f34f639df643..58bf51541813 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -715,6 +715,16 @@ static inline void msg_set_redundant_link(struct tipc_msg *m, u32 r)
715 msg_set_bits(m, 5, 12, 0x1, r); 715 msg_set_bits(m, 5, 12, 0x1, r);
716} 716}
717 717
718static inline u32 msg_peer_stopping(struct tipc_msg *m)
719{
720 return msg_bits(m, 5, 13, 0x1);
721}
722
723static inline void msg_set_peer_stopping(struct tipc_msg *m, u32 s)
724{
725 msg_set_bits(m, 5, 13, 0x1, s);
726}
727
718static inline char *msg_media_addr(struct tipc_msg *m) 728static inline char *msg_media_addr(struct tipc_msg *m)
719{ 729{
720 return (char *)&m->hdr[TIPC_MEDIA_INFO_OFFSET]; 730 return (char *)&m->hdr[TIPC_MEDIA_INFO_OFFSET];