__u16 *mss);
 
 extern __u32 cookie_init_timestamp(struct request_sock *req);
-extern bool cookie_check_timestamp(struct tcp_options_received *tcp_opt);
+extern bool cookie_check_timestamp(struct tcp_options_received *opt, bool *);
 
 /* From net/ipv6/syncookies.c */
 extern struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb);
 
 #include <net/route.h>
 
 /* Timestamps: lowest bits store TCP options */
-#define TSBITS 5
+#define TSBITS 6
 #define TSMASK (((__u32)1 << TSBITS) - 1)
 
 extern int sysctl_tcp_syncookies;
 
        options = ireq->wscale_ok ? ireq->snd_wscale : 0xf;
        options |= ireq->sack_ok << 4;
+       options |= ireq->ecn_ok << 5;
 
        ts = ts_now & ~TSMASK;
        ts |= options;
  * This extracts these options from the timestamp echo.
  *
  * The lowest 4 bits store snd_wscale.
- * The next lsb is for sack_ok
+ * next 2 bits indicate SACK and ECN support.
  *
  * return false if we decode an option that should not be.
  */
-bool cookie_check_timestamp(struct tcp_options_received *tcp_opt)
+bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, bool *ecn_ok)
 {
        /* echoed timestamp, lowest bits contain options */
        u32 options = tcp_opt->rcv_tsecr & TSMASK;
                return false;
 
        tcp_opt->sack_ok = (options >> 4) & 0x1;
+       *ecn_ok = (options >> 5) & 1;
+       if (*ecn_ok && !sysctl_tcp_ecn)
+               return false;
 
        if (tcp_opt->sack_ok && !sysctl_tcp_sack)
                return false;
        int mss;
        struct rtable *rt;
        __u8 rcv_wscale;
+       bool ecn_ok;
 
        if (!sysctl_tcp_syncookies || !th->ack || th->rst)
                goto out;
        memset(&tcp_opt, 0, sizeof(tcp_opt));
        tcp_parse_options(skb, &tcp_opt, &hash_location, 0);
 
-       if (!cookie_check_timestamp(&tcp_opt))
+       if (!cookie_check_timestamp(&tcp_opt, &ecn_ok))
                goto out;
 
        ret = NULL;
        ireq->rmt_port          = th->source;
        ireq->loc_addr          = ip_hdr(skb)->daddr;
        ireq->rmt_addr          = ip_hdr(skb)->saddr;
-       ireq->ecn_ok            = 0;
+       ireq->ecn_ok            = ecn_ok;
        ireq->snd_wscale        = tcp_opt.snd_wscale;
        ireq->sack_ok           = tcp_opt.sack_ok;
        ireq->wscale_ok         = tcp_opt.wscale_ok;
 
        if (security_inet_conn_request(sk, skb, req))
                goto drop_and_free;
 
-       if (!want_cookie)
+       if (!want_cookie || tmp_opt.tstamp_ok)
                TCP_ECN_create_request(req, tcp_hdr(skb));
 
        if (want_cookie) {
-#ifdef CONFIG_SYN_COOKIES
-               req->cookie_ts = tmp_opt.tstamp_ok;
-#endif
                isn = cookie_v4_init_sequence(sk, skb, &req->mss);
+               req->cookie_ts = tmp_opt.tstamp_ok;
        } else if (!isn) {
                struct inet_peer *peer = NULL;
 
 
        int mss;
        struct dst_entry *dst;
        __u8 rcv_wscale;
+       bool ecn_ok;
 
        if (!sysctl_tcp_syncookies || !th->ack || th->rst)
                goto out;
        memset(&tcp_opt, 0, sizeof(tcp_opt));
        tcp_parse_options(skb, &tcp_opt, &hash_location, 0);
 
-       if (!cookie_check_timestamp(&tcp_opt))
+       if (!cookie_check_timestamp(&tcp_opt, &ecn_ok))
                goto out;
 
        ret = NULL;
 
        req->expires = 0UL;
        req->retrans = 0;
-       ireq->ecn_ok            = 0;
+       ireq->ecn_ok            = ecn_ok;
        ireq->snd_wscale        = tcp_opt.snd_wscale;
        ireq->sack_ok           = tcp_opt.sack_ok;
        ireq->wscale_ok         = tcp_opt.wscale_ok;