tcp: allow segment with FIN in tcp_try_coalesce()
authorEric Dumazet <edumazet@google.com>
Mon, 15 Sep 2014 11:19:52 +0000 (04:19 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 15 Sep 2014 18:41:07 +0000 (14:41 -0400)
We can allow a segment with FIN to be aggregated,
if we take care to add tcp flags,
and if skb_try_coalesce() takes care of zero sized skbs.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/skbuff.c
net/ipv4/tcp_input.c

index c8259ac387452092348529b9ce601cde909a1a4c..29f7f0121491b4fd92035698bfa4b07bc12e40fd 100644 (file)
@@ -3936,7 +3936,8 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
                return false;
 
        if (len <= skb_tailroom(to)) {
-               BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len));
+               if (len)
+                       BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len));
                *delta_truesize = 0;
                return true;
        }
index 8f639a4face9c7bd349a6d14fcd35cc7b602c4b3..228bf0c5ff195daed1e24bf5128c68d7e6110a04 100644 (file)
@@ -4143,9 +4143,6 @@ static bool tcp_try_coalesce(struct sock *sk,
 
        *fragstolen = false;
 
-       if (tcp_hdr(from)->fin)
-               return false;
-
        /* Its possible this segment overlaps with prior segment in queue */
        if (TCP_SKB_CB(from)->seq != TCP_SKB_CB(to)->end_seq)
                return false;
@@ -4158,6 +4155,7 @@ static bool tcp_try_coalesce(struct sock *sk,
        NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRCVCOALESCE);
        TCP_SKB_CB(to)->end_seq = TCP_SKB_CB(from)->end_seq;
        TCP_SKB_CB(to)->ack_seq = TCP_SKB_CB(from)->ack_seq;
+       TCP_SKB_CB(to)->tcp_flags |= TCP_SKB_CB(from)->tcp_flags;
        return true;
 }