Skip to content

Commit a1a5344

Browse files
Eric Dumazetdavem330
authored andcommitted
tcp: avoid two atomic ops for syncookies
inet_reqsk_alloc() is used to allocate a temporary request in order to generate a SYNACK with a cookie. Then later, syncookie validation also uses a temporary request. These paths already took a reference on listener refcount, we can avoid a couple of atomic operations. Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 004a5d0 commit a1a5344

File tree

7 files changed

+19
-11
lines changed

7 files changed

+19
-11
lines changed

include/net/inet_sock.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ static inline unsigned int __inet_ehashfn(const __be32 laddr,
245245
}
246246

247247
struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops,
248-
struct sock *sk_listener);
248+
struct sock *sk_listener,
249+
bool attach_listener);
249250

250251
static inline __u8 inet_sk_flowi_flags(const struct sock *sk)
251252
{

include/net/request_sock.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,21 @@ static inline struct sock *req_to_sk(struct request_sock *req)
8080
}
8181

8282
static inline struct request_sock *
83-
reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener)
83+
reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener,
84+
bool attach_listener)
8485
{
8586
struct request_sock *req;
8687

8788
req = kmem_cache_alloc(ops->slab, GFP_ATOMIC | __GFP_NOWARN);
8889

8990
if (req) {
9091
req->rsk_ops = ops;
91-
sock_hold(sk_listener);
92-
req->rsk_listener = sk_listener;
92+
if (attach_listener) {
93+
sock_hold(sk_listener);
94+
req->rsk_listener = sk_listener;
95+
} else {
96+
req->rsk_listener = NULL;
97+
}
9398
req_to_sk(req)->sk_prot = sk_listener->sk_prot;
9499
sk_node_init(&req_to_sk(req)->sk_node);
95100
sk_tx_queue_clear(req_to_sk(req));

net/dccp/ipv4.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
595595
if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
596596
goto drop;
597597

598-
req = inet_reqsk_alloc(&dccp_request_sock_ops, sk);
598+
req = inet_reqsk_alloc(&dccp_request_sock_ops, sk, true);
599599
if (req == NULL)
600600
goto drop;
601601

net/dccp/ipv6.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
319319
if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
320320
goto drop;
321321

322-
req = inet_reqsk_alloc(&dccp6_request_sock_ops, sk);
322+
req = inet_reqsk_alloc(&dccp6_request_sock_ops, sk, true);
323323
if (req == NULL)
324324
goto drop;
325325

net/ipv4/syncookies.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
326326
goto out;
327327

328328
ret = NULL;
329-
req = inet_reqsk_alloc(&tcp_request_sock_ops, sk); /* for safety */
329+
req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */
330330
if (!req)
331331
goto out;
332332

net/ipv4/tcp_input.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6042,9 +6042,11 @@ static void tcp_openreq_init(struct request_sock *req,
60426042
}
60436043

60446044
struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops,
6045-
struct sock *sk_listener)
6045+
struct sock *sk_listener,
6046+
bool attach_listener)
60466047
{
6047-
struct request_sock *req = reqsk_alloc(ops, sk_listener);
6048+
struct request_sock *req = reqsk_alloc(ops, sk_listener,
6049+
attach_listener);
60486050

60496051
if (req) {
60506052
struct inet_request_sock *ireq = inet_rsk(req);
@@ -6143,7 +6145,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
61436145
goto drop;
61446146
}
61456147

6146-
req = inet_reqsk_alloc(rsk_ops, sk);
6148+
req = inet_reqsk_alloc(rsk_ops, sk, !want_cookie);
61476149
if (!req)
61486150
goto drop;
61496151

net/ipv6/syncookies.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
170170
goto out;
171171

172172
ret = NULL;
173-
req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk);
173+
req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false);
174174
if (!req)
175175
goto out;
176176

0 commit comments

Comments
 (0)