Commit 7769f406 authored by Ilpo Järvinen's avatar Ilpo Järvinen Committed by David S. Miller

[TCP]: Fix logic breakage due to DSACK separation

Commit 6f74651a is found guilty
of breaking DSACK counting, which should be done only for the
SACK block reported by the DSACK instead of every SACK block
that is received along with DSACK information.
Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@helsinki.fi>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b9ce204f
...@@ -953,7 +953,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ ...@@ -953,7 +953,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
int prior_fackets; int prior_fackets;
u32 lost_retrans = 0; u32 lost_retrans = 0;
int flag = 0; int flag = 0;
int dup_sack = 0; int found_dup_sack = 0;
int cached_fack_count; int cached_fack_count;
int i; int i;
int first_sack_index; int first_sack_index;
...@@ -964,20 +964,20 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ ...@@ -964,20 +964,20 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
/* Check for D-SACK. */ /* Check for D-SACK. */
if (before(ntohl(sp[0].start_seq), TCP_SKB_CB(ack_skb)->ack_seq)) { if (before(ntohl(sp[0].start_seq), TCP_SKB_CB(ack_skb)->ack_seq)) {
dup_sack = 1; found_dup_sack = 1;
tp->rx_opt.sack_ok |= 4; tp->rx_opt.sack_ok |= 4;
NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV); NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV);
} else if (num_sacks > 1 && } else if (num_sacks > 1 &&
!after(ntohl(sp[0].end_seq), ntohl(sp[1].end_seq)) && !after(ntohl(sp[0].end_seq), ntohl(sp[1].end_seq)) &&
!before(ntohl(sp[0].start_seq), ntohl(sp[1].start_seq))) { !before(ntohl(sp[0].start_seq), ntohl(sp[1].start_seq))) {
dup_sack = 1; found_dup_sack = 1;
tp->rx_opt.sack_ok |= 4; tp->rx_opt.sack_ok |= 4;
NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV); NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV);
} }
/* D-SACK for already forgotten data... /* D-SACK for already forgotten data...
* Do dumb counting. */ * Do dumb counting. */
if (dup_sack && if (found_dup_sack &&
!after(ntohl(sp[0].end_seq), prior_snd_una) && !after(ntohl(sp[0].end_seq), prior_snd_una) &&
after(ntohl(sp[0].end_seq), tp->undo_marker)) after(ntohl(sp[0].end_seq), tp->undo_marker))
tp->undo_retrans--; tp->undo_retrans--;
...@@ -1058,6 +1058,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ ...@@ -1058,6 +1058,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
__u32 start_seq = ntohl(sp->start_seq); __u32 start_seq = ntohl(sp->start_seq);
__u32 end_seq = ntohl(sp->end_seq); __u32 end_seq = ntohl(sp->end_seq);
int fack_count; int fack_count;
int dup_sack = (found_dup_sack && (i == first_sack_index));
skb = cached_skb; skb = cached_skb;
fack_count = cached_fack_count; fack_count = cached_fack_count;
......
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