Skip to content

Commit 68cc924

Browse files
author
Paolo Abeni
committed
mptcp: fix duplicate data handling
When a subflow receives and discards duplicate data, the mptcp stack assumes that the consumed offset inside the current skb is zero. With multiple subflows receiving data simultaneously such assertion does not held true. As a result the subflow-level copied_seq will be incorrectly increased and later on the same subflow will observe a bad mapping, leading to subflow reset. Address the issue taking into account the skb consumed offset in mptcp_subflow_discard_data(). Fixes: 04e4cd4 ("mptcp: cleanup mptcp_subflow_discard_data()") Cc: [email protected] Link: multipath-tcp/mptcp_net-next#501 Signed-off-by: Paolo Abeni <[email protected]> Reviewed-by: Mat Martineau <[email protected]> Signed-off-by: Matthieu Baerts (NGI0) <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 0a567c2 commit 68cc924

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

net/mptcp/subflow.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,14 +1230,22 @@ static void mptcp_subflow_discard_data(struct sock *ssk, struct sk_buff *skb,
12301230
{
12311231
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
12321232
bool fin = TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN;
1233-
u32 incr;
1233+
struct tcp_sock *tp = tcp_sk(ssk);
1234+
u32 offset, incr, avail_len;
12341235

1235-
incr = limit >= skb->len ? skb->len + fin : limit;
1236+
offset = tp->copied_seq - TCP_SKB_CB(skb)->seq;
1237+
if (WARN_ON_ONCE(offset > skb->len))
1238+
goto out;
1239+
1240+
avail_len = skb->len - offset;
1241+
incr = limit >= avail_len ? avail_len + fin : limit;
12361242

1237-
pr_debug("discarding=%d len=%d seq=%d", incr, skb->len,
1238-
subflow->map_subflow_seq);
1243+
pr_debug("discarding=%d len=%d offset=%d seq=%d", incr, skb->len,
1244+
offset, subflow->map_subflow_seq);
12391245
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DUPDATA);
12401246
tcp_sk(ssk)->copied_seq += incr;
1247+
1248+
out:
12411249
if (!before(tcp_sk(ssk)->copied_seq, TCP_SKB_CB(skb)->end_seq))
12421250
sk_eat_skb(ssk, skb);
12431251
if (mptcp_subflow_get_map_offset(subflow) >= subflow->map_data_len)

0 commit comments

Comments
 (0)