struct request_sock *req);
 };
 
+extern int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req);
+
 /* struct request_sock - mini sock to represent a connection request
  */
 struct request_sock {
        struct request_sock             *dl_next; /* Must be first member! */
        u16                             mss;
-       u8                              retrans;
-       u8                              cookie_ts; /* syncookie: encode tcpopts in timestamp */
+       u8                              num_retrans; /* number of retransmits */
+       u8                              cookie_ts:1; /* syncookie: encode tcpopts in timestamp */
+       u8                              num_timeout:7; /* number of timeouts */
        /* The following two fields can be easily recomputed I think -AK */
        u32                             window_clamp; /* window clamp at creation time */
        u32                             rcv_wnd;          /* rcv_wnd offered first time */
 {
        struct listen_sock *lopt = queue->listen_opt;
 
-       if (req->retrans == 0)
+       if (req->num_timeout == 0)
                --lopt->qlen_young;
 
        return --lopt->qlen;
        struct listen_sock *lopt = queue->listen_opt;
 
        req->expires = jiffies + timeout;
-       req->retrans = 0;
+       req->num_retrans = 0;
+       req->num_timeout = 0;
        req->sk = NULL;
        req->dl_next = lopt->syn_table[hash];
 
 
                         * To protect against Request floods, increment retrans
                         * counter (backoff, monitored by dccp_response_timer).
                         */
-                       req->retrans++;
-                       req->rsk_ops->rtx_syn_ack(sk, req, NULL);
+                       inet_rtx_syn_ack(sk, req);
                }
                /* Network Duplicate, discard packet */
                return NULL;
 
                                  int *expire, int *resend)
 {
        if (!rskq_defer_accept) {
-               *expire = req->retrans >= thresh;
+               *expire = req->num_timeout >= thresh;
                *resend = 1;
                return;
        }
-       *expire = req->retrans >= thresh &&
-                 (!inet_rsk(req)->acked || req->retrans >= max_retries);
+       *expire = req->num_timeout >= thresh &&
+                 (!inet_rsk(req)->acked || req->num_timeout >= max_retries);
        /*
         * Do not resend while waiting for data after ACK,
         * start to resend on end of deferring period to give
         * last chance for data or ACK to create established socket.
         */
        *resend = !inet_rsk(req)->acked ||
-                 req->retrans >= rskq_defer_accept - 1;
+                 req->num_timeout >= rskq_defer_accept - 1;
 }
 
+int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req)
+{
+       int err = req->rsk_ops->rtx_syn_ack(parent, req, NULL);
+
+       if (!err)
+               req->num_retrans++;
+       return err;
+}
+EXPORT_SYMBOL(inet_rtx_syn_ack);
+
 void inet_csk_reqsk_queue_prune(struct sock *parent,
                                const unsigned long interval,
                                const unsigned long timeout,
                                req->rsk_ops->syn_ack_timeout(parent, req);
                                if (!expire &&
                                    (!resend ||
-                                    !req->rsk_ops->rtx_syn_ack(parent, req, NULL) ||
+                                    !inet_rtx_syn_ack(parent, req) ||
                                     inet_rsk(req)->acked)) {
                                        unsigned long timeo;
 
-                                       if (req->retrans++ == 0)
+                                       if (req->num_timeout++ == 0)
                                                lopt->qlen_young--;
-                                       timeo = min((timeout << req->retrans), max_rto);
+                                       timeo = min(timeout << req->num_timeout,
+                                                   max_rto);
                                        req->expires = now + timeo;
                                        reqp = &req->dl_next;
                                        continue;
 
        r->idiag_family = sk->sk_family;
        r->idiag_state = TCP_SYN_RECV;
        r->idiag_timer = 1;
-       r->idiag_retrans = req->retrans;
+       r->idiag_retrans = req->num_retrans;
 
        r->id.idiag_if = sk->sk_bound_dev_if;
        sock_diag_save_cookie(req, r->id.idiag_cookie);
 
        }
 
        req->expires    = 0UL;
-       req->retrans    = 0;
+       req->num_retrans = 0;
 
        /*
         * We need to lookup the route here to get at the correct
 
                                 */
                                if (req) {
                                        tcp_synack_rtt_meas(sk, req);
-                                       tp->total_retrans = req->retrans;
+                                       tp->total_retrans = req->num_retrans;
 
                                        reqsk_fastopen_remove(sk, req, false);
                                } else {
 
 }
 
 static int tcp_v4_rtx_synack(struct sock *sk, struct request_sock *req,
-                             struct request_values *rvp)
+                            struct request_values *rvp)
 {
-       TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
-       return tcp_v4_send_synack(sk, NULL, req, rvp, 0, false);
+       int res = tcp_v4_send_synack(sk, NULL, req, rvp, 0, false);
+
+       if (!res)
+               TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
+       return res;
 }
 
 /*
        struct sock *child;
        int err;
 
-       req->retrans = 0;
+       req->num_retrans = 0;
+       req->num_timeout = 0;
        req->sk = NULL;
 
        child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL);
 
        tcp_initialize_rcv_mss(newsk);
        tcp_synack_rtt_meas(newsk, req);
-       newtp->total_retrans = req->retrans;
+       newtp->total_retrans = req->num_retrans;
 
 #ifdef CONFIG_TCP_MD5SIG
        /* Copy over the MD5 key from the original socket */
                0, 0, /* could print option size, but that is af dependent. */
                1,    /* timers active (only the expire timer) */
                jiffies_delta_to_clock_t(delta),
-               req->retrans,
+               req->num_timeout,
                from_kuid_munged(seq_user_ns(f), uid),
                0,  /* non standard timer */
                0, /* open_requests have no inode */
 
                         * it can be estimated (approximately)
                         * from another data.
                         */
-                       tmp_opt.ts_recent_stamp = get_seconds() - ((TCP_TIMEOUT_INIT/HZ)<<req->retrans);
+                       tmp_opt.ts_recent_stamp = get_seconds() - ((TCP_TIMEOUT_INIT/HZ)<<req->num_timeout);
                        paws_reject = tcp_paws_reject(&tmp_opt, th->rst);
                }
        }
                 * Note that even if there is new data in the SYN packet
                 * they will be thrown away too.
                 */
-               req->rsk_ops->rtx_syn_ack(sk, req, NULL);
+               inet_rtx_syn_ack(sk, req);
                return NULL;
        }
 
        /* Got ACK for our SYNACK, so update baseline for SYNACK RTT sample. */
        if (tmp_opt.saw_tstamp && tmp_opt.rcv_tsecr)
                tcp_rsk(req)->snt_synack = tmp_opt.rcv_tsecr;
-       else if (req->retrans) /* don't take RTT sample if retrans && ~TS */
+       else if (req->num_retrans) /* don't take RTT sample if retrans && ~TS */
                tcp_rsk(req)->snt_synack = 0;
 
        /* For Fast Open no more processing is needed (sk is the
                return sk;
 
        /* While TCP_DEFER_ACCEPT is active, drop bare ACK. */
-       if (req->retrans < inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
+       if (req->num_timeout < inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
            TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) {
                inet_rsk(req)->acked = 1;
                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPDEFERACCEPTDROP);
 
        req = tcp_sk(sk)->fastopen_rsk;
        req->rsk_ops->syn_ack_timeout(sk, req);
 
-       if (req->retrans >= max_retries) {
+       if (req->num_timeout >= max_retries) {
                tcp_write_err(sk);
                return;
        }
         * regular retransmit because if the child socket has been accepted
         * it's not good to give up too easily.
         */
-       req->rsk_ops->rtx_syn_ack(sk, req, NULL);
-       req->retrans++;
+       inet_rtx_syn_ack(sk, req);
+       req->num_timeout++;
        inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
-                         TCP_TIMEOUT_INIT << req->retrans, TCP_RTO_MAX);
+                         TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX);
 }
 
 /*
 
                ireq6->iif = inet6_iif(skb);
 
        req->expires = 0UL;
-       req->retrans = 0;
+       req->num_retrans = 0;
        ireq->ecn_ok            = ecn_ok;
        ireq->snd_wscale        = tcp_opt.snd_wscale;
        ireq->sack_ok           = tcp_opt.sack_ok;
 
                             struct request_values *rvp)
 {
        struct flowi6 fl6;
+       int res;
 
-       TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
-       return tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0);
+       res = tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0);
+       if (!res)
+               TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
+       return res;
 }
 
 static void tcp_v6_reqsk_destructor(struct request_sock *req)
 
        tcp_initialize_rcv_mss(newsk);
        tcp_synack_rtt_meas(newsk, req);
-       newtp->total_retrans = req->retrans;
+       newtp->total_retrans = req->num_retrans;
 
        newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
        newinet->inet_rcv_saddr = LOOPBACK4_IPV6;
                   0,0, /* could print option size, but that is af dependent. */
                   1,   /* timers active (only the expire timer) */
                   jiffies_to_clock_t(ttd),
-                  req->retrans,
+                  req->num_timeout,
                   from_kuid_munged(seq_user_ns(seq), uid),
                   0,  /* non standard timer */
                   0, /* open_requests have no inode */