|
@@ -357,14 +357,10 @@ static void tcp_ecn_clear_syn(struct sock *sk, struct sk_buff *skb)
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-tcp_ecn_make_synack(const struct request_sock *req, struct tcphdr *th,
|
|
|
- struct sock *sk)
|
|
|
+tcp_ecn_make_synack(const struct request_sock *req, struct tcphdr *th)
|
|
|
{
|
|
|
- if (inet_rsk(req)->ecn_ok) {
|
|
|
+ if (inet_rsk(req)->ecn_ok)
|
|
|
th->ece = 1;
|
|
|
- if (tcp_ca_needs_ecn(sk))
|
|
|
- INET_ECN_xmit(sk);
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
/* Set up ECN state for a packet on a ESTABLISHED socket that is about to
|
|
@@ -612,12 +608,11 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb,
|
|
|
}
|
|
|
|
|
|
/* Set up TCP options for SYN-ACKs. */
|
|
|
-static unsigned int tcp_synack_options(struct sock *sk,
|
|
|
- struct request_sock *req,
|
|
|
- unsigned int mss, struct sk_buff *skb,
|
|
|
- struct tcp_out_options *opts,
|
|
|
- const struct tcp_md5sig_key *md5,
|
|
|
- struct tcp_fastopen_cookie *foc)
|
|
|
+static unsigned int tcp_synack_options(struct request_sock *req,
|
|
|
+ unsigned int mss, struct sk_buff *skb,
|
|
|
+ struct tcp_out_options *opts,
|
|
|
+ const struct tcp_md5sig_key *md5,
|
|
|
+ struct tcp_fastopen_cookie *foc)
|
|
|
{
|
|
|
struct inet_request_sock *ireq = inet_rsk(req);
|
|
|
unsigned int remaining = MAX_TCP_OPTION_SPACE;
|
|
@@ -2949,20 +2944,25 @@ int tcp_send_synack(struct sock *sk)
|
|
|
* 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 sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
|
|
|
struct request_sock *req,
|
|
|
struct tcp_fastopen_cookie *foc)
|
|
|
{
|
|
|
- struct tcp_out_options opts;
|
|
|
struct inet_request_sock *ireq = inet_rsk(req);
|
|
|
- struct tcp_sock *tp = tcp_sk(sk);
|
|
|
- struct tcphdr *th;
|
|
|
- struct sk_buff *skb;
|
|
|
+ const struct tcp_sock *tp = tcp_sk(sk);
|
|
|
struct tcp_md5sig_key *md5 = NULL;
|
|
|
+ struct tcp_out_options opts;
|
|
|
+ struct sk_buff *skb;
|
|
|
int tcp_header_size;
|
|
|
+ struct tcphdr *th;
|
|
|
+ u16 user_mss;
|
|
|
int mss;
|
|
|
|
|
|
- skb = sock_wmalloc(sk, MAX_TCP_HEADER, 1, GFP_ATOMIC);
|
|
|
+ /* sk is a const pointer, because we want to express multiple cpus
|
|
|
+ * might call us concurrently.
|
|
|
+ * sock_wmalloc() will change sk->sk_wmem_alloc in an atomic way.
|
|
|
+ */
|
|
|
+ skb = sock_wmalloc((struct sock *)sk, MAX_TCP_HEADER, 1, GFP_ATOMIC);
|
|
|
if (unlikely(!skb)) {
|
|
|
dst_release(dst);
|
|
|
return NULL;
|
|
@@ -2973,8 +2973,9 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
|
|
|
skb_dst_set(skb, dst);
|
|
|
|
|
|
mss = dst_metric_advmss(dst);
|
|
|
- if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)
|
|
|
- mss = tp->rx_opt.user_mss;
|
|
|
+ user_mss = READ_ONCE(tp->rx_opt.user_mss);
|
|
|
+ if (user_mss && user_mss < mss)
|
|
|
+ mss = user_mss;
|
|
|
|
|
|
memset(&opts, 0, sizeof(opts));
|
|
|
#ifdef CONFIG_SYN_COOKIES
|
|
@@ -2989,8 +2990,8 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
|
|
|
md5 = tcp_rsk(req)->af_specific->req_md5_lookup(sk, req_to_sk(req));
|
|
|
#endif
|
|
|
skb_set_hash(skb, tcp_rsk(req)->txhash, PKT_HASH_TYPE_L4);
|
|
|
- tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, md5,
|
|
|
- foc) + sizeof(*th);
|
|
|
+ tcp_header_size = tcp_synack_options(req, mss, skb, &opts, md5, foc) +
|
|
|
+ sizeof(*th);
|
|
|
|
|
|
skb_push(skb, tcp_header_size);
|
|
|
skb_reset_transport_header(skb);
|
|
@@ -2999,7 +3000,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
|
|
|
memset(th, 0, sizeof(struct tcphdr));
|
|
|
th->syn = 1;
|
|
|
th->ack = 1;
|
|
|
- tcp_ecn_make_synack(req, th, sk);
|
|
|
+ tcp_ecn_make_synack(req, th);
|
|
|
th->source = htons(ireq->ir_num);
|
|
|
th->dest = ireq->ir_rmt_port;
|
|
|
/* Setting of flags are superfluous here for callers (and ECE is
|
|
@@ -3014,7 +3015,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
|
|
|
|
|
|
/* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */
|
|
|
th->window = htons(min(req->rcv_wnd, 65535U));
|
|
|
- tcp_options_write((__be32 *)(th + 1), tp, &opts);
|
|
|
+ tcp_options_write((__be32 *)(th + 1), NULL, &opts);
|
|
|
th->doff = (tcp_header_size >> 2);
|
|
|
TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_OUTSEGS);
|
|
|
|
|
@@ -3501,7 +3502,7 @@ void tcp_send_probe0(struct sock *sk)
|
|
|
TCP_RTO_MAX);
|
|
|
}
|
|
|
|
|
|
-int tcp_rtx_synack(struct sock *sk, struct request_sock *req)
|
|
|
+int tcp_rtx_synack(const struct sock *sk, struct request_sock *req)
|
|
|
{
|
|
|
const struct tcp_request_sock_ops *af_ops = tcp_rsk(req)->af_specific;
|
|
|
struct flowi fl;
|