Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
voxel committed Jul 17, 2019
1 parent b816095 commit d79ca65
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 8 deletions.
3 changes: 3 additions & 0 deletions git_home/linux.git/sourcecode/include/linux/tcp.h
Expand Up @@ -503,4 +503,7 @@ static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk)

#endif /* __KERNEL__ */

int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from, int pcount,
int shiftlen);

#endif /* _LINUX_TCP_H */
2 changes: 2 additions & 0 deletions git_home/linux.git/sourcecode/include/net/tcp.h
Expand Up @@ -54,6 +54,8 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);

#define MAX_TCP_HEADER (128 + MAX_HEADER)
#define MAX_TCP_OPTION_SPACE 40
#define TCP_MIN_SND_MSS 48
#define TCP_MIN_GSO_SIZE (TCP_MIN_SND_MSS - MAX_TCP_OPTION_SPACE)

/*
* Never offer a window over 32767 without using window scaling. Some
Expand Down
1 change: 1 addition & 0 deletions git_home/linux.git/sourcecode/net/ipv4/tcp.c
Expand Up @@ -3276,6 +3276,7 @@ void __init tcp_init(void)
unsigned int i;
unsigned long jiffy = jiffies;

BUILD_BUG_ON(TCP_MIN_SND_MSS <= MAX_TCP_OPTION_SPACE);
BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb));

percpu_counter_init(&tcp_sockets_allocated, 0);
Expand Down
26 changes: 20 additions & 6 deletions git_home/linux.git/sourcecode/net/ipv4/tcp_input.c
Expand Up @@ -1429,7 +1429,7 @@ static int tcp_shifted_skb(struct sock *sk, struct sk_buff *skb,
TCP_SKB_CB(skb)->seq += shifted;

skb_shinfo(prev)->gso_segs += pcount;
BUG_ON(skb_shinfo(skb)->gso_segs < pcount);
WARN_ON_ONCE(tcp_skb_pcount(skb) < pcount);
skb_shinfo(skb)->gso_segs -= pcount;

/* When we're adding to gso_segs == 1, gso_size will be zero,
Expand Down Expand Up @@ -1497,6 +1497,21 @@ static int skb_can_shift(const struct sk_buff *skb)
return !skb_headlen(skb) && skb_is_nonlinear(skb);
}

int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from,
int pcount, int shiftlen)
{
/* TCP min gso_size is 8 bytes (TCP_MIN_GSO_SIZE)
* Since TCP_SKB_CB(skb)->tcp_gso_segs is 16 bits, we need
* to make sure not storing more than 65535 * 8 bytes per skb,
* even if current MSS is bigger.
*/
if (unlikely(to->len + shiftlen >= 65535 * TCP_MIN_GSO_SIZE))
return 0;
if (unlikely(tcp_skb_pcount(to) + pcount > 65535))
return 0;
return skb_shift(to, from, shiftlen);
}

/* Try collapsing SACK blocks spanning across multiple skbs to a single
* skb.
*/
Expand Down Expand Up @@ -1602,7 +1617,7 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb,
if (!after(TCP_SKB_CB(skb)->seq + len, tp->snd_una))
goto fallback;

if (!skb_shift(prev, skb, len))
if (!tcp_skb_shift(prev, skb, pcount, len))
goto fallback;
if (!tcp_shifted_skb(sk, skb, state, pcount, len, mss, dup_sack))
goto out;
Expand All @@ -1621,10 +1636,9 @@ static struct sk_buff *tcp_shift_skb_data(struct sock *sk, struct sk_buff *skb,
goto out;

len = skb->len;
if (skb_shift(prev, skb, len)) {
pcount += tcp_skb_pcount(skb);
tcp_shifted_skb(sk, skb, state, tcp_skb_pcount(skb), len, mss, 0);
}
pcount = tcp_skb_pcount(skb);
if (tcp_skb_shift(prev, skb, pcount, len))
tcp_shifted_skb(sk, skb, state, pcount, len, mss, 0);

out:
state->fack_count += pcount;
Expand Down
4 changes: 2 additions & 2 deletions git_home/linux.git/sourcecode/net/ipv4/tcp_output.c
Expand Up @@ -1171,8 +1171,8 @@ int tcp_mtu_to_mss(const struct sock *sk, int pmtu)
mss_now -= icsk->icsk_ext_hdr_len;

/* Then reserve room for full set of TCP options and 8 bytes of data */
if (mss_now < 48)
mss_now = 48;
if (mss_now < TCP_MIN_SND_MSS)
mss_now = TCP_MIN_SND_MSS;

/* Now subtract TCP options size, not including SACKs */
mss_now -= tp->tcp_header_len - sizeof(struct tcphdr);
Expand Down

0 comments on commit d79ca65

Please sign in to comment.