Skip to content

Commit 9caad86

Browse files
Eric Dumazetdavem330
authored andcommitted
tcp: increment sk_drops for listeners
Goal: packets dropped by a listener are accounted for. This adds tcp_listendrop() helper, and clears sk_drops in sk_clone_lock() so that children do not inherit their parent drop count. Note that we no longer increment LINUX_MIB_LISTENDROPS counter when sending a SYNCOOKIE, since the SYN packet generated a SYNACK. We already have a separate LINUX_MIB_SYNCOOKIESSENT Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 532182c commit 9caad86

File tree

5 files changed

+24
-8
lines changed

5 files changed

+24
-8
lines changed

include/net/tcp.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,4 +1836,17 @@ static inline void tcp_segs_in(struct tcp_sock *tp, const struct sk_buff *skb)
18361836
tp->data_segs_in += segs_in;
18371837
}
18381838

1839+
/*
1840+
* TCP listen path runs lockless.
1841+
* We forced "struct sock" to be const qualified to make sure
1842+
* we don't modify one of its field by mistake.
1843+
* Here, we increment sk_drops which is an atomic_t, so we can safely
1844+
* make sock writable again.
1845+
*/
1846+
static inline void tcp_listendrop(const struct sock *sk)
1847+
{
1848+
atomic_inc(&((struct sock *)sk)->sk_drops);
1849+
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
1850+
}
1851+
18391852
#endif /* _TCP_H */

net/core/sock.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,6 +1525,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
15251525
newsk->sk_dst_cache = NULL;
15261526
newsk->sk_wmem_queued = 0;
15271527
newsk->sk_forward_alloc = 0;
1528+
atomic_set(&newsk->sk_drops, 0);
15281529
newsk->sk_send_head = NULL;
15291530
newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK;
15301531

net/ipv4/tcp_input.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6339,8 +6339,10 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
63396339
inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
63406340
af_ops->send_synack(sk, dst, &fl, req,
63416341
&foc, !want_cookie);
6342-
if (want_cookie)
6343-
goto drop_and_free;
6342+
if (want_cookie) {
6343+
reqsk_free(req);
6344+
return 0;
6345+
}
63446346
}
63456347
reqsk_put(req);
63466348
return 0;
@@ -6350,7 +6352,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
63506352
drop_and_free:
63516353
reqsk_free(req);
63526354
drop:
6353-
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
6355+
tcp_listendrop(sk);
63546356
return 0;
63556357
}
63566358
EXPORT_SYMBOL(tcp_conn_request);

net/ipv4/tcp_ipv4.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ void tcp_req_err(struct sock *sk, u32 seq, bool abort)
329329
* errors returned from accept().
330330
*/
331331
inet_csk_reqsk_queue_drop(req->rsk_listener, req);
332-
NET_INC_STATS_BH(net, LINUX_MIB_LISTENDROPS);
332+
tcp_listendrop(req->rsk_listener);
333333
}
334334
reqsk_put(req);
335335
}
@@ -1246,7 +1246,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
12461246
&tcp_request_sock_ipv4_ops, sk, skb);
12471247

12481248
drop:
1249-
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
1249+
tcp_listendrop(sk);
12501250
return 0;
12511251
}
12521252
EXPORT_SYMBOL(tcp_v4_conn_request);
@@ -1348,7 +1348,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
13481348
exit_nonewsk:
13491349
dst_release(dst);
13501350
exit:
1351-
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
1351+
tcp_listendrop(sk);
13521352
return NULL;
13531353
put_and_exit:
13541354
inet_csk_prepare_forced_close(newsk);

net/ipv6/tcp_ipv6.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
964964
&tcp_request_sock_ipv6_ops, sk, skb);
965965

966966
drop:
967-
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
967+
tcp_listendrop(sk);
968968
return 0; /* don't send reset */
969969
}
970970

@@ -1169,7 +1169,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
11691169
out_nonewsk:
11701170
dst_release(dst);
11711171
out:
1172-
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
1172+
tcp_listendrop(sk);
11731173
return NULL;
11741174
}
11751175

0 commit comments

Comments
 (0)