.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
---|
1 | 2 | /* |
---|
2 | 3 | * INET An implementation of the TCP/IP protocol suite for the LINUX |
---|
3 | 4 | * operating system. INET is implemented using the BSD Socket |
---|
4 | 5 | * interface as the means of communication with the user level. |
---|
5 | 6 | * |
---|
6 | 7 | * Authors: Lotsa people, from code originally in tcp |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or |
---|
9 | | - * modify it under the terms of the GNU General Public License |
---|
10 | | - * as published by the Free Software Foundation; either version |
---|
11 | | - * 2 of the License, or (at your option) any later version. |
---|
12 | 8 | */ |
---|
13 | 9 | |
---|
14 | 10 | #ifndef _INET_HASHTABLES_H |
---|
.. | .. |
---|
79 | 75 | |
---|
80 | 76 | struct inet_bind_bucket { |
---|
81 | 77 | possible_net_t ib_net; |
---|
| 78 | + int l3mdev; |
---|
82 | 79 | unsigned short port; |
---|
83 | 80 | signed char fastreuse; |
---|
84 | 81 | signed char fastreuseport; |
---|
.. | .. |
---|
188 | 185 | |
---|
189 | 186 | int inet_ehash_locks_alloc(struct inet_hashinfo *hashinfo); |
---|
190 | 187 | |
---|
| 188 | +static inline void inet_hashinfo2_free_mod(struct inet_hashinfo *h) |
---|
| 189 | +{ |
---|
| 190 | + kfree(h->lhash2); |
---|
| 191 | + h->lhash2 = NULL; |
---|
| 192 | +} |
---|
| 193 | + |
---|
191 | 194 | static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo) |
---|
192 | 195 | { |
---|
193 | 196 | kvfree(hashinfo->ehash_locks); |
---|
.. | .. |
---|
197 | 200 | struct inet_bind_bucket * |
---|
198 | 201 | inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net, |
---|
199 | 202 | struct inet_bind_hashbucket *head, |
---|
200 | | - const unsigned short snum); |
---|
| 203 | + const unsigned short snum, int l3mdev); |
---|
201 | 204 | void inet_bind_bucket_destroy(struct kmem_cache *cachep, |
---|
202 | 205 | struct inet_bind_bucket *tb); |
---|
203 | 206 | |
---|
.. | .. |
---|
231 | 234 | unsigned long numentries, int scale, |
---|
232 | 235 | unsigned long low_limit, |
---|
233 | 236 | unsigned long high_limit); |
---|
| 237 | +int inet_hashinfo2_init_mod(struct inet_hashinfo *h); |
---|
234 | 238 | |
---|
235 | | -bool inet_ehash_insert(struct sock *sk, struct sock *osk); |
---|
236 | | -bool inet_ehash_nolisten(struct sock *sk, struct sock *osk); |
---|
| 239 | +bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk); |
---|
| 240 | +bool inet_ehash_nolisten(struct sock *sk, struct sock *osk, |
---|
| 241 | + bool *found_dup_sk); |
---|
237 | 242 | int __inet_hash(struct sock *sk, struct sock *osk); |
---|
238 | 243 | int inet_hash(struct sock *sk); |
---|
239 | 244 | void inet_unhash(struct sock *sk); |
---|
.. | .. |
---|
273 | 278 | ((__force __portpair)(((__u32)(__dport) << 16) | (__force __u32)(__be16)(__sport))) |
---|
274 | 279 | #endif |
---|
275 | 280 | |
---|
276 | | -#if (BITS_PER_LONG == 64) |
---|
277 | 281 | #ifdef __BIG_ENDIAN |
---|
278 | 282 | #define INET_ADDR_COOKIE(__name, __saddr, __daddr) \ |
---|
279 | 283 | const __addrpair __name = (__force __addrpair) ( \ |
---|
.. | .. |
---|
285 | 289 | (((__force __u64)(__be32)(__daddr)) << 32) | \ |
---|
286 | 290 | ((__force __u64)(__be32)(__saddr))) |
---|
287 | 291 | #endif /* __BIG_ENDIAN */ |
---|
288 | | -#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \ |
---|
289 | | - (((__sk)->sk_portpair == (__ports)) && \ |
---|
290 | | - ((__sk)->sk_addrpair == (__cookie)) && \ |
---|
291 | | - (!(__sk)->sk_bound_dev_if || \ |
---|
292 | | - ((__sk)->sk_bound_dev_if == (__dif)) || \ |
---|
293 | | - ((__sk)->sk_bound_dev_if == (__sdif))) && \ |
---|
294 | | - net_eq(sock_net(__sk), (__net))) |
---|
295 | | -#else /* 32-bit arch */ |
---|
296 | | -#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \ |
---|
297 | | - const int __name __deprecated __attribute__((unused)) |
---|
298 | 292 | |
---|
299 | | -#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \ |
---|
300 | | - (((__sk)->sk_portpair == (__ports)) && \ |
---|
301 | | - ((__sk)->sk_daddr == (__saddr)) && \ |
---|
302 | | - ((__sk)->sk_rcv_saddr == (__daddr)) && \ |
---|
303 | | - (!(__sk)->sk_bound_dev_if || \ |
---|
304 | | - ((__sk)->sk_bound_dev_if == (__dif)) || \ |
---|
305 | | - ((__sk)->sk_bound_dev_if == (__sdif))) && \ |
---|
306 | | - net_eq(sock_net(__sk), (__net))) |
---|
307 | | -#endif /* 64-bit arch */ |
---|
| 293 | +static inline bool INET_MATCH(struct net *net, const struct sock *sk, |
---|
| 294 | + const __addrpair cookie, const __portpair ports, |
---|
| 295 | + int dif, int sdif) |
---|
| 296 | +{ |
---|
| 297 | + if (!net_eq(sock_net(sk), net) || |
---|
| 298 | + sk->sk_portpair != ports || |
---|
| 299 | + sk->sk_addrpair != cookie) |
---|
| 300 | + return false; |
---|
| 301 | + |
---|
| 302 | + /* READ_ONCE() paired with WRITE_ONCE() in sock_bindtoindex_locked() */ |
---|
| 303 | + return inet_sk_bound_dev_eq(net, READ_ONCE(sk->sk_bound_dev_if), dif, |
---|
| 304 | + sdif); |
---|
| 305 | +} |
---|
308 | 306 | |
---|
309 | 307 | /* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need |
---|
310 | 308 | * not check it for lookups anymore, thanks Alexey. -DaveM |
---|
.. | .. |
---|
372 | 370 | const int sdif, |
---|
373 | 371 | bool *refcounted) |
---|
374 | 372 | { |
---|
375 | | - struct sock *sk = skb_steal_sock(skb); |
---|
| 373 | + struct sock *sk = skb_steal_sock(skb, refcounted); |
---|
376 | 374 | const struct iphdr *iph = ip_hdr(skb); |
---|
377 | 375 | |
---|
378 | | - *refcounted = true; |
---|
379 | 376 | if (sk) |
---|
380 | 377 | return sk; |
---|
381 | 378 | |
---|
.. | .. |
---|
406 | 403 | } |
---|
407 | 404 | |
---|
408 | 405 | int __inet_hash_connect(struct inet_timewait_death_row *death_row, |
---|
409 | | - struct sock *sk, u32 port_offset, |
---|
| 406 | + struct sock *sk, u64 port_offset, |
---|
410 | 407 | int (*check_established)(struct inet_timewait_death_row *, |
---|
411 | 408 | struct sock *, __u16, |
---|
412 | 409 | struct inet_timewait_sock **)); |
---|