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/
Showing the changes to include (3 of 10 files). Show all
Unified · Split
| @@ -25,7 +25,6 @@ · 24 unmodified lines | |||
| 25 | #undef INET_CSK_CLEAR_TIMERS | 25 | #undef INET_CSK_CLEAR_TIMERS |
| 26 | 26 | ||
| 27 | struct inet_bind_bucket; | 27 | struct inet_bind_bucket; |
| 28 | struct inet_bind2_bucket; | ||
| 29 | struct tcp_congestion_ops; | 28 | struct 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 children | 58 | * @icsk_accept_queue: FIFO of established children |
| 60 | * @icsk_bind_hash: Bind node | 59 | * @icsk_bind_hash: Bind node |
| 61 | * @icsk_bind2_hash: Bind node in the bhash2 table | ||
| 62 | * @icsk_timeout: Timeout | 60 | * @icsk_timeout: Timeout |
| 63 | * @icsk_retransmit_timer: Resend (no ack) | 61 | * @icsk_retransmit_timer: Resend (no ack) |
| 64 | * @icsk_rto: Retransmit timeout | 62 | * @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; |
| @@ -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 | ||
| 93 | struct 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 | |||
| 109 | static inline struct net *ib_net(struct inet_bind_bucket *ib) | 93 | static 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 | ||
| 114 | static 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 | */ | ||
| 132 | struct 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 without | 108 | * 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 | |||
| 229 | void inet_bind_bucket_destroy(struct kmem_cache *cachep, | 193 | void inet_bind_bucket_destroy(struct kmem_cache *cachep, |
| 230 | struct inet_bind_bucket *tb); | 194 | struct inet_bind_bucket *tb); |
| 231 | 195 | ||
| 232 | static 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 | |||
| 241 | struct inet_bind2_bucket * | ||
| 242 | inet_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 | |||
| 247 | void inet_bind2_bucket_destroy(struct kmem_cache *cachep, | ||
| 248 | struct inet_bind2_bucket *tb); | ||
| 249 | |||
| 250 | struct inet_bind2_bucket * | ||
| 251 | inet_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 | |||
| 256 | bool 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 | |||
| 262 | static inline u32 inet_bhashfn(const struct net *net, const __u16 lport, | 196 | static 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 | ||
| 268 | void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb, | 202 | void 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. */ |
| 272 | int __inet_inherit_port(const struct sock *sk, struct sock *child); | 206 | int __inet_inherit_port(const struct sock *sk, struct sock *child); |
| @@ -348,7 +348,6 @@ struct sk_filter; · 347 unmodified lines | |||
| 348 | * @sk_txtime_report_errors: set report errors mode for SO_TXTIME | 348 | * @sk_txtime_report_errors: set report errors mode for SO_TXTIME |
| 349 | * @sk_txtime_unused: unused txtime flags | 349 | * @sk_txtime_unused: unused txtime flags |
| 350 | * @ns_tracker: tracker for netns reference | 350 | * @ns_tracker: tracker for netns reference |
| 351 | * @sk_bind2_node: bind node in the bhash2 table | ||
| 352 | */ | 351 | */ |
| 353 | struct sock { | 352 | struct sock { |
| 354 | /* | 353 | /* |
| @@ -538,7 +537,6 @@ struct sock { · 183 unmodified lines | |||
| 538 | #endif | 537 | #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 | ||
| 544 | enum sk_pacing { | 542 | enum 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 | ||
| 822 | static inline void __sk_del_bind2_node(struct sock *sk) | ||
| 823 | { | ||
| 824 | __hlist_del(&sk->sk_bind2_node); | ||
| 825 | } | ||
| 826 | |||
| 827 | static 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 offset | 839 | * sk_for_each_entry_offset_rcu - iterate over a list at a given struct offset |