Merge tag 'master-2014-09-08' of git://git.kernel.org/pub/scm/linux/kernel/git/linvil...
[pandora-kernel.git] / net / ipv4 / tcp_input.c
index a906e02..f97003a 100644 (file)
@@ -1888,21 +1888,21 @@ static inline void tcp_reset_reno_sack(struct tcp_sock *tp)
        tp->sacked_out = 0;
 }
 
-static void tcp_clear_retrans_partial(struct tcp_sock *tp)
+void tcp_clear_retrans(struct tcp_sock *tp)
 {
        tp->retrans_out = 0;
        tp->lost_out = 0;
-
        tp->undo_marker = 0;
        tp->undo_retrans = -1;
+       tp->fackets_out = 0;
+       tp->sacked_out = 0;
 }
 
-void tcp_clear_retrans(struct tcp_sock *tp)
+static inline void tcp_init_undo(struct tcp_sock *tp)
 {
-       tcp_clear_retrans_partial(tp);
-
-       tp->fackets_out = 0;
-       tp->sacked_out = 0;
+       tp->undo_marker = tp->snd_una;
+       /* Retransmission still in flight may cause DSACKs later. */
+       tp->undo_retrans = tp->retrans_out ? : -1;
 }
 
 /* Enter Loss state. If we detect SACK reneging, forget all SACK information
@@ -1925,18 +1925,18 @@ void tcp_enter_loss(struct sock *sk)
                tp->prior_ssthresh = tcp_current_ssthresh(sk);
                tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk);
                tcp_ca_event(sk, CA_EVENT_LOSS);
+               tcp_init_undo(tp);
        }
        tp->snd_cwnd       = 1;
        tp->snd_cwnd_cnt   = 0;
        tp->snd_cwnd_stamp = tcp_time_stamp;
 
-       tcp_clear_retrans_partial(tp);
+       tp->retrans_out = 0;
+       tp->lost_out = 0;
 
        if (tcp_is_reno(tp))
                tcp_reset_reno_sack(tp);
 
-       tp->undo_marker = tp->snd_una;
-
        skb = tcp_write_queue_head(sk);
        is_reneg = skb && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED);
        if (is_reneg) {
@@ -1950,9 +1950,6 @@ void tcp_enter_loss(struct sock *sk)
                if (skb == tcp_send_head(sk))
                        break;
 
-               if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)
-                       tp->undo_marker = 0;
-
                TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED;
                if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED) || is_reneg) {
                        TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED;
@@ -2671,8 +2668,7 @@ static void tcp_enter_recovery(struct sock *sk, bool ece_ack)
        NET_INC_STATS_BH(sock_net(sk), mib_idx);
 
        tp->prior_ssthresh = 0;
-       tp->undo_marker = tp->snd_una;
-       tp->undo_retrans = tp->retrans_out ? : -1;
+       tcp_init_undo(tp);
 
        if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) {
                if (!ece_ack)
@@ -2971,7 +2967,8 @@ void tcp_rearm_rto(struct sock *sk)
                if (icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
                    icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
                        struct sk_buff *skb = tcp_write_queue_head(sk);
-                       const u32 rto_time_stamp = TCP_SKB_CB(skb)->when + rto;
+                       const u32 rto_time_stamp =
+                               tcp_skb_timestamp(skb) + rto;
                        s32 delta = (s32)(rto_time_stamp - tcp_time_stamp);
                        /* delta may not be positive if the socket is locked
                         * when the retrans timer fires and is rescheduled.
@@ -5910,7 +5907,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
        struct request_sock *req;
        struct tcp_sock *tp = tcp_sk(sk);
        struct dst_entry *dst = NULL;
-       __u32 isn = TCP_SKB_CB(skb)->when;
+       __u32 isn = TCP_SKB_CB(skb)->tcp_tw_isn;
        bool want_cookie = false, fastopen;
        struct flowi fl;
        struct tcp_fastopen_cookie foc = { .len = -1 };