Commit 93499313 authored by Allan Stephens's avatar Allan Stephens Committed by Paul Gortmaker

tipc: Ensure broadcast link re-acquires node after link failure

Fix a bug that can prevent TIPC from sending broadcast messages to a node
if contact with the node is lost and then regained. The problem occurs if
the broadcast link first clears the flag indicating the node is part of the
link's distribution set (when it loses contact with the node), and later
fails to restore the flag (when contact is regained); restoration fails
if contact with the node is regained by implicit unicast link activation
triggered by the arrival of a data message, rather than explicitly by the
arrival of a link activation message.

The broadcast link now uses separate fields to track whether a node is
theoretically capable of receiving broadcast messages versus whether it is
actually part of the link's distribution set. The former member is updated
by the receipt of link protocol messages, which can occur at any time; the
latter member is updated only when contact with the node is gained or lost.
This change also permits the simplification of several conditional
expressions since the broadcast link's "supported" field can now only be
set if there are working links to the associated node.
Signed-off-by: default avatarAllan Stephens <allan.stephens@windriver.com>
Signed-off-by: default avatarPaul Gortmaker <paul.gortmaker@windriver.com>
parent 4d75313c
...@@ -1502,6 +1502,7 @@ static void link_retransmit_failure(struct tipc_link *l_ptr, ...@@ -1502,6 +1502,7 @@ static void link_retransmit_failure(struct tipc_link *l_ptr,
tipc_addr_string_fill(addr_string, n_ptr->addr); tipc_addr_string_fill(addr_string, n_ptr->addr);
info("Multicast link info for %s\n", addr_string); info("Multicast link info for %s\n", addr_string);
info("Supportable: %d, ", n_ptr->bclink.supportable);
info("Supported: %d, ", n_ptr->bclink.supported); info("Supported: %d, ", n_ptr->bclink.supported);
info("Acked: %u\n", n_ptr->bclink.acked); info("Acked: %u\n", n_ptr->bclink.acked);
info("Last in: %u, ", n_ptr->bclink.last_in); info("Last in: %u, ", n_ptr->bclink.last_in);
...@@ -1736,7 +1737,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr) ...@@ -1736,7 +1737,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
/* Release acked messages */ /* Release acked messages */
if (tipc_node_is_up(n_ptr) && n_ptr->bclink.supported) if (n_ptr->bclink.supported)
tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg)); tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg));
crs = l_ptr->first_out; crs = l_ptr->first_out;
...@@ -2126,7 +2127,7 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf) ...@@ -2126,7 +2127,7 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf)
} else { } else {
l_ptr->max_pkt = l_ptr->max_pkt_target; l_ptr->max_pkt = l_ptr->max_pkt_target;
} }
l_ptr->owner->bclink.supported = (max_pkt_info != 0); l_ptr->owner->bclink.supportable = (max_pkt_info != 0);
/* Synchronize broadcast link info, if not done previously */ /* Synchronize broadcast link info, if not done previously */
......
...@@ -306,8 +306,9 @@ static void node_established_contact(struct tipc_node *n_ptr) ...@@ -306,8 +306,9 @@ static void node_established_contact(struct tipc_node *n_ptr)
/* Syncronize broadcast acks */ /* Syncronize broadcast acks */
n_ptr->bclink.acked = tipc_bclink_get_last_sent(); n_ptr->bclink.acked = tipc_bclink_get_last_sent();
if (n_ptr->bclink.supported) { if (n_ptr->bclink.supportable) {
tipc_bclink_add_node(n_ptr->addr); tipc_bclink_add_node(n_ptr->addr);
n_ptr->bclink.supported = 1;
if (n_ptr->addr < tipc_own_addr) if (n_ptr->addr < tipc_own_addr)
tipc_own_tag++; tipc_own_tag++;
} }
......
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
* @link_cnt: number of links to node * @link_cnt: number of links to node
* @permit_changeover: non-zero if node has redundant links to this system * @permit_changeover: non-zero if node has redundant links to this system
* @bclink: broadcast-related info * @bclink: broadcast-related info
* @supportable: non-zero if node supports TIPC b'cast link capability
* @supported: non-zero if node supports TIPC b'cast capability * @supported: non-zero if node supports TIPC b'cast capability
* @acked: sequence # of last outbound b'cast message acknowledged by node * @acked: sequence # of last outbound b'cast message acknowledged by node
* @last_in: sequence # of last in-sequence b'cast message received from node * @last_in: sequence # of last in-sequence b'cast message received from node
...@@ -86,7 +87,8 @@ struct tipc_node { ...@@ -86,7 +87,8 @@ struct tipc_node {
int block_setup; int block_setup;
int permit_changeover; int permit_changeover;
struct { struct {
int supported; u8 supportable;
u8 supported;
u32 acked; u32 acked;
u32 last_in; u32 last_in;
u32 gap_after; u32 gap_after;
......
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