Commit 34b9cd64 authored by Jon Paul Maloy's avatar Jon Paul Maloy Committed by David S. Miller

tipc: let first message on link be a state message

According to the link FSM, a received traffic packet can take a link
from state ESTABLISHING to ESTABLISHED, but the link can still not be
fully set up in one atomic operation. This means that even if the the
very first packet on the link is a traffic packet with sequence number
1 (one), it has to be dropped and retransmitted.

This can be avoided if we let the mentioned packet be preceded by a
LINK_PROTOCOL/STATE message, which takes up the endpoint before the
arrival of the traffic.

We add this small feature in this commit.

This is a fully compatible change.
Acked-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent de7e07f9
...@@ -1107,12 +1107,12 @@ static bool tipc_link_release_pkts(struct tipc_link *l, u16 acked) ...@@ -1107,12 +1107,12 @@ static bool tipc_link_release_pkts(struct tipc_link *l, u16 acked)
return released; return released;
} }
/* tipc_link_build_ack_msg: prepare link acknowledge message for transmission /* tipc_link_build_state_msg: prepare link state message for transmission
* *
* Note that sending of broadcast ack is coordinated among nodes, to reduce * Note that sending of broadcast ack is coordinated among nodes, to reduce
* risk of ack storms towards the sender * risk of ack storms towards the sender
*/ */
int tipc_link_build_ack_msg(struct tipc_link *l, struct sk_buff_head *xmitq) int tipc_link_build_state_msg(struct tipc_link *l, struct sk_buff_head *xmitq)
{ {
if (!l) if (!l)
return 0; return 0;
...@@ -1222,7 +1222,7 @@ int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb, ...@@ -1222,7 +1222,7 @@ int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb,
if (!tipc_data_input(l, skb, l->inputq)) if (!tipc_data_input(l, skb, l->inputq))
rc |= tipc_link_input(l, skb, l->inputq); rc |= tipc_link_input(l, skb, l->inputq);
if (unlikely(++l->rcv_unacked >= TIPC_MIN_LINK_WIN)) if (unlikely(++l->rcv_unacked >= TIPC_MIN_LINK_WIN))
rc |= tipc_link_build_ack_msg(l, xmitq); rc |= tipc_link_build_state_msg(l, xmitq);
if (unlikely(rc & ~TIPC_LINK_SND_BC_ACK)) if (unlikely(rc & ~TIPC_LINK_SND_BC_ACK))
break; break;
} while ((skb = __skb_dequeue(defq))); } while ((skb = __skb_dequeue(defq)));
......
...@@ -123,7 +123,7 @@ int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]); ...@@ -123,7 +123,7 @@ int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]);
int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq); int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq);
int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb, int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb,
struct sk_buff_head *xmitq); struct sk_buff_head *xmitq);
int tipc_link_build_ack_msg(struct tipc_link *l, struct sk_buff_head *xmitq); int tipc_link_build_state_msg(struct tipc_link *l, struct sk_buff_head *xmitq);
void tipc_link_add_bc_peer(struct tipc_link *snd_l, void tipc_link_add_bc_peer(struct tipc_link *snd_l,
struct tipc_link *uc_l, struct tipc_link *uc_l,
struct sk_buff_head *xmitq); struct sk_buff_head *xmitq);
......
...@@ -545,6 +545,9 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id, ...@@ -545,6 +545,9 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id,
pr_debug("Established link <%s> on network plane %c\n", pr_debug("Established link <%s> on network plane %c\n",
tipc_link_name(nl), tipc_link_plane(nl)); tipc_link_name(nl), tipc_link_plane(nl));
/* Ensure that a STATE message goes first */
tipc_link_build_state_msg(nl, xmitq);
/* First link? => give it both slots */ /* First link? => give it both slots */
if (!ol) { if (!ol) {
*slot0 = bearer_id; *slot0 = bearer_id;
...@@ -1283,7 +1286,7 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id ...@@ -1283,7 +1286,7 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id
/* Broadcast ACKs are sent on a unicast link */ /* Broadcast ACKs are sent on a unicast link */
if (rc & TIPC_LINK_SND_BC_ACK) { if (rc & TIPC_LINK_SND_BC_ACK) {
tipc_node_read_lock(n); tipc_node_read_lock(n);
tipc_link_build_ack_msg(le->link, &xmitq); tipc_link_build_state_msg(le->link, &xmitq);
tipc_node_read_unlock(n); tipc_node_read_unlock(n);
} }
......
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