]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/ipv4/tcp_output.c
Merge remote-tracking branch 'net-next/master'
[karo-tx-linux.git] / net / ipv4 / tcp_output.c
index e5ce0e1d13b7f1c677336e032dd6c2b342f492ae..672854664ff5c1d36783ac1bfb72fea481648ca1 100644 (file)
@@ -986,8 +986,10 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb)
 static void tcp_set_skb_tso_segs(const struct sock *sk, struct sk_buff *skb,
                                 unsigned int mss_now)
 {
-       if (skb->len <= mss_now || !sk_can_gso(sk) ||
-           skb->ip_summed == CHECKSUM_NONE) {
+       /* Make sure we own this skb before messing gso_size/gso_segs */
+       WARN_ON_ONCE(skb_cloned(skb));
+
+       if (skb->len <= mss_now || skb->ip_summed == CHECKSUM_NONE) {
                /* Avoid the costly divide in the normal
                 * non-TSO case.
                 */
@@ -1067,9 +1069,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
        if (nsize < 0)
                nsize = 0;
 
-       if (skb_cloned(skb) &&
-           skb_is_nonlinear(skb) &&
-           pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+       if (skb_unclone(skb, GFP_ATOMIC))
                return -ENOMEM;
 
        /* Get a new skb... force flag on. */
@@ -2344,6 +2344,8 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
                int oldpcount = tcp_skb_pcount(skb);
 
                if (unlikely(oldpcount > 1)) {
+                       if (skb_unclone(skb, GFP_ATOMIC))
+                               return -ENOMEM;
                        tcp_init_tso_segs(sk, skb, cur_mss);
                        tcp_adjust_pcount(sk, skb, oldpcount - tcp_skb_pcount(skb));
                }
@@ -2351,21 +2353,6 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 
        tcp_retrans_try_collapse(sk, skb, cur_mss);
 
-       /* Some Solaris stacks overoptimize and ignore the FIN on a
-        * retransmit when old data is attached.  So strip it off
-        * since it is cheap to do so and saves bytes on the network.
-        */
-       if (skb->len > 0 &&
-           (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) &&
-           tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
-               if (!pskb_trim(skb, 0)) {
-                       /* Reuse, even though it does some unnecessary work */
-                       tcp_init_nondata_skb(skb, TCP_SKB_CB(skb)->end_seq - 1,
-                                            TCP_SKB_CB(skb)->tcp_flags);
-                       skb->ip_summed = CHECKSUM_NONE;
-               }
-       }
-
        /* Make a copy, if the first transmission SKB clone we made
         * is still in somebody's hands, else make a clone.
         */