On ven., 2016-03-04 at 15:57 -0800, Martin KaFai Lau wrote: > diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c > index 4c8d58d..c9b576f 100644 > --- a/net/ipv4/tcp_ipv4.c > +++ b/net/ipv4/tcp_ipv4.c > @@ -1540,6 +1540,7 @@ int tcp_v4_rcv(struct sk_buff *skb) > const struct iphdr *iph; > const struct tcphdr *th; > struct sock *sk; > + u16 segs_in; > int ret; > struct net *net = dev_net(skb->dev); > > @@ -1650,7 +1651,11 @@ process: > sk_incoming_cpu_update(sk); > > bh_lock_sock_nested(sk); > - tcp_sk(sk)->segs_in += max_t(u16, 1, skb_shinfo(skb)->gso_segs); > + segs_in = max_t(u16, 1, skb_shinfo(skb)->gso_segs); > + tcp_sk(sk)->segs_in += segs_in; > + if (skb->len > __tcp_hdrlen(th)) > + tcp_sk(sk)->data_segs_in += segs_in;
It looks like we have a bug if the segment comes for a SYN_RECV request socket. (It happens if the ACK packet of the 3WHS was lost) We do not enter this path in this case.