summaryrefslogtreecommitdiff
path: root/include/net/tcp.h
diff options
context:
space:
mode:
authorDmitry Safonov <dima@arista.com>2023-10-23 20:22:12 +0100
committerDavid S. Miller <davem@davemloft.net>2023-10-27 10:35:45 +0100
commit67fa83f7c86a86913ab9cd5a13b4bebd8d2ebb43 (patch)
treea08a7cdd4c208883f96a724379ff871cffe9a76a /include/net/tcp.h
parentd6732b95b6fbbc6d5bb9d2f809e275763640c4a2 (diff)
net/tcp: Add static_key for TCP-AO
Similarly to TCP-MD5, add a static key to TCP-AO that is patched out when there are no keys on a machine and dynamically enabled with the first setsockopt(TCP_AO) adds a key on any socket. The static key is as well dynamically disabled later when the socket is destructed. The lifetime of enabled static key here is the same as ao_info: it is enabled on allocation, passed over from full socket to twsk and destructed when ao_info is scheduled for destruction. Signed-off-by: Dmitry Safonov <dima@arista.com> Acked-by: David Ahern <dsahern@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/tcp.h')
-rw-r--r--include/net/tcp.h24
1 files changed, 16 insertions, 8 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 54226d85feb8..e3617c433cf1 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -2288,14 +2288,18 @@ static inline void tcp_get_current_key(const struct sock *sk,
#if defined(CONFIG_TCP_AO) || defined(CONFIG_TCP_MD5SIG)
const struct tcp_sock *tp = tcp_sk(sk);
#endif
-#ifdef CONFIG_TCP_AO
- struct tcp_ao_info *ao;
- ao = rcu_dereference_protected(tp->ao_info, lockdep_sock_is_held(sk));
- if (ao) {
- out->ao_key = READ_ONCE(ao->current_key);
- out->type = TCP_KEY_AO;
- return;
+#ifdef CONFIG_TCP_AO
+ if (static_branch_unlikely(&tcp_ao_needed.key)) {
+ struct tcp_ao_info *ao;
+
+ ao = rcu_dereference_protected(tp->ao_info,
+ lockdep_sock_is_held(sk));
+ if (ao) {
+ out->ao_key = READ_ONCE(ao->current_key);
+ out->type = TCP_KEY_AO;
+ return;
+ }
}
#endif
#ifdef CONFIG_TCP_MD5SIG
@@ -2324,7 +2328,8 @@ static inline bool tcp_key_is_md5(const struct tcp_key *key)
static inline bool tcp_key_is_ao(const struct tcp_key *key)
{
#ifdef CONFIG_TCP_AO
- if (key->type == TCP_KEY_AO)
+ if (static_branch_unlikely(&tcp_ao_needed.key) &&
+ key->type == TCP_KEY_AO)
return true;
#endif
return false;
@@ -2718,6 +2723,9 @@ static inline bool tcp_ao_required(struct sock *sk, const void *saddr,
struct tcp_ao_info *ao_info;
struct tcp_ao_key *ao_key;
+ if (!static_branch_unlikely(&tcp_ao_needed.key))
+ return false;
+
ao_info = rcu_dereference_check(tcp_sk(sk)->ao_info,
lockdep_sock_is_held(sk));
if (!ao_info)