Do timestamping before cloneing.
This fixes the bug where the timestamp was performed in tcp_transmit_skb
on
the cloned skb leading to the timestamp being lost.

Signed-off-by: Thomas Young <[EMAIL PROTECTED]>
---

diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -265,7 +265,6 @@ static __inline__ u16 tcp_select_window(
 static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
 {
        if (skb != NULL) {
-               const struct inet_connection_sock *icsk = inet_csk(sk);
                struct inet_sock *inet = inet_sk(sk);
                struct tcp_sock *tp = tcp_sk(sk);
                struct tcp_skb_cb *tcb = TCP_SKB_CB(skb);
@@ -280,10 +279,6 @@ static int tcp_transmit_skb(struct sock 
 #define SYSCTL_FLAG_WSCALE     0x2
 #define SYSCTL_FLAG_SACK       0x4
 
-               /* If congestion control is doing timestamping */
-               if (icsk->icsk_ca_ops->rtt_sample)
-                       __net_timestamp(skb);
-
                sysctl_flags = 0;
                if (tcb->flags & TCPCB_FLAG_SYN) {
                        tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS;
@@ -982,6 +977,7 @@ static int tcp_tso_should_defer(struct s
 static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int
nonagle)
 {
        struct tcp_sock *tp = tcp_sk(sk);
+       struct inet_connection_sock *icsk = inet_csk(sk);
        struct sk_buff *skb;
        unsigned int tso_segs, sent_pkts;
        int cwnd_quota;
@@ -1036,6 +1032,9 @@ static int tcp_write_xmit(struct sock *s
 
                TCP_SKB_CB(skb)->when = tcp_time_stamp;
 
+               if (icsk->icsk_ca_ops->rtt_sample)
+                       __net_timestamp(skb);
+
                if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))))
                        break;
 
@@ -1076,6 +1075,7 @@ void __tcp_push_pending_frames(struct so
 void tcp_push_one(struct sock *sk, unsigned int mss_now)
 {
        struct tcp_sock *tp = tcp_sk(sk);
+       const struct inet_connection_sock *icsk = inet_csk(sk);
        struct sk_buff *skb = sk->sk_send_head;
        unsigned int tso_segs, cwnd_quota;
 
@@ -1109,6 +1109,9 @@ void tcp_push_one(struct sock *sk, unsig
                /* Send it out now. */
                TCP_SKB_CB(skb)->when = tcp_time_stamp;
 
+               if (icsk->icsk_ca_ops->rtt_sample)
+                       __net_timestamp(skb);
+
                if (likely(!tcp_transmit_skb(sk, skb_clone(skb, 
sk->sk_allocation))))
{
                        update_send_head(sk, tp, skb);
                        tcp_cwnd_validate(sk, tp);
@@ -1364,6 +1367,7 @@ void tcp_simple_retransmit(struct sock *
 int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 {
        struct tcp_sock *tp = tcp_sk(sk);
+       struct inet_connection_sock *icsk = inet_csk(sk);
        unsigned int cur_mss = tcp_current_mss(sk, 0);
        int err;
 
@@ -1429,6 +1433,9 @@ int tcp_retransmit_skb(struct sock *sk, 
         */
        TCP_SKB_CB(skb)->when = tcp_time_stamp;
 
+       if (icsk->icsk_ca_ops->rtt_sample)
+               __net_timestamp(skb);
+
        err = tcp_transmit_skb(sk, (skb_cloned(skb) ?
                                    pskb_copy(skb, GFP_ATOMIC):
                                    skb_clone(skb, GFP_ATOMIC)));
@@ -1677,6 +1684,7 @@ void tcp_send_active_reset(struct sock *
 int tcp_send_synack(struct sock *sk)
 {
        struct sk_buff* skb;
+       struct inet_connection_sock *icsk = inet_csk(sk);
 
        skb = skb_peek(&sk->sk_write_queue);
        if (skb == NULL || !(TCP_SKB_CB(skb)->flags&TCPCB_FLAG_SYN)) {
@@ -1700,6 +1708,8 @@ int tcp_send_synack(struct sock *sk)
                TCP_ECN_send_synack(tcp_sk(sk), skb);
        }
        TCP_SKB_CB(skb)->when = tcp_time_stamp;
+       if (icsk->icsk_ca_ops->rtt_sample)
+               __net_timestamp(skb);
        return tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
 }
 
@@ -1832,6 +1842,7 @@ static inline void tcp_connect_init(stru
 int tcp_connect(struct sock *sk)
 {
        struct tcp_sock *tp = tcp_sk(sk);
+       struct inet_connection_sock *icsk = inet_csk(sk);
        struct sk_buff *buff;
 
        tcp_connect_init(sk);
@@ -1856,6 +1867,8 @@ int tcp_connect(struct sock *sk)
 
        /* Send it off. */
        TCP_SKB_CB(buff)->when = tcp_time_stamp;
+       if (icsk->icsk_ca_ops->rtt_sample)
+               __net_timestamp(buff);
        tp->retrans_stamp = TCP_SKB_CB(buff)->when;
        skb_header_release(buff);
        __skb_queue_tail(&sk->sk_write_queue, buff);
@@ -2004,6 +2017,7 @@ int tcp_write_wakeup(struct sock *sk)
 {
        if (sk->sk_state != TCP_CLOSE) {
                struct tcp_sock *tp = tcp_sk(sk);
+               struct inet_connection_sock *icsk = inet_csk(sk);
                struct sk_buff *skb;
 
                if ((skb = sk->sk_send_head) != NULL &&
@@ -2030,6 +2044,8 @@ int tcp_write_wakeup(struct sock *sk)
 
                        TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
                        TCP_SKB_CB(skb)->when = tcp_time_stamp;
+                       if (icsk->icsk_ca_ops->rtt_sample)
+                               __net_timestamp(skb);
                        err = tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
                        if (!err) {
                                update_send_head(sk, tp, skb);


-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to