Commit a686e685 authored by Allan Stephens's avatar Allan Stephens Committed by David S. Miller

tipc: Fix minor bugs in link session number handling

This patch introduces a new, out-of-range value to indicate that
a link endpoint does not have an existing session established
with its peer, eliminating the risk that the previously used
"invalid session number" value (i.e. zero) might eventually be
assigned as a valid session number and cause incorrect link
behavior.

The patch also introduces explicit bit masking when assigning a
new link session number to ensure it does not exceed 16 bits.
Signed-off-by: default avatarAllan Stephens <allan.stephens@windriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e0d4e3d0
...@@ -50,6 +50,12 @@ ...@@ -50,6 +50,12 @@
#include "bcast.h" #include "bcast.h"
/*
* Out-of-range value for link session numbers
*/
#define INVALID_SESSION 0x10000
/* /*
* Limit for deferred reception queue: * Limit for deferred reception queue:
*/ */
...@@ -464,7 +470,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, ...@@ -464,7 +470,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
msg = l_ptr->pmsg; msg = l_ptr->pmsg;
msg_init(msg, LINK_PROTOCOL, RESET_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); msg_init(msg, LINK_PROTOCOL, RESET_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr);
msg_set_size(msg, sizeof(l_ptr->proto_msg)); msg_set_size(msg, sizeof(l_ptr->proto_msg));
msg_set_session(msg, tipc_random); msg_set_session(msg, (tipc_random & 0xffff));
msg_set_bearer_id(msg, b_ptr->identity); msg_set_bearer_id(msg, b_ptr->identity);
strcpy((char *)msg_data(msg), if_name); strcpy((char *)msg_data(msg), if_name);
...@@ -705,10 +711,10 @@ void tipc_link_reset(struct link *l_ptr) ...@@ -705,10 +711,10 @@ void tipc_link_reset(struct link *l_ptr)
u32 checkpoint = l_ptr->next_in_no; u32 checkpoint = l_ptr->next_in_no;
int was_active_link = tipc_link_is_active(l_ptr); int was_active_link = tipc_link_is_active(l_ptr);
msg_set_session(l_ptr->pmsg, msg_session(l_ptr->pmsg) + 1); msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff));
/* Link is down, accept any session: */ /* Link is down, accept any session */
l_ptr->peer_session = 0; l_ptr->peer_session = INVALID_SESSION;
/* Prepare for max packet size negotiation */ /* Prepare for max packet size negotiation */
link_init_max_pkt(l_ptr); link_init_max_pkt(l_ptr);
...@@ -2275,7 +2281,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) ...@@ -2275,7 +2281,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf)
switch (msg_type(msg)) { switch (msg_type(msg)) {
case RESET_MSG: case RESET_MSG:
if (!link_working_unknown(l_ptr) && l_ptr->peer_session) { if (!link_working_unknown(l_ptr) &&
(l_ptr->peer_session != INVALID_SESSION)) {
if (msg_session(msg) == l_ptr->peer_session) { if (msg_session(msg) == l_ptr->peer_session) {
dbg("Duplicate RESET: %u<->%u\n", dbg("Duplicate RESET: %u<->%u\n",
msg_session(msg), l_ptr->peer_session); msg_session(msg), l_ptr->peer_session);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment