History

Revert "net: Add a second bind table hashed by port and address"

This reverts: commit d5a42de8bdbe ("net: Add a second bind table hashed by port and address") commit 538aaf9b2383 ("selftests: Add test for timing a bind request to a port with a populated bhash entry") Link: https://lore.kernel.org/netdev/20220520001834.2247810-1-kuba@kernel.org/ There are a few things that need to be fixed here: * Updating bhash2 in cases where the socket's rcv saddr changes * Adding bhash2 hashbucket locks Links to syzbot reports: https://lore.kernel.org/netdev/00000000000022208805e0df247a@google.com/ https://lore.kernel.org/netdev/0000000000003f33bc05dfaf44fe@google.com/

Joanne Koong committed 4 years ago

Commit 593d1eb1 parent 219b51a10 files · +83 −611Browse files

Showing the changes to include (3 of 10 files). Show all

Unified · Split

3 files
  1. include/net/inet_connection_sock.h +0 −3
  2. include/net/inet_hashtables.h +1 −67
  3. include/net/sock.h +0 −14
include/net/inet_connection_sock.h+0−3
@@ -25,7 +25,6 @@ · 24 unmodified lines
25#undef INET_CSK_CLEAR_TIMERS25#undef INET_CSK_CLEAR_TIMERS
26 26
27struct inet_bind_bucket;27struct inet_bind_bucket;
28struct inet_bind2_bucket;
29struct tcp_congestion_ops;28struct tcp_congestion_ops;
30 29
31/*30/*
@@ -58,7 +57,6 @@ struct inet_connection_sock_af_ops { · 26 unmodified lines
58 *57 *
59 * @icsk_accept_queue: FIFO of established children58 * @icsk_accept_queue: FIFO of established children
60 * @icsk_bind_hash: Bind node59 * @icsk_bind_hash: Bind node
61 * @icsk_bind2_hash: Bind node in the bhash2 table
62 * @icsk_timeout: Timeout60 * @icsk_timeout: Timeout
63 * @icsk_retransmit_timer: Resend (no ack)61 * @icsk_retransmit_timer: Resend (no ack)
64 * @icsk_rto: Retransmit timeout62 * @icsk_rto: Retransmit timeout
@@ -85,7 +83,6 @@ struct inet_connection_sock { · 20 unmodified lines
85 struct inet_sock icsk_inet;83 struct inet_sock icsk_inet;
86 struct request_sock_queue icsk_accept_queue;84 struct request_sock_queue icsk_accept_queue;
87 struct inet_bind_bucket *icsk_bind_hash;85 struct inet_bind_bucket *icsk_bind_hash;
88 struct inet_bind2_bucket *icsk_bind2_hash;
89 unsigned long icsk_timeout;86 unsigned long icsk_timeout;
90 struct timer_list icsk_retransmit_timer;87 struct timer_list icsk_retransmit_timer;
91 struct timer_list icsk_delack_timer;88 struct timer_list icsk_delack_timer;
include/net/inet_hashtables.h+1−67
@@ -90,32 +90,11 @@ struct inet_bind_bucket { · 89 unmodified lines
90 struct hlist_head owners;90 struct hlist_head owners;
91};91};
92 92
93struct inet_bind2_bucket {
94 possible_net_t ib_net;
95 int l3mdev;
96 unsigned short port;
97 union {
98#if IS_ENABLED(CONFIG_IPV6)
99 struct in6_addr v6_rcv_saddr;
100#endif
101 __be32 rcv_saddr;
102 };
103 /* Node in the inet2_bind_hashbucket chain */
104 struct hlist_node node;
105 /* List of sockets hashed to this bucket */
106 struct hlist_head owners;
107};
108
109static inline struct net *ib_net(struct inet_bind_bucket *ib)93static inline struct net *ib_net(struct inet_bind_bucket *ib)
110{94{
111 return read_pnet(&ib->ib_net);95 return read_pnet(&ib->ib_net);
112}96}
113 97
114static inline struct net *ib2_net(struct inet_bind2_bucket *ib)
115{
116 return read_pnet(&ib->ib_net);
117}
118
119#define inet_bind_bucket_for_each(tb, head) \98#define inet_bind_bucket_for_each(tb, head) \
120 hlist_for_each_entry(tb, head, node)99 hlist_for_each_entry(tb, head, node)
121 100
@@ -124,15 +103,6 @@ struct inet_bind_hashbucket { · 2 unmodified lines
124 struct hlist_head chain;103 struct hlist_head chain;
125};104};
126 105
127/* This is synchronized using the inet_bind_hashbucket's spinlock.
128 * Instead of having separate spinlocks, the inet_bind2_hashbucket can share
129 * the inet_bind_hashbucket's given that in every case where the bhash2 table
130 * is useful, a lookup in the bhash table also occurs.
131 */
132struct inet_bind2_hashbucket {
133 struct hlist_head chain;
134};
135
136/* Sockets can be hashed in established or listening table.106/* Sockets can be hashed in established or listening table.
137 * We must use different 'nulls' end-of-chain value for all hash buckets :107 * We must use different 'nulls' end-of-chain value for all hash buckets :
138 * A socket might transition from ESTABLISH to LISTEN state without108 * A socket might transition from ESTABLISH to LISTEN state without
@@ -164,12 +134,6 @@ struct inet_hashinfo { · 25 unmodified lines
164 */134 */
165 struct kmem_cache *bind_bucket_cachep;135 struct kmem_cache *bind_bucket_cachep;
166 struct inet_bind_hashbucket *bhash;136 struct inet_bind_hashbucket *bhash;
167 /* The 2nd binding table hashed by port and address.
168 * This is used primarily for expediting the resolution of bind
169 * conflicts.
170 */
171 struct kmem_cache *bind2_bucket_cachep;
172 struct inet_bind2_hashbucket *bhash2;
173 unsigned int bhash_size;137 unsigned int bhash_size;
174 138
175 /* The 2nd listener table hashed by local port and address */139 /* The 2nd listener table hashed by local port and address */
@@ -229,36 +193,6 @@ inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net, · 53 unmodified lines
229void inet_bind_bucket_destroy(struct kmem_cache *cachep,193void inet_bind_bucket_destroy(struct kmem_cache *cachep,
230 struct inet_bind_bucket *tb);194 struct inet_bind_bucket *tb);
231 195
232static inline bool check_bind_bucket_match(struct inet_bind_bucket *tb,
233 struct net *net,
234 const unsigned short port,
235 int l3mdev)
236{
237 return net_eq(ib_net(tb), net) && tb->port == port &&
238 tb->l3mdev == l3mdev;
239}
240
241struct inet_bind2_bucket *
242inet_bind2_bucket_create(struct kmem_cache *cachep, struct net *net,
243 struct inet_bind2_hashbucket *head,
244 const unsigned short port, int l3mdev,
245 const struct sock *sk);
246
247void inet_bind2_bucket_destroy(struct kmem_cache *cachep,
248 struct inet_bind2_bucket *tb);
249
250struct inet_bind2_bucket *
251inet_bind2_bucket_find(struct inet_hashinfo *hinfo, struct net *net,
252 const unsigned short port, int l3mdev,
253 struct sock *sk,
254 struct inet_bind2_hashbucket **head);
255
256bool check_bind2_bucket_match_nulladdr(struct inet_bind2_bucket *tb,
257 struct net *net,
258 const unsigned short port,
259 int l3mdev,
260 const struct sock *sk);
261
262static inline u32 inet_bhashfn(const struct net *net, const __u16 lport,196static inline u32 inet_bhashfn(const struct net *net, const __u16 lport,
263 const u32 bhash_size)197 const u32 bhash_size)
264{198{
@@ -266,7 +200,7 @@ static inline u32 inet_bhashfn(const struct net *net, const __u16 lport, · 1 unmodified line
266}200}
267 201
268void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb,202void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb,
269 struct inet_bind2_bucket *tb2, const unsigned short snum);203 const unsigned short snum);
270 204
271/* Caller must disable local BH processing. */205/* Caller must disable local BH processing. */
272int __inet_inherit_port(const struct sock *sk, struct sock *child);206int __inet_inherit_port(const struct sock *sk, struct sock *child);
include/net/sock.h+0−14
@@ -348,7 +348,6 @@ struct sk_filter; · 347 unmodified lines
348 * @sk_txtime_report_errors: set report errors mode for SO_TXTIME348 * @sk_txtime_report_errors: set report errors mode for SO_TXTIME
349 * @sk_txtime_unused: unused txtime flags349 * @sk_txtime_unused: unused txtime flags
350 * @ns_tracker: tracker for netns reference350 * @ns_tracker: tracker for netns reference
351 * @sk_bind2_node: bind node in the bhash2 table
352 */351 */
353struct sock {352struct sock {
354 /*353 /*
@@ -538,7 +537,6 @@ struct sock { · 183 unmodified lines
538#endif537#endif
539 struct rcu_head sk_rcu;538 struct rcu_head sk_rcu;
540 netns_tracker ns_tracker;539 netns_tracker ns_tracker;
541 struct hlist_node sk_bind2_node;
542};540};
543 541
544enum sk_pacing {542enum sk_pacing {
@@ -819,16 +817,6 @@ static inline void sk_add_bind_node(struct sock *sk, · 274 unmodified lines
819 hlist_add_head(&sk->sk_bind_node, list);817 hlist_add_head(&sk->sk_bind_node, list);
820}818}
821 819
822static inline void __sk_del_bind2_node(struct sock *sk)
823{
824 __hlist_del(&sk->sk_bind2_node);
825}
826
827static inline void sk_add_bind2_node(struct sock *sk, struct hlist_head *list)
828{
829 hlist_add_head(&sk->sk_bind2_node, list);
830}
831
832#define sk_for_each(__sk, list) \820#define sk_for_each(__sk, list) \
833 hlist_for_each_entry(__sk, list, sk_node)821 hlist_for_each_entry(__sk, list, sk_node)
834#define sk_for_each_rcu(__sk, list) \822#define sk_for_each_rcu(__sk, list) \
@@ -846,8 +834,6 @@ static inline void sk_add_bind2_node(struct sock *sk, struct hlist_head *list) · 11 unmodified lines
846 hlist_for_each_entry_safe(__sk, tmp, list, sk_node)834 hlist_for_each_entry_safe(__sk, tmp, list, sk_node)
847#define sk_for_each_bound(__sk, list) \835#define sk_for_each_bound(__sk, list) \
848 hlist_for_each_entry(__sk, list, sk_bind_node)836 hlist_for_each_entry(__sk, list, sk_bind_node)
849#define sk_for_each_bound_bhash2(__sk, list) \
850 hlist_for_each_entry(__sk, list, sk_bind2_node)
851 837
852/**838/**
853 * sk_for_each_entry_offset_rcu - iterate over a list at a given struct offset839 * sk_for_each_entry_offset_rcu - iterate over a list at a given struct offset