fec: Remove unneeded asm header files
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / ipv4 / tcp_output.c
index 817fbb396bc80077e23b03358355aca6ece6deba..d12694353540547f63a207f8176f1e8d6fb485c2 100644 (file)
@@ -65,27 +65,22 @@ int sysctl_tcp_base_mss __read_mostly = TCP_BASE_MSS;
 /* By default, RFC2861 behavior.  */
 int sysctl_tcp_slow_start_after_idle __read_mostly = 1;
 
-int sysctl_tcp_cookie_size __read_mostly = 0; /* TCP_COOKIE_MAX */
-EXPORT_SYMBOL_GPL(sysctl_tcp_cookie_size);
-
 static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
                           int push_one, gfp_t gfp);
 
 /* Account for new data that has been sent to the network. */
 static void tcp_event_new_data_sent(struct sock *sk, const struct sk_buff *skb)
 {
+       struct inet_connection_sock *icsk = inet_csk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
        unsigned int prior_packets = tp->packets_out;
 
        tcp_advance_send_head(sk, skb);
        tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
 
-       /* Don't override Nagle indefinitely with F-RTO */
-       if (tp->frto_counter == 2)
-               tp->frto_counter = 3;
-
        tp->packets_out += tcp_skb_pcount(skb);
-       if (!prior_packets || tp->early_retrans_delayed)
+       if (!prior_packets || icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
+           icsk->icsk_pending == ICSK_TIME_LOSS_PROBE)
                tcp_rearm_rto(sk);
 }
 
@@ -384,7 +379,6 @@ static inline bool tcp_urg_mode(const struct tcp_sock *tp)
 #define OPTION_TS              (1 << 1)
 #define OPTION_MD5             (1 << 2)
 #define OPTION_WSCALE          (1 << 3)
-#define OPTION_COOKIE_EXTENSION        (1 << 4)
 #define OPTION_FAST_OPEN_COOKIE        (1 << 8)
 
 struct tcp_out_options {
@@ -398,36 +392,6 @@ struct tcp_out_options {
        struct tcp_fastopen_cookie *fastopen_cookie;    /* Fast open cookie */
 };
 
-/* The sysctl int routines are generic, so check consistency here.
- */
-static u8 tcp_cookie_size_check(u8 desired)
-{
-       int cookie_size;
-
-       if (desired > 0)
-               /* previously specified */
-               return desired;
-
-       cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size);
-       if (cookie_size <= 0)
-               /* no default specified */
-               return 0;
-
-       if (cookie_size <= TCP_COOKIE_MIN)
-               /* value too small, specify minimum */
-               return TCP_COOKIE_MIN;
-
-       if (cookie_size >= TCP_COOKIE_MAX)
-               /* value too large, specify maximum */
-               return TCP_COOKIE_MAX;
-
-       if (cookie_size & 1)
-               /* 8-bit multiple, illegal, fix it */
-               cookie_size++;
-
-       return (u8)cookie_size;
-}
-
 /* Write previously computed TCP options to the packet.
  *
  * Beware: Something in the Internet is very sensitive to the ordering of
@@ -446,27 +410,9 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
 {
        u16 options = opts->options;    /* mungable copy */
 
-       /* Having both authentication and cookies for security is redundant,
-        * and there's certainly not enough room.  Instead, the cookie-less
-        * extension variant is proposed.
-        *
-        * Consider the pessimal case with authentication.  The options
-        * could look like:
-        *   COOKIE|MD5(20) + MSS(4) + SACK|TS(12) + WSCALE(4) == 40
-        */
        if (unlikely(OPTION_MD5 & options)) {
-               if (unlikely(OPTION_COOKIE_EXTENSION & options)) {
-                       *ptr++ = htonl((TCPOPT_COOKIE << 24) |
-                                      (TCPOLEN_COOKIE_BASE << 16) |
-                                      (TCPOPT_MD5SIG << 8) |
-                                      TCPOLEN_MD5SIG);
-               } else {
-                       *ptr++ = htonl((TCPOPT_NOP << 24) |
-                                      (TCPOPT_NOP << 16) |
-                                      (TCPOPT_MD5SIG << 8) |
-                                      TCPOLEN_MD5SIG);
-               }
-               options &= ~OPTION_COOKIE_EXTENSION;
+               *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+                              (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
                /* overload cookie hash location */
                opts->hash_location = (__u8 *)ptr;
                ptr += 4;
@@ -495,44 +441,6 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
                *ptr++ = htonl(opts->tsecr);
        }
 
-       /* Specification requires after timestamp, so do it now.
-        *
-        * Consider the pessimal case without authentication.  The options
-        * could look like:
-        *   MSS(4) + SACK|TS(12) + COOKIE(20) + WSCALE(4) == 40
-        */
-       if (unlikely(OPTION_COOKIE_EXTENSION & options)) {
-               __u8 *cookie_copy = opts->hash_location;
-               u8 cookie_size = opts->hash_size;
-
-               /* 8-bit multiple handled in tcp_cookie_size_check() above,
-                * and elsewhere.
-                */
-               if (0x2 & cookie_size) {
-                       __u8 *p = (__u8 *)ptr;
-
-                       /* 16-bit multiple */
-                       *p++ = TCPOPT_COOKIE;
-                       *p++ = TCPOLEN_COOKIE_BASE + cookie_size;
-                       *p++ = *cookie_copy++;
-                       *p++ = *cookie_copy++;
-                       ptr++;
-                       cookie_size -= 2;
-               } else {
-                       /* 32-bit multiple */
-                       *ptr++ = htonl(((TCPOPT_NOP << 24) |
-                                       (TCPOPT_NOP << 16) |
-                                       (TCPOPT_COOKIE << 8) |
-                                       TCPOLEN_COOKIE_BASE) +
-                                      cookie_size);
-               }
-
-               if (cookie_size > 0) {
-                       memcpy(ptr, cookie_copy, cookie_size);
-                       ptr += (cookie_size / 4);
-               }
-       }
-
        if (unlikely(OPTION_SACK_ADVERTISE & options)) {
                *ptr++ = htonl((TCPOPT_NOP << 24) |
                               (TCPOPT_NOP << 16) |
@@ -591,11 +499,7 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb,
                                struct tcp_md5sig_key **md5)
 {
        struct tcp_sock *tp = tcp_sk(sk);
-       struct tcp_cookie_values *cvp = tp->cookie_values;
        unsigned int remaining = MAX_TCP_OPTION_SPACE;
-       u8 cookie_size = (!tp->rx_opt.cookie_out_never && cvp != NULL) ?
-                        tcp_cookie_size_check(cvp->cookie_desired) :
-                        0;
        struct tcp_fastopen_request *fastopen = tp->fastopen_req;
 
 #ifdef CONFIG_TCP_MD5SIG
@@ -647,52 +551,7 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb,
                        tp->syn_fastopen = 1;
                }
        }
-       /* Note that timestamps are required by the specification.
-        *
-        * Odd numbers of bytes are prohibited by the specification, ensuring
-        * that the cookie is 16-bit aligned, and the resulting cookie pair is
-        * 32-bit aligned.
-        */
-       if (*md5 == NULL &&
-           (OPTION_TS & opts->options) &&
-           cookie_size > 0) {
-               int need = TCPOLEN_COOKIE_BASE + cookie_size;
-
-               if (0x2 & need) {
-                       /* 32-bit multiple */
-                       need += 2; /* NOPs */
-
-                       if (need > remaining) {
-                               /* try shrinking cookie to fit */
-                               cookie_size -= 2;
-                               need -= 4;
-                       }
-               }
-               while (need > remaining && TCP_COOKIE_MIN <= cookie_size) {
-                       cookie_size -= 4;
-                       need -= 4;
-               }
-               if (TCP_COOKIE_MIN <= cookie_size) {
-                       opts->options |= OPTION_COOKIE_EXTENSION;
-                       opts->hash_location = (__u8 *)&cvp->cookie_pair[0];
-                       opts->hash_size = cookie_size;
-
-                       /* Remember for future incarnations. */
-                       cvp->cookie_desired = cookie_size;
-
-                       if (cvp->cookie_desired != cvp->cookie_pair_size) {
-                               /* Currently use random bytes as a nonce,
-                                * assuming these are completely unpredictable
-                                * by hostile users of the same system.
-                                */
-                               get_random_bytes(&cvp->cookie_pair[0],
-                                                cookie_size);
-                               cvp->cookie_pair_size = cookie_size;
-                       }
 
-                       remaining -= need;
-               }
-       }
        return MAX_TCP_OPTION_SPACE - remaining;
 }
 
@@ -702,14 +561,10 @@ static unsigned int tcp_synack_options(struct sock *sk,
                                   unsigned int mss, struct sk_buff *skb,
                                   struct tcp_out_options *opts,
                                   struct tcp_md5sig_key **md5,
-                                  struct tcp_extend_values *xvp,
                                   struct tcp_fastopen_cookie *foc)
 {
        struct inet_request_sock *ireq = inet_rsk(req);
        unsigned int remaining = MAX_TCP_OPTION_SPACE;
-       u8 cookie_plus = (xvp != NULL && !xvp->cookie_out_never) ?
-                        xvp->cookie_plus :
-                        0;
 
 #ifdef CONFIG_TCP_MD5SIG
        *md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req);
@@ -757,28 +612,7 @@ static unsigned int tcp_synack_options(struct sock *sk,
                        remaining -= need;
                }
        }
-       /* Similar rationale to tcp_syn_options() applies here, too.
-        * If the <SYN> options fit, the same options should fit now!
-        */
-       if (*md5 == NULL &&
-           ireq->tstamp_ok &&
-           cookie_plus > TCPOLEN_COOKIE_BASE) {
-               int need = cookie_plus; /* has TCPOLEN_COOKIE_BASE */
-
-               if (0x2 & need) {
-                       /* 32-bit multiple */
-                       need += 2; /* NOPs */
-               }
-               if (need <= remaining) {
-                       opts->options |= OPTION_COOKIE_EXTENSION;
-                       opts->hash_size = cookie_plus - TCPOLEN_COOKIE_BASE;
-                       remaining -= need;
-               } else {
-                       /* There's no error return, so flag it. */
-                       xvp->cookie_out_never = 1; /* true */
-                       opts->hash_size = 0;
-               }
-       }
+
        return MAX_TCP_OPTION_SPACE - remaining;
 }
 
@@ -953,7 +787,7 @@ void __init tcp_tasklet_init(void)
  * We cant xmit new skbs from this context, as we might already
  * hold qdisc lock.
  */
-static void tcp_wfree(struct sk_buff *skb)
+void tcp_wfree(struct sk_buff *skb)
 {
        struct sock *sk = skb->sk;
        struct tcp_sock *tp = tcp_sk(sk);
@@ -1632,11 +1466,8 @@ static inline bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buf
        if (nonagle & TCP_NAGLE_PUSH)
                return true;
 
-       /* Don't use the nagle rule for urgent data (or for the final FIN).
-        * Nagle can be ignored during F-RTO too (see RFC4138).
-        */
-       if (tcp_urg_mode(tp) || (tp->frto_counter == 2) ||
-           (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN))
+       /* Don't use the nagle rule for urgent data (or for the final FIN). */
+       if (tcp_urg_mode(tp) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN))
                return true;
 
        if (!tcp_nagle_check(tp, skb, cur_mss, nonagle))
@@ -1809,8 +1640,11 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
                        goto send_now;
        }
 
-       /* Ok, it looks like it is advisable to defer.  */
-       tp->tso_deferred = 1 | (jiffies << 1);
+       /* Ok, it looks like it is advisable to defer.
+        * Do not rearm the timer if already set to not break TCP ACK clocking.
+        */
+       if (!tp->tso_deferred)
+               tp->tso_deferred = 1 | (jiffies << 1);
 
        return true;
 
@@ -1958,6 +1792,9 @@ static int tcp_mtu_probe(struct sock *sk)
  * snd_up-64k-mss .. snd_up cannot be large. However, taking into
  * account rare use of URG, this is not a big flaw.
  *
+ * Send at most one packet when push_one > 0. Temporarily ignore
+ * cwnd limit to force at most one packet out when push_one == 2.
+
  * Returns true, if no segments are in flight and we have queued segments,
  * but cannot send anything now because of SWS or another problem.
  */
@@ -1993,8 +1830,13 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
                        goto repair; /* Skip network transmission */
 
                cwnd_quota = tcp_cwnd_test(tp, skb);
-               if (!cwnd_quota)
-                       break;
+               if (!cwnd_quota) {
+                       if (push_one == 2)
+                               /* Force out a loss probe pkt. */
+                               cwnd_quota = 1;
+                       else
+                               break;
+               }
 
                if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now)))
                        break;
@@ -2048,10 +1890,129 @@ repair:
        if (likely(sent_pkts)) {
                if (tcp_in_cwnd_reduction(sk))
                        tp->prr_out += sent_pkts;
+
+               /* Send one loss probe per tail loss episode. */
+               if (push_one != 2)
+                       tcp_schedule_loss_probe(sk);
                tcp_cwnd_validate(sk);
                return false;
        }
-       return !tp->packets_out && tcp_send_head(sk);
+       return (push_one == 2) || (!tp->packets_out && tcp_send_head(sk));
+}
+
+bool tcp_schedule_loss_probe(struct sock *sk)
+{
+       struct inet_connection_sock *icsk = inet_csk(sk);
+       struct tcp_sock *tp = tcp_sk(sk);
+       u32 timeout, tlp_time_stamp, rto_time_stamp;
+       u32 rtt = tp->srtt >> 3;
+
+       if (WARN_ON(icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS))
+               return false;
+       /* No consecutive loss probes. */
+       if (WARN_ON(icsk->icsk_pending == ICSK_TIME_LOSS_PROBE)) {
+               tcp_rearm_rto(sk);
+               return false;
+       }
+       /* Don't do any loss probe on a Fast Open connection before 3WHS
+        * finishes.
+        */
+       if (sk->sk_state == TCP_SYN_RECV)
+               return false;
+
+       /* TLP is only scheduled when next timer event is RTO. */
+       if (icsk->icsk_pending != ICSK_TIME_RETRANS)
+               return false;
+
+       /* Schedule a loss probe in 2*RTT for SACK capable connections
+        * in Open state, that are either limited by cwnd or application.
+        */
+       if (sysctl_tcp_early_retrans < 3 || !rtt || !tp->packets_out ||
+           !tcp_is_sack(tp) || inet_csk(sk)->icsk_ca_state != TCP_CA_Open)
+               return false;
+
+       if ((tp->snd_cwnd > tcp_packets_in_flight(tp)) &&
+            tcp_send_head(sk))
+               return false;
+
+       /* Probe timeout is at least 1.5*rtt + TCP_DELACK_MAX to account
+        * for delayed ack when there's one outstanding packet.
+        */
+       timeout = rtt << 1;
+       if (tp->packets_out == 1)
+               timeout = max_t(u32, timeout,
+                               (rtt + (rtt >> 1) + TCP_DELACK_MAX));
+       timeout = max_t(u32, timeout, msecs_to_jiffies(10));
+
+       /* If RTO is shorter, just schedule TLP in its place. */
+       tlp_time_stamp = tcp_time_stamp + timeout;
+       rto_time_stamp = (u32)inet_csk(sk)->icsk_timeout;
+       if ((s32)(tlp_time_stamp - rto_time_stamp) > 0) {
+               s32 delta = rto_time_stamp - tcp_time_stamp;
+               if (delta > 0)
+                       timeout = delta;
+       }
+
+       inet_csk_reset_xmit_timer(sk, ICSK_TIME_LOSS_PROBE, timeout,
+                                 TCP_RTO_MAX);
+       return true;
+}
+
+/* When probe timeout (PTO) fires, send a new segment if one exists, else
+ * retransmit the last segment.
+ */
+void tcp_send_loss_probe(struct sock *sk)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct sk_buff *skb;
+       int pcount;
+       int mss = tcp_current_mss(sk);
+       int err = -1;
+
+       if (tcp_send_head(sk) != NULL) {
+               err = tcp_write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC);
+               goto rearm_timer;
+       }
+
+       /* At most one outstanding TLP retransmission. */
+       if (tp->tlp_high_seq)
+               goto rearm_timer;
+
+       /* Retransmit last segment. */
+       skb = tcp_write_queue_tail(sk);
+       if (WARN_ON(!skb))
+               goto rearm_timer;
+
+       pcount = tcp_skb_pcount(skb);
+       if (WARN_ON(!pcount))
+               goto rearm_timer;
+
+       if ((pcount > 1) && (skb->len > (pcount - 1) * mss)) {
+               if (unlikely(tcp_fragment(sk, skb, (pcount - 1) * mss, mss)))
+                       goto rearm_timer;
+               skb = tcp_write_queue_tail(sk);
+       }
+
+       if (WARN_ON(!skb || !tcp_skb_pcount(skb)))
+               goto rearm_timer;
+
+       /* Probe with zero data doesn't trigger fast recovery. */
+       if (skb->len > 0)
+               err = __tcp_retransmit_skb(sk, skb);
+
+       /* Record snd_nxt for loss detection. */
+       if (likely(!err))
+               tp->tlp_high_seq = tp->snd_nxt;
+
+rearm_timer:
+       inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
+                                 inet_csk(sk)->icsk_rto,
+                                 TCP_RTO_MAX);
+
+       if (likely(!err))
+               NET_INC_STATS_BH(sock_net(sk),
+                                LINUX_MIB_TCPLOSSPROBES);
+       return;
 }
 
 /* Push out any pending frames which were held back due to
@@ -2672,32 +2633,24 @@ int tcp_send_synack(struct sock *sk)
  * sk: listener socket
  * dst: dst entry attached to the SYNACK
  * req: request_sock pointer
- * rvp: request_values pointer
  *
  * Allocate one skb and build a SYNACK packet.
  * @dst is consumed : Caller should not use it again.
  */
 struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
                                struct request_sock *req,
-                               struct request_values *rvp,
                                struct tcp_fastopen_cookie *foc)
 {
        struct tcp_out_options opts;
-       struct tcp_extend_values *xvp = tcp_xv(rvp);
        struct inet_request_sock *ireq = inet_rsk(req);
        struct tcp_sock *tp = tcp_sk(sk);
-       const struct tcp_cookie_values *cvp = tp->cookie_values;
        struct tcphdr *th;
        struct sk_buff *skb;
        struct tcp_md5sig_key *md5;
        int tcp_header_size;
        int mss;
-       int s_data_desired = 0;
 
-       if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired)
-               s_data_desired = cvp->s_data_desired;
-       skb = alloc_skb(MAX_TCP_HEADER + 15 + s_data_desired,
-                       sk_gfp_atomic(sk, GFP_ATOMIC));
+       skb = alloc_skb(MAX_TCP_HEADER + 15, sk_gfp_atomic(sk, GFP_ATOMIC));
        if (unlikely(!skb)) {
                dst_release(dst);
                return NULL;
@@ -2739,9 +2692,8 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
        else
 #endif
        TCP_SKB_CB(skb)->when = tcp_time_stamp;
-       tcp_header_size = tcp_synack_options(sk, req, mss,
-                                            skb, &opts, &md5, xvp, foc)
-                       + sizeof(*th);
+       tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, &md5,
+                                            foc) + sizeof(*th);
 
        skb_push(skb, tcp_header_size);
        skb_reset_transport_header(skb);
@@ -2759,40 +2711,6 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
        tcp_init_nondata_skb(skb, tcp_rsk(req)->snt_isn,
                             TCPHDR_SYN | TCPHDR_ACK);
 
-       if (OPTION_COOKIE_EXTENSION & opts.options) {
-               if (s_data_desired) {
-                       u8 *buf = skb_put(skb, s_data_desired);
-
-                       /* copy data directly from the listening socket. */
-                       memcpy(buf, cvp->s_data_payload, s_data_desired);
-                       TCP_SKB_CB(skb)->end_seq += s_data_desired;
-               }
-
-               if (opts.hash_size > 0) {
-                       __u32 workspace[SHA_WORKSPACE_WORDS];
-                       u32 *mess = &xvp->cookie_bakery[COOKIE_DIGEST_WORDS];
-                       u32 *tail = &mess[COOKIE_MESSAGE_WORDS-1];
-
-                       /* Secret recipe depends on the Timestamp, (future)
-                        * Sequence and Acknowledgment Numbers, Initiator
-                        * Cookie, and others handled by IP variant caller.
-                        */
-                       *tail-- ^= opts.tsval;
-                       *tail-- ^= tcp_rsk(req)->rcv_isn + 1;
-                       *tail-- ^= TCP_SKB_CB(skb)->seq + 1;
-
-                       /* recommended */
-                       *tail-- ^= (((__force u32)th->dest << 16) | (__force u32)th->source);
-                       *tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */
-
-                       sha_transform((__u32 *)&xvp->cookie_bakery[0],
-                                     (char *)mess,
-                                     &workspace[0]);
-                       opts.hash_location =
-                               (__u8 *)&xvp->cookie_bakery[0];
-               }
-       }
-
        th->seq = htonl(TCP_SKB_CB(skb)->seq);
        /* XXX data is queued and acked as is. No buffer/window check */
        th->ack_seq = htonl(tcp_rsk(req)->rcv_nxt);