aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/tcp.h6
-rw-r--r--net/ipv4/inet_connection_sock.c2
-rw-r--r--net/ipv4/tcp_fastopen.c4
-rw-r--r--net/ipv4/tcp_input.c23
-rw-r--r--net/ipv4/tcp_ipv4.c5
-rw-r--r--net/ipv4/tcp_output.c22
-rw-r--r--net/ipv6/tcp_ipv6.c5
-rw-r--r--net/sched/sch_fq.c12
8 files changed, 47 insertions, 32 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 225e9561af35..a6be56d5f0e3 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -462,7 +462,8 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len);
462int tcp_connect(struct sock *sk); 462int tcp_connect(struct sock *sk);
463struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, 463struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
464 struct request_sock *req, 464 struct request_sock *req,
465 struct tcp_fastopen_cookie *foc); 465 struct tcp_fastopen_cookie *foc,
466 bool attach_req);
466int tcp_disconnect(struct sock *sk, int flags); 467int tcp_disconnect(struct sock *sk, int flags);
467 468
468void tcp_finish_connect(struct sock *sk, struct sk_buff *skb); 469void tcp_finish_connect(struct sock *sk, struct sk_buff *skb);
@@ -1715,7 +1716,8 @@ struct tcp_request_sock_ops {
1715 __u32 (*init_seq)(const struct sk_buff *skb); 1716 __u32 (*init_seq)(const struct sk_buff *skb);
1716 int (*send_synack)(const struct sock *sk, struct dst_entry *dst, 1717 int (*send_synack)(const struct sock *sk, struct dst_entry *dst,
1717 struct flowi *fl, struct request_sock *req, 1718 struct flowi *fl, struct request_sock *req,
1718 u16 queue_mapping, struct tcp_fastopen_cookie *foc); 1719 u16 queue_mapping, struct tcp_fastopen_cookie *foc,
1720 bool attach_req);
1719}; 1721};
1720 1722
1721#ifdef CONFIG_SYN_COOKIES 1723#ifdef CONFIG_SYN_COOKIES
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 80904df02187..099e0ea9242a 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -628,7 +628,7 @@ static void reqsk_queue_hash_req(struct request_sock *req,
628 * are committed to memory and refcnt initialized. 628 * are committed to memory and refcnt initialized.
629 */ 629 */
630 smp_wmb(); 630 smp_wmb();
631 atomic_set(&req->rsk_refcnt, 2); 631 atomic_set(&req->rsk_refcnt, 2 + 1);
632} 632}
633 633
634void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, 634void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req,
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index f69f436fcbcc..410ac481fda0 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -161,13 +161,13 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk,
161 tp->snd_wnd = ntohs(tcp_hdr(skb)->window); 161 tp->snd_wnd = ntohs(tcp_hdr(skb)->window);
162 162
163 /* Activate the retrans timer so that SYNACK can be retransmitted. 163 /* Activate the retrans timer so that SYNACK can be retransmitted.
164 * The request socket is not added to the SYN table of the parent 164 * The request socket is not added to the ehash
165 * because it's been added to the accept queue directly. 165 * because it's been added to the accept queue directly.
166 */ 166 */
167 inet_csk_reset_xmit_timer(child, ICSK_TIME_RETRANS, 167 inet_csk_reset_xmit_timer(child, ICSK_TIME_RETRANS,
168 TCP_TIMEOUT_INIT, TCP_RTO_MAX); 168 TCP_TIMEOUT_INIT, TCP_RTO_MAX);
169 169
170 atomic_set(&req->rsk_refcnt, 1); 170 atomic_set(&req->rsk_refcnt, 2);
171 /* Add the child socket directly into the accept queue */ 171 /* Add the child socket directly into the accept queue */
172 inet_csk_reqsk_queue_add(sk, req, child); 172 inet_csk_reqsk_queue_add(sk, req, child);
173 173
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index a56912772354..27108757c310 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -6120,8 +6120,6 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
6120 struct request_sock *req; 6120 struct request_sock *req;
6121 bool want_cookie = false; 6121 bool want_cookie = false;
6122 struct flowi fl; 6122 struct flowi fl;
6123 int err;
6124
6125 6123
6126 /* TW buckets are converted to open requests without 6124 /* TW buckets are converted to open requests without
6127 * limitations, they conserve resources and peer is 6125 * limitations, they conserve resources and peer is
@@ -6230,21 +6228,24 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
6230 tcp_rsk(req)->snt_isn = isn; 6228 tcp_rsk(req)->snt_isn = isn;
6231 tcp_rsk(req)->txhash = net_tx_rndhash(); 6229 tcp_rsk(req)->txhash = net_tx_rndhash();
6232 tcp_openreq_init_rwin(req, sk, dst); 6230 tcp_openreq_init_rwin(req, sk, dst);
6233 if (!want_cookie) 6231 if (!want_cookie) {
6234 fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc, dst); 6232 fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc, dst);
6235 err = af_ops->send_synack(fastopen_sk ?: sk, dst, &fl, req, 6233 tcp_reqsk_record_syn(sk, req, skb);
6236 skb_get_queue_mapping(skb), &foc); 6234 }
6237 if (fastopen_sk) { 6235 if (fastopen_sk) {
6236 af_ops->send_synack(fastopen_sk, dst, &fl, req,
6237 skb_get_queue_mapping(skb), &foc, false);
6238 sock_put(fastopen_sk); 6238 sock_put(fastopen_sk);
6239 } else { 6239 } else {
6240 if (err || want_cookie)
6241 goto drop_and_free;
6242
6243 tcp_rsk(req)->tfo_listener = false; 6240 tcp_rsk(req)->tfo_listener = false;
6244 inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); 6241 if (!want_cookie)
6242 inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
6243 af_ops->send_synack(sk, dst, &fl, req,
6244 skb_get_queue_mapping(skb), &foc, !want_cookie);
6245 if (want_cookie)
6246 goto drop_and_free;
6245 } 6247 }
6246 tcp_reqsk_record_syn(sk, req, skb); 6248 reqsk_put(req);
6247
6248 return 0; 6249 return 0;
6249 6250
6250drop_and_release: 6251drop_and_release:
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index bfe9d39ee87d..ac2ea73e9aaf 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -822,7 +822,8 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
822 struct flowi *fl, 822 struct flowi *fl,
823 struct request_sock *req, 823 struct request_sock *req,
824 u16 queue_mapping, 824 u16 queue_mapping,
825 struct tcp_fastopen_cookie *foc) 825 struct tcp_fastopen_cookie *foc,
826 bool attach_req)
826{ 827{
827 const struct inet_request_sock *ireq = inet_rsk(req); 828 const struct inet_request_sock *ireq = inet_rsk(req);
828 struct flowi4 fl4; 829 struct flowi4 fl4;
@@ -833,7 +834,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
833 if (!dst && (dst = inet_csk_route_req(sk, &fl4, req)) == NULL) 834 if (!dst && (dst = inet_csk_route_req(sk, &fl4, req)) == NULL)
834 return -1; 835 return -1;
835 836
836 skb = tcp_make_synack(sk, dst, req, foc); 837 skb = tcp_make_synack(sk, dst, req, foc, attach_req);
837 838
838 if (skb) { 839 if (skb) {
839 __tcp_v4_send_check(skb, ireq->ir_loc_addr, ireq->ir_rmt_addr); 840 __tcp_v4_send_check(skb, ireq->ir_loc_addr, ireq->ir_rmt_addr);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 09bb082ca1a7..55ed3266b05f 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2947,7 +2947,8 @@ int tcp_send_synack(struct sock *sk)
2947 */ 2947 */
2948struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, 2948struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
2949 struct request_sock *req, 2949 struct request_sock *req,
2950 struct tcp_fastopen_cookie *foc) 2950 struct tcp_fastopen_cookie *foc,
2951 bool attach_req)
2951{ 2952{
2952 struct inet_request_sock *ireq = inet_rsk(req); 2953 struct inet_request_sock *ireq = inet_rsk(req);
2953 const struct tcp_sock *tp = tcp_sk(sk); 2954 const struct tcp_sock *tp = tcp_sk(sk);
@@ -2959,11 +2960,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
2959 u16 user_mss; 2960 u16 user_mss;
2960 int mss; 2961 int mss;
2961 2962
2962 /* sk is a const pointer, because we want to express multiple cpus 2963 skb = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC);
2963 * might call us concurrently.
2964 * sock_wmalloc() will change sk->sk_wmem_alloc in an atomic way.
2965 */
2966 skb = sock_wmalloc((struct sock *)sk, MAX_TCP_HEADER, 1, GFP_ATOMIC);
2967 if (unlikely(!skb)) { 2964 if (unlikely(!skb)) {
2968 dst_release(dst); 2965 dst_release(dst);
2969 return NULL; 2966 return NULL;
@@ -2971,6 +2968,17 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
2971 /* Reserve space for headers. */ 2968 /* Reserve space for headers. */
2972 skb_reserve(skb, MAX_TCP_HEADER); 2969 skb_reserve(skb, MAX_TCP_HEADER);
2973 2970
2971 if (attach_req) {
2972 skb->destructor = sock_edemux;
2973 sock_hold(req_to_sk(req));
2974 skb->sk = req_to_sk(req);
2975 } else {
2976 /* sk is a const pointer, because we want to express multiple
2977 * cpu might call us concurrently.
2978 * sk->sk_wmem_alloc in an atomic, we can promote to rw.
2979 */
2980 skb_set_owner_w(skb, (struct sock *)sk);
2981 }
2974 skb_dst_set(skb, dst); 2982 skb_dst_set(skb, dst);
2975 2983
2976 mss = dst_metric_advmss(dst); 2984 mss = dst_metric_advmss(dst);
@@ -3510,7 +3518,7 @@ int tcp_rtx_synack(const struct sock *sk, struct request_sock *req)
3510 int res; 3518 int res;
3511 3519
3512 tcp_rsk(req)->txhash = net_tx_rndhash(); 3520 tcp_rsk(req)->txhash = net_tx_rndhash();
3513 res = af_ops->send_synack(sk, NULL, &fl, req, 0, NULL); 3521 res = af_ops->send_synack(sk, NULL, &fl, req, 0, NULL, true);
3514 if (!res) { 3522 if (!res) {
3515 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); 3523 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
3516 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNRETRANS); 3524 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNRETRANS);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index a215614cfb2b..3d18571811c5 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -438,7 +438,8 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
438 struct flowi *fl, 438 struct flowi *fl,
439 struct request_sock *req, 439 struct request_sock *req,
440 u16 queue_mapping, 440 u16 queue_mapping,
441 struct tcp_fastopen_cookie *foc) 441 struct tcp_fastopen_cookie *foc,
442 bool attach_req)
442{ 443{
443 struct inet_request_sock *ireq = inet_rsk(req); 444 struct inet_request_sock *ireq = inet_rsk(req);
444 struct ipv6_pinfo *np = inet6_sk(sk); 445 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -451,7 +452,7 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
451 IPPROTO_TCP)) == NULL) 452 IPPROTO_TCP)) == NULL)
452 goto done; 453 goto done;
453 454
454 skb = tcp_make_synack(sk, dst, req, foc); 455 skb = tcp_make_synack(sk, dst, req, foc, attach_req);
455 456
456 if (skb) { 457 if (skb) {
457 __tcp_v6_send_check(skb, &ireq->ir_v6_loc_addr, 458 __tcp_v6_send_check(skb, &ireq->ir_v6_loc_addr,
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
index f377702d4b91..3386cce4751e 100644
--- a/net/sched/sch_fq.c
+++ b/net/sched/sch_fq.c
@@ -224,13 +224,15 @@ static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q)
224 if (unlikely((skb->priority & TC_PRIO_MAX) == TC_PRIO_CONTROL)) 224 if (unlikely((skb->priority & TC_PRIO_MAX) == TC_PRIO_CONTROL))
225 return &q->internal; 225 return &q->internal;
226 226
227 /* SYNACK messages are attached to a listener socket. 227 /* SYNACK messages are attached to a TCP_NEW_SYN_RECV request socket
228 * 1) They are not part of a 'flow' yet 228 * 1) request sockets are not full blown,
229 * 2) We do not want to rate limit them (eg SYNFLOOD attack), 229 * they do not contain sk_pacing_rate
230 * 2) They are not part of a 'flow' yet
231 * 3) We do not want to rate limit them (eg SYNFLOOD attack),
230 * especially if the listener set SO_MAX_PACING_RATE 232 * especially if the listener set SO_MAX_PACING_RATE
231 * 3) We pretend they are orphaned 233 * 4) We pretend they are orphaned
232 */ 234 */
233 if (!sk || sk->sk_state == TCP_LISTEN) { 235 if (!sk || sk->sk_state == TCP_NEW_SYN_RECV) {
234 unsigned long hash = skb_get_hash(skb) & q->orphan_mask; 236 unsigned long hash = skb_get_hash(skb) & q->orphan_mask;
235 237
236 /* By forcing low order bit to 1, we make sure to not 238 /* By forcing low order bit to 1, we make sure to not