[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220511233757.2001218-11-eric.dumazet@gmail.com>
Date: Wed, 11 May 2022 16:37:57 -0700
From: Eric Dumazet <eric.dumazet@...il.com>
To: "David S . Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>
Cc: netdev <netdev@...r.kernel.org>,
Eric Dumazet <edumazet@...gle.com>,
Eric Dumazet <eric.dumazet@...il.com>
Subject: [PATCH net-next 10/10] inet: add READ_ONCE(sk->sk_bound_dev_if) in INET_MATCH()
From: Eric Dumazet <edumazet@...gle.com>
INET_MATCH() runs without holding a lock on the socket.
We probably need to annotate most reads.
This patch makes INET_MATCH() an inline function
to ease our changes. This also allows us
to add some __always_unused qualifiers.
Signed-off-by: Eric Dumazet <edumazet@...gle.com>
---
include/net/inet_hashtables.h | 52 +++++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 14 deletions(-)
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 98e1ec1a14f0382d1f4f8e85fe5ac2a056d2d6bc..5d3fa071d754601149c9ad0dd559f074ac58deaa 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -307,23 +307,47 @@ static inline struct sock *inet_lookup_listener(struct net *net,
(((__force __u64)(__be32)(__daddr)) << 32) | \
((__force __u64)(__be32)(__saddr)))
#endif /* __BIG_ENDIAN */
-#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \
- (((__sk)->sk_portpair == (__ports)) && \
- ((__sk)->sk_addrpair == (__cookie)) && \
- (((__sk)->sk_bound_dev_if == (__dif)) || \
- ((__sk)->sk_bound_dev_if == (__sdif))) && \
- net_eq(sock_net(__sk), (__net)))
+static inline bool INET_MATCH(const struct sock *sk, struct net *net,
+ const __addrpair cookie,
+ const __be32 __always_unused saddr,
+ const __be32 __always_unused daddr,
+ const __portpair ports,
+ const int dif,
+ const int sdif)
+{
+ int bound_dev_if;
+
+ if (!net_eq(sock_net(sk), net) ||
+ sk->sk_portpair != ports ||
+ sk->sk_addrpair != cookie)
+ return false;
+
+ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+ return bound_dev_if == dif || bound_dev_if == sdif;
+}
#else /* 32-bit arch */
#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
- const int __name __deprecated __attribute__((unused))
+ const int __name __deprecated __always_unused
-#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \
- (((__sk)->sk_portpair == (__ports)) && \
- ((__sk)->sk_daddr == (__saddr)) && \
- ((__sk)->sk_rcv_saddr == (__daddr)) && \
- (((__sk)->sk_bound_dev_if == (__dif)) || \
- ((__sk)->sk_bound_dev_if == (__sdif))) && \
- net_eq(sock_net(__sk), (__net)))
+static inline bool INET_MATCH(const struct sock *sk, struct net *net,
+ const __addrpair __always_unused cookie,
+ const __be32 saddr,
+ const __be32 daddr,
+ const __portpair ports,
+ const int dif,
+ const int sdif)
+{
+ int bound_dev_if;
+
+ if (!net_eq(sock_net(sk), net) ||
+ sk->sk_portpair != ports ||
+ sk->sk_daddr != saddr ||
+ sk->sk_rcv_saddr != daddr)
+ return false;
+
+ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+ return bound_dev_if == dif || bound_dev_if == sdif;
+}
#endif /* 64-bit arch */
/* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need
--
2.36.0.512.ge40c2bad7a-goog
Powered by blists - more mailing lists