| .. | .. |
|---|
| 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 _INET6_HASHTABLES_H |
|---|
| .. | .. |
|---|
| 89 | 85 | int iif, int sdif, |
|---|
| 90 | 86 | bool *refcounted) |
|---|
| 91 | 87 | { |
|---|
| 92 | | - struct sock *sk = skb_steal_sock(skb); |
|---|
| 88 | + struct sock *sk = skb_steal_sock(skb, refcounted); |
|---|
| 93 | 89 | |
|---|
| 94 | | - *refcounted = true; |
|---|
| 95 | 90 | if (sk) |
|---|
| 96 | 91 | return sk; |
|---|
| 97 | 92 | |
|---|
| .. | .. |
|---|
| 108 | 103 | const int dif); |
|---|
| 109 | 104 | |
|---|
| 110 | 105 | int inet6_hash(struct sock *sk); |
|---|
| 111 | | -#endif /* IS_ENABLED(CONFIG_IPV6) */ |
|---|
| 112 | 106 | |
|---|
| 113 | | -#define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif, __sdif) \ |
|---|
| 114 | | - (((__sk)->sk_portpair == (__ports)) && \ |
|---|
| 115 | | - ((__sk)->sk_family == AF_INET6) && \ |
|---|
| 116 | | - ipv6_addr_equal(&(__sk)->sk_v6_daddr, (__saddr)) && \ |
|---|
| 117 | | - ipv6_addr_equal(&(__sk)->sk_v6_rcv_saddr, (__daddr)) && \ |
|---|
| 118 | | - (!(__sk)->sk_bound_dev_if || \ |
|---|
| 119 | | - ((__sk)->sk_bound_dev_if == (__dif)) || \ |
|---|
| 120 | | - ((__sk)->sk_bound_dev_if == (__sdif))) && \ |
|---|
| 121 | | - net_eq(sock_net(__sk), (__net))) |
|---|
| 107 | +static inline bool inet6_match(struct net *net, const struct sock *sk, |
|---|
| 108 | + const struct in6_addr *saddr, |
|---|
| 109 | + const struct in6_addr *daddr, |
|---|
| 110 | + const __portpair ports, |
|---|
| 111 | + const int dif, const int sdif) |
|---|
| 112 | +{ |
|---|
| 113 | + if (!net_eq(sock_net(sk), net) || |
|---|
| 114 | + sk->sk_family != AF_INET6 || |
|---|
| 115 | + sk->sk_portpair != ports || |
|---|
| 116 | + !ipv6_addr_equal(&sk->sk_v6_daddr, saddr) || |
|---|
| 117 | + !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr)) |
|---|
| 118 | + return false; |
|---|
| 119 | + |
|---|
| 120 | + /* READ_ONCE() paired with WRITE_ONCE() in sock_bindtoindex_locked() */ |
|---|
| 121 | + return inet_sk_bound_dev_eq(net, READ_ONCE(sk->sk_bound_dev_if), dif, |
|---|
| 122 | + sdif); |
|---|
| 123 | +} |
|---|
| 124 | +#endif /* IS_ENABLED(CONFIG_IPV6) */ |
|---|
| 122 | 125 | |
|---|
| 123 | 126 | #endif /* _INET6_HASHTABLES_H */ |
|---|