#define RTAX_MAX (__RTAX_MAX - 1)
 
 #define RTAX_FEATURE_ECN       0x00000001
-#define RTAX_FEATURE_NO_SACK   0x00000002
-#define RTAX_FEATURE_NO_TSTAMP 0x00000004
+#define RTAX_FEATURE_SACK      0x00000002
+#define RTAX_FEATURE_TIMESTAMP 0x00000004
 #define RTAX_FEATURE_ALLFRAG   0x00000008
-#define RTAX_FEATURE_NO_WSCALE 0x00000010
-#define RTAX_FEATURE_NO_DSACK  0x00000020
 
 struct rta_session {
        __u8    proto;
 
 static inline u32
 dst_feature(const struct dst_entry *dst, u32 feature)
 {
-       return (dst ? dst_metric(dst, RTAX_FEATURES) & feature : 0);
+       return dst_metric(dst, RTAX_FEATURES) & feature;
 }
 
 static inline u32 dst_mtu(const struct dst_entry *dst)
 
 extern void                    tcp_parse_options(struct sk_buff *skb,
                                                  struct tcp_options_received *opt_rx,
                                                  u8 **hvpp,
-                                                 int estab,
-                                                 struct dst_entry *dst);
+                                                 int estab);
 
 extern u8                      *tcp_parse_md5sig_option(struct tcphdr *th);
 
 
 
        NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV);
 
+       /* check for timestamp cookie support */
+       memset(&tcp_opt, 0, sizeof(tcp_opt));
+       tcp_parse_options(skb, &tcp_opt, &hash_location, 0);
+
+       if (tcp_opt.saw_tstamp)
+               cookie_check_timestamp(&tcp_opt);
+
        ret = NULL;
        req = inet_reqsk_alloc(&tcp_request_sock_ops); /* for safety */
        if (!req)
        ireq->loc_addr          = ip_hdr(skb)->daddr;
        ireq->rmt_addr          = ip_hdr(skb)->saddr;
        ireq->ecn_ok            = 0;
+       ireq->snd_wscale        = tcp_opt.snd_wscale;
+       ireq->rcv_wscale        = tcp_opt.rcv_wscale;
+       ireq->sack_ok           = tcp_opt.sack_ok;
+       ireq->wscale_ok         = tcp_opt.wscale_ok;
+       ireq->tstamp_ok         = tcp_opt.saw_tstamp;
+       req->ts_recent          = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
 
        /* We throwed the options of the initial SYN away, so we hope
         * the ACK carries the same options again (see RFC1122 4.2.3.8)
                }
        }
 
-       /* check for timestamp cookie support */
-       memset(&tcp_opt, 0, sizeof(tcp_opt));
-       tcp_parse_options(skb, &tcp_opt, &hash_location, 0, &rt->u.dst);
-
-       if (tcp_opt.saw_tstamp)
-               cookie_check_timestamp(&tcp_opt);
-
-       ireq->snd_wscale        = tcp_opt.snd_wscale;
-       ireq->rcv_wscale        = tcp_opt.rcv_wscale;
-       ireq->sack_ok           = tcp_opt.sack_ok;
-       ireq->wscale_ok         = tcp_opt.wscale_ok;
-       ireq->tstamp_ok         = tcp_opt.saw_tstamp;
-       req->ts_recent          = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
-
        /* Try to redo what tcp_v4_send_synack did. */
        req->window_clamp = tp->window_clamp ? :dst_metric(&rt->u.dst, RTAX_WINDOW);
 
 
  * the fast version below fails.
  */
 void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
-                      u8 **hvpp, int estab,  struct dst_entry *dst)
+                      u8 **hvpp, int estab)
 {
        unsigned char *ptr;
        struct tcphdr *th = tcp_hdr(skb);
                                break;
                        case TCPOPT_WINDOW:
                                if (opsize == TCPOLEN_WINDOW && th->syn &&
-                                   !estab && sysctl_tcp_window_scaling &&
-                                   !dst_feature(dst, RTAX_FEATURE_NO_WSCALE)) {
+                                   !estab && sysctl_tcp_window_scaling) {
                                        __u8 snd_wscale = *(__u8 *)ptr;
                                        opt_rx->wscale_ok = 1;
                                        if (snd_wscale > 14) {
                        case TCPOPT_TIMESTAMP:
                                if ((opsize == TCPOLEN_TIMESTAMP) &&
                                    ((estab && opt_rx->tstamp_ok) ||
-                                    (!estab && sysctl_tcp_timestamps &&
-                                     !dst_feature(dst, RTAX_FEATURE_NO_TSTAMP)))) {
+                                    (!estab && sysctl_tcp_timestamps))) {
                                        opt_rx->saw_tstamp = 1;
                                        opt_rx->rcv_tsval = get_unaligned_be32(ptr);
                                        opt_rx->rcv_tsecr = get_unaligned_be32(ptr + 4);
                                break;
                        case TCPOPT_SACK_PERM:
                                if (opsize == TCPOLEN_SACK_PERM && th->syn &&
-                                   !estab && sysctl_tcp_sack &&
-                                   !dst_feature(dst, RTAX_FEATURE_NO_SACK)) {
+                                   !estab && sysctl_tcp_sack) {
                                        opt_rx->sack_ok = 1;
                                        tcp_sack_reset(opt_rx);
                                }
                if (tcp_parse_aligned_timestamp(tp, th))
                        return 1;
        }
-       tcp_parse_options(skb, &tp->rx_opt, hvpp, 1, NULL);
+       tcp_parse_options(skb, &tp->rx_opt, hvpp, 1);
        return 1;
 }
 
 static void tcp_dsack_set(struct sock *sk, u32 seq, u32 end_seq)
 {
        struct tcp_sock *tp = tcp_sk(sk);
-       struct dst_entry *dst = __sk_dst_get(sk);
 
-       if (tcp_is_sack(tp) && sysctl_tcp_dsack &&
-           !dst_feature(dst, RTAX_FEATURE_NO_DSACK)) {
+       if (tcp_is_sack(tp) && sysctl_tcp_dsack) {
                int mib_idx;
 
                if (before(seq, tp->rcv_nxt))
 static void tcp_send_dupack(struct sock *sk, struct sk_buff *skb)
 {
        struct tcp_sock *tp = tcp_sk(sk);
-       struct dst_entry *dst = __sk_dst_get(sk);
 
        if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq &&
            before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOST);
                tcp_enter_quickack_mode(sk);
 
-               if (tcp_is_sack(tp) && sysctl_tcp_dsack &&
-                   !dst_feature(dst, RTAX_FEATURE_NO_DSACK)) {
+               if (tcp_is_sack(tp) && sysctl_tcp_dsack) {
                        u32 end_seq = TCP_SKB_CB(skb)->end_seq;
 
                        if (after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt))
        u8 *hash_location;
        struct inet_connection_sock *icsk = inet_csk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
-       struct dst_entry *dst = __sk_dst_get(sk);
        struct tcp_cookie_values *cvp = tp->cookie_values;
        int saved_clamp = tp->rx_opt.mss_clamp;
 
-       tcp_parse_options(skb, &tp->rx_opt, &hash_location, 0, dst);
+       tcp_parse_options(skb, &tp->rx_opt, &hash_location, 0);
 
        if (th->ack) {
                /* rfc793:
 
        tcp_rsk(req)->af_specific = &tcp_request_sock_ipv4_ops;
 #endif
 
-       ireq = inet_rsk(req);
-       ireq->loc_addr = daddr;
-       ireq->rmt_addr = saddr;
-       ireq->no_srccheck = inet_sk(sk)->transparent;
-       ireq->opt = tcp_v4_save_options(sk, skb);
-
-       dst = inet_csk_route_req(sk, req);
-       if(!dst)
-               goto drop_and_free;
-
        tcp_clear_options(&tmp_opt);
        tmp_opt.mss_clamp = TCP_MSS_DEFAULT;
        tmp_opt.user_mss  = tp->rx_opt.user_mss;
-       tcp_parse_options(skb, &tmp_opt, &hash_location, 0, dst);
+       tcp_parse_options(skb, &tmp_opt, &hash_location, 0);
 
        if (tmp_opt.cookie_plus > 0 &&
            tmp_opt.saw_tstamp &&
        tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
        tcp_openreq_init(req, &tmp_opt, skb);
 
+       ireq = inet_rsk(req);
+       ireq->loc_addr = daddr;
+       ireq->rmt_addr = saddr;
+       ireq->no_srccheck = inet_sk(sk)->transparent;
+       ireq->opt = tcp_v4_save_options(sk, skb);
+
        if (security_inet_conn_request(sk, skb, req))
-               goto drop_and_release;
+               goto drop_and_free;
 
        if (!want_cookie)
                TCP_ECN_create_request(req, tcp_hdr(skb));
                 */
                if (tmp_opt.saw_tstamp &&
                    tcp_death_row.sysctl_tw_recycle &&
+                   (dst = inet_csk_route_req(sk, req)) != NULL &&
                    (peer = rt_get_peer((struct rtable *)dst)) != NULL &&
                    peer->v4daddr == saddr) {
                        if ((u32)get_seconds() - peer->tcp_ts_stamp < TCP_PAWS_MSL &&
 
        struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
        int paws_reject = 0;
 
+       tmp_opt.saw_tstamp = 0;
        if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) {
-               tmp_opt.tstamp_ok = 1;
-               tcp_parse_options(skb, &tmp_opt, &hash_location, 1, NULL);
+               tcp_parse_options(skb, &tmp_opt, &hash_location, 0);
 
                if (tmp_opt.saw_tstamp) {
                        tmp_opt.ts_recent       = tcptw->tw_ts_recent;
        __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK);
        int paws_reject = 0;
 
-       if ((th->doff > (sizeof(*th) >> 2)) && (req->ts_recent)) {
-               tmp_opt.tstamp_ok = 1;
-               tcp_parse_options(skb, &tmp_opt, &hash_location, 1, NULL);
+       tmp_opt.saw_tstamp = 0;
+       if (th->doff > (sizeof(struct tcphdr)>>2)) {
+               tcp_parse_options(skb, &tmp_opt, &hash_location, 0);
 
                if (tmp_opt.saw_tstamp) {
                        tmp_opt.ts_recent = req->ts_recent;
 
                                struct tcp_md5sig_key **md5) {
        struct tcp_sock *tp = tcp_sk(sk);
        struct tcp_cookie_values *cvp = tp->cookie_values;
-       struct dst_entry *dst = __sk_dst_get(sk);
        unsigned remaining = MAX_TCP_OPTION_SPACE;
        u8 cookie_size = (!tp->rx_opt.cookie_out_never && cvp != NULL) ?
                         tcp_cookie_size_check(cvp->cookie_desired) :
        opts->mss = tcp_advertise_mss(sk);
        remaining -= TCPOLEN_MSS_ALIGNED;
 
-       if (likely(sysctl_tcp_timestamps &&
-                  !dst_feature(dst, RTAX_FEATURE_NO_TSTAMP) &&
-                  *md5 == NULL)) {
+       if (likely(sysctl_tcp_timestamps && *md5 == NULL)) {
                opts->options |= OPTION_TS;
                opts->tsval = TCP_SKB_CB(skb)->when;
                opts->tsecr = tp->rx_opt.ts_recent;
                remaining -= TCPOLEN_TSTAMP_ALIGNED;
        }
-       if (likely(sysctl_tcp_window_scaling &&
-                  !dst_feature(dst, RTAX_FEATURE_NO_WSCALE))) {
+       if (likely(sysctl_tcp_window_scaling)) {
                opts->ws = tp->rx_opt.rcv_wscale;
                opts->options |= OPTION_WSCALE;
                remaining -= TCPOLEN_WSCALE_ALIGNED;
        }
-       if (likely(sysctl_tcp_sack &&
-                  !dst_feature(dst, RTAX_FEATURE_NO_SACK))) {
+       if (likely(sysctl_tcp_sack)) {
                opts->options |= OPTION_SACK_ADVERTISE;
                if (unlikely(!(OPTION_TS & opts->options)))
                        remaining -= TCPOLEN_SACKPERM_ALIGNED;
         * See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT.
         */
        tp->tcp_header_len = sizeof(struct tcphdr) +
-               (sysctl_tcp_timestamps &&
-               (!dst_feature(dst, RTAX_FEATURE_NO_TSTAMP) ?
-                 TCPOLEN_TSTAMP_ALIGNED : 0));
+               (sysctl_tcp_timestamps ? TCPOLEN_TSTAMP_ALIGNED : 0);
 
 #ifdef CONFIG_TCP_MD5SIG
        if (tp->af_specific->md5_lookup(sk, sk) != NULL)
                                  tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0),
                                  &tp->rcv_wnd,
                                  &tp->window_clamp,
-                                 (sysctl_tcp_window_scaling &&
-                                  !dst_feature(dst, RTAX_FEATURE_NO_WSCALE)),
+                                 sysctl_tcp_window_scaling,
                                  &rcv_wscale);
 
        tp->rx_opt.rcv_wscale = rcv_wscale;
 
 
        NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV);
 
+       /* check for timestamp cookie support */
+       memset(&tcp_opt, 0, sizeof(tcp_opt));
+       tcp_parse_options(skb, &tcp_opt, &hash_location, 0);
+
+       if (tcp_opt.saw_tstamp)
+               cookie_check_timestamp(&tcp_opt);
+
        ret = NULL;
        req = inet6_reqsk_alloc(&tcp6_request_sock_ops);
        if (!req)
        req->expires = 0UL;
        req->retrans = 0;
        ireq->ecn_ok            = 0;
+       ireq->snd_wscale        = tcp_opt.snd_wscale;
+       ireq->rcv_wscale        = tcp_opt.rcv_wscale;
+       ireq->sack_ok           = tcp_opt.sack_ok;
+       ireq->wscale_ok         = tcp_opt.wscale_ok;
+       ireq->tstamp_ok         = tcp_opt.saw_tstamp;
+       req->ts_recent          = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
        treq->rcv_isn = ntohl(th->seq) - 1;
        treq->snt_isn = cookie;
 
                        goto out_free;
        }
 
-       /* check for timestamp cookie support */
-       memset(&tcp_opt, 0, sizeof(tcp_opt));
-       tcp_parse_options(skb, &tcp_opt, &hash_location, 0, dst);
-
-       if (tcp_opt.saw_tstamp)
-               cookie_check_timestamp(&tcp_opt);
-
-       req->ts_recent          = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
-
-       ireq->snd_wscale        = tcp_opt.snd_wscale;
-       ireq->rcv_wscale        = tcp_opt.rcv_wscale;
-       ireq->sack_ok           = tcp_opt.sack_ok;
-       ireq->wscale_ok         = tcp_opt.wscale_ok;
-       ireq->tstamp_ok         = tcp_opt.saw_tstamp;
-
        req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
        tcp_select_initial_window(tcp_full_space(sk), req->mss,
                                  &req->rcv_wnd, &req->window_clamp,
 
        struct inet6_request_sock *treq;
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
-       struct dst_entry *dst = __sk_dst_get(sk);
        __u32 isn = TCP_SKB_CB(skb)->when;
 #ifdef CONFIG_SYN_COOKIES
        int want_cookie = 0;
        tcp_clear_options(&tmp_opt);
        tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
        tmp_opt.user_mss = tp->rx_opt.user_mss;
-       tcp_parse_options(skb, &tmp_opt, &hash_location, 0, dst);
+       tcp_parse_options(skb, &tmp_opt, &hash_location, 0);
 
        if (tmp_opt.cookie_plus > 0 &&
            tmp_opt.saw_tstamp &&