diff options
-rw-r--r-- | net/tipc/link.c | 15 | ||||
-rw-r--r-- | net/tipc/msg.h | 22 | ||||
-rw-r--r-- | net/tipc/node.c | 11 |
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 | */ | ||
366 | static inline bool msg_dest_session_valid(struct tipc_msg *m) | ||
367 | { | ||
368 | return msg_bits(m, 1, 16, 0x1); | ||
369 | } | ||
370 | |||
371 | static 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 | |||
376 | static inline u16 msg_dest_session(struct tipc_msg *m) | ||
377 | { | ||
378 | return msg_bits(m, 1, 0, 0xffff); | ||
379 | } | ||
380 | |||
381 | static 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) |