]> Pileus Git - ~andy/linux/blobdiff - net/ipv4/tcp.c
tunneling: Add generic Tunnel segmentation.
[~andy/linux] / net / ipv4 / tcp.c
index 2aa69c8ae60c1990c76e69fe5aef46b990b6da6e..8d14573ade772f62378da2f90393806d4069ae04 100644 (file)
@@ -400,6 +400,8 @@ void tcp_init_sock(struct sock *sk)
        tcp_enable_early_retrans(tp);
        icsk->icsk_ca_ops = &tcp_init_congestion_ops;
 
+       tp->tsoffset = 0;
+
        sk->sk_state = TCP_CLOSE;
 
        sk->sk_write_space = sk_stream_write_space;
@@ -895,6 +897,7 @@ new_segment:
                        get_page(page);
                        skb_fill_page_desc(skb, i, page, offset, copy);
                }
+               skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
 
                skb->len += copy;
                skb->data_len += copy;
@@ -1406,10 +1409,10 @@ static void tcp_service_net_dma(struct sock *sk, bool wait)
                return;
 
        last_issued = tp->ucopy.dma_cookie;
-       dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+       dma_async_issue_pending(tp->ucopy.dma_chan);
 
        do {
-               if (dma_async_memcpy_complete(tp->ucopy.dma_chan,
+               if (dma_async_is_tx_complete(tp->ucopy.dma_chan,
                                              last_issued, &done,
                                              &used) == DMA_SUCCESS) {
                        /* Safe to free early-copied skbs now */
@@ -1751,7 +1754,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                                tcp_service_net_dma(sk, true);
                                tcp_cleanup_rbuf(sk, copied);
                        } else
-                               dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+                               dma_async_issue_pending(tp->ucopy.dma_chan);
                }
 #endif
                if (copied >= target) {
@@ -1844,7 +1847,7 @@ do_prequeue:
                                        break;
                                }
 
-                               dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+                               dma_async_issue_pending(tp->ucopy.dma_chan);
 
                                if ((offset + used) == skb->len)
                                        copied_early = true;
@@ -2287,7 +2290,6 @@ int tcp_disconnect(struct sock *sk, int flags)
        tp->packets_out = 0;
        tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
        tp->snd_cwnd_cnt = 0;
-       tp->bytes_acked = 0;
        tp->window_clamp = 0;
        tcp_set_ca_state(sk, TCP_CA_Open);
        tcp_clear_retrans(tp);
@@ -2711,6 +2713,12 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
                else
                        err = -EINVAL;
                break;
+       case TCP_TIMESTAMP:
+               if (!tp->repair)
+                       err = -EPERM;
+               else
+                       tp->tsoffset = val - tcp_time_stamp;
+               break;
        default:
                err = -ENOPROTOOPT;
                break;
@@ -2959,6 +2967,9 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
        case TCP_USER_TIMEOUT:
                val = jiffies_to_msecs(icsk->icsk_user_timeout);
                break;
+       case TCP_TIMESTAMP:
+               val = tcp_time_stamp + tp->tsoffset;
+               break;
        default:
                return -ENOPROTOOPT;
        }
@@ -3032,6 +3043,8 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
                               SKB_GSO_DODGY |
                               SKB_GSO_TCP_ECN |
                               SKB_GSO_TCPV6 |
+                              SKB_GSO_GRE |
+                              SKB_GSO_UDP_TUNNEL |
                               0) ||
                             !(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))))
                        goto out;
@@ -3243,7 +3256,7 @@ __tcp_alloc_md5sig_pool(struct sock *sk)
                struct crypto_hash *hash;
 
                hash = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
-               if (!hash || IS_ERR(hash))
+               if (IS_ERR_OR_NULL(hash))
                        goto out_free;
 
                per_cpu_ptr(pool, cpu)->md5_desc.tfm = hash;