aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/tipc/link.c15
-rw-r--r--net/tipc/msg.h22
-rw-r--r--net/tipc/node.c11
3 files changed, 43 insertions, 5 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 7c70034b1073..85ad5c0678d0 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1425,6 +1425,10 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
1425 l->rcv_unacked = 0; 1425 l->rcv_unacked = 0;
1426 } else { 1426 } else {
1427 /* RESET_MSG or ACTIVATE_MSG */ 1427 /* RESET_MSG or ACTIVATE_MSG */
1428 if (mtyp == ACTIVATE_MSG) {
1429 msg_set_dest_session_valid(hdr, 1);
1430 msg_set_dest_session(hdr, l->peer_session);
1431 }
1428 msg_set_max_pkt(hdr, l->advertised_mtu); 1432 msg_set_max_pkt(hdr, l->advertised_mtu);
1429 strcpy(data, l->if_name); 1433 strcpy(data, l->if_name);
1430 msg_set_size(hdr, INT_H_SIZE + TIPC_MAX_IF_NAME); 1434 msg_set_size(hdr, INT_H_SIZE + TIPC_MAX_IF_NAME);
@@ -1642,6 +1646,17 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1642 rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT); 1646 rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
1643 break; 1647 break;
1644 } 1648 }
1649
1650 /* If this endpoint was re-created while peer was ESTABLISHING
1651 * it doesn't know current session number. Force re-synch.
1652 */
1653 if (mtyp == ACTIVATE_MSG && msg_dest_session_valid(hdr) &&
1654 l->session != msg_dest_session(hdr)) {
1655 if (less(l->session, msg_dest_session(hdr)))
1656 l->session = msg_dest_session(hdr) + 1;
1657 break;
1658 }
1659
1645 /* ACTIVATE_MSG serves as PEER_RESET if link is already down */ 1660 /* ACTIVATE_MSG serves as PEER_RESET if link is already down */
1646 if (mtyp == RESET_MSG || !link_is_up(l)) 1661 if (mtyp == RESET_MSG || !link_is_up(l))
1647 rc = tipc_link_fsm_evt(l, LINK_PEER_RESET_EVT); 1662 rc = tipc_link_fsm_evt(l, LINK_PEER_RESET_EVT);
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index a0924956bb61..d7e4b8b93f9d 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -360,6 +360,28 @@ static inline void msg_set_bcast_ack(struct tipc_msg *m, u16 n)
360 msg_set_bits(m, 1, 0, 0xffff, n); 360 msg_set_bits(m, 1, 0, 0xffff, n);
361} 361}
362 362
363/* Note: reusing bits in word 1 for ACTIVATE_MSG only, to re-synch
364 * link peer session number
365 */
366static inline bool msg_dest_session_valid(struct tipc_msg *m)
367{
368 return msg_bits(m, 1, 16, 0x1);
369}
370
371static inline void msg_set_dest_session_valid(struct tipc_msg *m, bool valid)
372{
373 msg_set_bits(m, 1, 16, 0x1, valid);
374}
375
376static inline u16 msg_dest_session(struct tipc_msg *m)
377{
378 return msg_bits(m, 1, 0, 0xffff);
379}
380
381static inline void msg_set_dest_session(struct tipc_msg *m, u16 n)
382{
383 msg_set_bits(m, 1, 0, 0xffff, n);
384}
363 385
364/* 386/*
365 * Word 2 387 * Word 2
diff --git a/net/tipc/node.c b/net/tipc/node.c
index db2a6c3e0be9..2dc4919ab23c 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -830,15 +830,16 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete)
830 tipc_node_write_lock(n); 830 tipc_node_write_lock(n);
831 if (!tipc_link_is_establishing(l)) { 831 if (!tipc_link_is_establishing(l)) {
832 __tipc_node_link_down(n, &bearer_id, &xmitq, &maddr); 832 __tipc_node_link_down(n, &bearer_id, &xmitq, &maddr);
833 if (delete) {
834 kfree(l);
835 le->link = NULL;
836 n->link_cnt--;
837 }
838 } else { 833 } else {
839 /* Defuse pending tipc_node_link_up() */ 834 /* Defuse pending tipc_node_link_up() */
835 tipc_link_reset(l);
840 tipc_link_fsm_evt(l, LINK_RESET_EVT); 836 tipc_link_fsm_evt(l, LINK_RESET_EVT);
841 } 837 }
838 if (delete) {
839 kfree(l);
840 le->link = NULL;
841 n->link_cnt--;
842 }
842 trace_tipc_node_link_down(n, true, "node link down or deleted!"); 843 trace_tipc_node_link_down(n, true, "node link down or deleted!");
843 tipc_node_write_unlock(n); 844 tipc_node_write_unlock(n);
844 if (delete) 845 if (delete)