|
@@ -5876,20 +5876,22 @@ static inline void pr_drop_req(struct request_sock *req, __u16 port, int family)
|
|
*/
|
|
*/
|
|
static void tcp_ecn_create_request(struct request_sock *req,
|
|
static void tcp_ecn_create_request(struct request_sock *req,
|
|
const struct sk_buff *skb,
|
|
const struct sk_buff *skb,
|
|
- const struct sock *listen_sk)
|
|
|
|
|
|
+ const struct sock *listen_sk,
|
|
|
|
+ const struct dst_entry *dst)
|
|
{
|
|
{
|
|
const struct tcphdr *th = tcp_hdr(skb);
|
|
const struct tcphdr *th = tcp_hdr(skb);
|
|
const struct net *net = sock_net(listen_sk);
|
|
const struct net *net = sock_net(listen_sk);
|
|
bool th_ecn = th->ece && th->cwr;
|
|
bool th_ecn = th->ece && th->cwr;
|
|
- bool ect, need_ecn;
|
|
|
|
|
|
+ bool ect, need_ecn, ecn_ok;
|
|
|
|
|
|
if (!th_ecn)
|
|
if (!th_ecn)
|
|
return;
|
|
return;
|
|
|
|
|
|
ect = !INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield);
|
|
ect = !INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield);
|
|
need_ecn = tcp_ca_needs_ecn(listen_sk);
|
|
need_ecn = tcp_ca_needs_ecn(listen_sk);
|
|
|
|
+ ecn_ok = net->ipv4.sysctl_tcp_ecn || dst_feature(dst, RTAX_FEATURE_ECN);
|
|
|
|
|
|
- if (!ect && !need_ecn && net->ipv4.sysctl_tcp_ecn)
|
|
|
|
|
|
+ if (!ect && !need_ecn && ecn_ok)
|
|
inet_rsk(req)->ecn_ok = 1;
|
|
inet_rsk(req)->ecn_ok = 1;
|
|
else if (ect && need_ecn)
|
|
else if (ect && need_ecn)
|
|
inet_rsk(req)->ecn_ok = 1;
|
|
inet_rsk(req)->ecn_ok = 1;
|
|
@@ -5954,13 +5956,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
|
|
if (security_inet_conn_request(sk, skb, req))
|
|
if (security_inet_conn_request(sk, skb, req))
|
|
goto drop_and_free;
|
|
goto drop_and_free;
|
|
|
|
|
|
- if (!want_cookie || tmp_opt.tstamp_ok)
|
|
|
|
- tcp_ecn_create_request(req, skb, sk);
|
|
|
|
-
|
|
|
|
- if (want_cookie) {
|
|
|
|
- isn = cookie_init_sequence(af_ops, sk, skb, &req->mss);
|
|
|
|
- req->cookie_ts = tmp_opt.tstamp_ok;
|
|
|
|
- } else if (!isn) {
|
|
|
|
|
|
+ if (!want_cookie && !isn) {
|
|
/* VJ's idea. We save last timestamp seen
|
|
/* VJ's idea. We save last timestamp seen
|
|
* from the destination in peer table, when entering
|
|
* from the destination in peer table, when entering
|
|
* state TIME-WAIT, and check against it before
|
|
* state TIME-WAIT, and check against it before
|
|
@@ -6008,6 +6004,15 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
|
|
goto drop_and_free;
|
|
goto drop_and_free;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ tcp_ecn_create_request(req, skb, sk, dst);
|
|
|
|
+
|
|
|
|
+ if (want_cookie) {
|
|
|
|
+ isn = cookie_init_sequence(af_ops, sk, skb, &req->mss);
|
|
|
|
+ req->cookie_ts = tmp_opt.tstamp_ok;
|
|
|
|
+ if (!tmp_opt.tstamp_ok)
|
|
|
|
+ inet_rsk(req)->ecn_ok = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
tcp_rsk(req)->snt_isn = isn;
|
|
tcp_rsk(req)->snt_isn = isn;
|
|
tcp_openreq_init_rwin(req, sk, dst);
|
|
tcp_openreq_init_rwin(req, sk, dst);
|
|
fastopen = !want_cookie &&
|
|
fastopen = !want_cookie &&
|