Skip to content

Commit

Permalink
tcp: Make SACK code to split only at mss boundaries
Browse files Browse the repository at this point in the history
Sadly enough, this adds possible divide though we try to avoid
it by checking one mss as common case.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Ilpo Järvinen authored and David S. Miller committed Nov 25, 2008
1 parent e8bae27 commit adb92db
Showing 1 changed file with 23 additions and 4 deletions.
27 changes: 23 additions & 4 deletions net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -1248,20 +1248,39 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb,
{
int in_sack, err;
unsigned int pkt_len;
unsigned int mss;

in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) &&
!before(end_seq, TCP_SKB_CB(skb)->end_seq);

if (tcp_skb_pcount(skb) > 1 && !in_sack &&
after(TCP_SKB_CB(skb)->end_seq, start_seq)) {

mss = tcp_skb_mss(skb);
in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq);

if (!in_sack)
if (!in_sack) {
pkt_len = start_seq - TCP_SKB_CB(skb)->seq;
else
if (pkt_len < mss)
pkt_len = mss;
} else {
pkt_len = end_seq - TCP_SKB_CB(skb)->seq;
err = tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->gso_size);
if (pkt_len < mss)
return -EINVAL;
}

/* Round if necessary so that SACKs cover only full MSSes
* and/or the remaining small portion (if present)
*/
if (pkt_len > mss) {
unsigned int new_len = (pkt_len / mss) * mss;
if (!in_sack && new_len < pkt_len) {
new_len += mss;
if (new_len > skb->len)
return 0;
}
pkt_len = new_len;
}
err = tcp_fragment(sk, skb, pkt_len, mss);
if (err < 0)
return err;
}
Expand Down

0 comments on commit adb92db

Please sign in to comment.