Skip to content

Commit a34f829

Browse files
Hamish Martindavem330
authored andcommitted
tipc: fix retransmission on unicast links
A scenario has been observed where a 'bc_init' message for a link is not retransmitted if it fails to be received by the peer. This leads to the peer never establishing the link fully and it discarding all other data received on the link. In this scenario the message is lost in transit to the peer. The issue is traced to the 'nxt_retr' field of the skb not being initialised for links that aren't a bc_sndlink. This leads to the comparison in tipc_link_advance_transmq() that gates whether to attempt retransmission of a message performing in an undesirable way. Depending on the relative value of 'jiffies', this comparison: time_before(jiffies, TIPC_SKB_CB(skb)->nxt_retr) may return true or false given that 'nxt_retr' remains at the uninitialised value of 0 for non bc_sndlinks. This is most noticeable shortly after boot when jiffies is initialised to a high value (to flush out rollover bugs) and we compare a jiffies of, say, 4294940189 to zero. In that case time_before returns 'true' leading to the skb not being retransmitted. The fix is to ensure that all skbs have a valid 'nxt_retr' time set for them and this is achieved by refactoring the setting of this value into a central function. With this fix, transmission losses of 'bc_init' messages do not stall the link establishment forever because the 'bc_init' message is retransmitted and the link eventually establishes correctly. Fixes: 382f598 ("tipc: reduce duplicate packets for unicast traffic") Acked-by: Jon Maloy <[email protected]> Signed-off-by: Hamish Martin <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 27d5332 commit a34f829

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

net/tipc/link.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,21 @@ static void link_prepare_wakeup(struct tipc_link *l)
921921

922922
}
923923

924+
/**
925+
* tipc_link_set_skb_retransmit_time - set the time at which retransmission of
926+
* the given skb should be next attempted
927+
* @skb: skb to set a future retransmission time for
928+
* @l: link the skb will be transmitted on
929+
*/
930+
static void tipc_link_set_skb_retransmit_time(struct sk_buff *skb,
931+
struct tipc_link *l)
932+
{
933+
if (link_is_bc_sndlink(l))
934+
TIPC_SKB_CB(skb)->nxt_retr = TIPC_BC_RETR_LIM;
935+
else
936+
TIPC_SKB_CB(skb)->nxt_retr = TIPC_UC_RETR_TIME;
937+
}
938+
924939
void tipc_link_reset(struct tipc_link *l)
925940
{
926941
struct sk_buff_head list;
@@ -1036,9 +1051,7 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list,
10361051
return -ENOBUFS;
10371052
}
10381053
__skb_queue_tail(transmq, skb);
1039-
/* next retransmit attempt */
1040-
if (link_is_bc_sndlink(l))
1041-
TIPC_SKB_CB(skb)->nxt_retr = TIPC_BC_RETR_LIM;
1054+
tipc_link_set_skb_retransmit_time(skb, l);
10421055
__skb_queue_tail(xmitq, _skb);
10431056
TIPC_SKB_CB(skb)->ackers = l->ackers;
10441057
l->rcv_unacked = 0;
@@ -1139,9 +1152,7 @@ static void tipc_link_advance_backlog(struct tipc_link *l,
11391152
if (unlikely(skb == l->backlog[imp].target_bskb))
11401153
l->backlog[imp].target_bskb = NULL;
11411154
__skb_queue_tail(&l->transmq, skb);
1142-
/* next retransmit attempt */
1143-
if (link_is_bc_sndlink(l))
1144-
TIPC_SKB_CB(skb)->nxt_retr = TIPC_BC_RETR_LIM;
1155+
tipc_link_set_skb_retransmit_time(skb, l);
11451156

11461157
__skb_queue_tail(xmitq, _skb);
11471158
TIPC_SKB_CB(skb)->ackers = l->ackers;
@@ -1584,8 +1595,7 @@ static int tipc_link_advance_transmq(struct tipc_link *l, struct tipc_link *r,
15841595
/* retransmit skb if unrestricted*/
15851596
if (time_before(jiffies, TIPC_SKB_CB(skb)->nxt_retr))
15861597
continue;
1587-
TIPC_SKB_CB(skb)->nxt_retr = (is_uc) ?
1588-
TIPC_UC_RETR_TIME : TIPC_BC_RETR_LIM;
1598+
tipc_link_set_skb_retransmit_time(skb, l);
15891599
_skb = pskb_copy(skb, GFP_ATOMIC);
15901600
if (!_skb)
15911601
continue;

0 commit comments

Comments
 (0)