diff options
author | Dmitry Safonov <dima@arista.com> | 2023-10-23 20:22:12 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2023-10-27 10:35:45 +0100 |
commit | 67fa83f7c86a86913ab9cd5a13b4bebd8d2ebb43 (patch) | |
tree | a08a7cdd4c208883f96a724379ff871cffe9a76a /net/ipv6/tcp_ipv6.c | |
parent | d6732b95b6fbbc6d5bb9d2f809e275763640c4a2 (diff) | |
download | linux-67fa83f7c86a86913ab9cd5a13b4bebd8d2ebb43.tar.gz linux-67fa83f7c86a86913ab9cd5a13b4bebd8d2ebb43.tar.bz2 linux-67fa83f7c86a86913ab9cd5a13b4bebd8d2ebb43.zip |
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 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index fa7050579e9a..b5936294dba2 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1154,17 +1154,19 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) #ifdef CONFIG_TCP_AO struct tcp_ao_info *ao_info; - /* FIXME: the segment to-be-acked is not verified yet */ - ao_info = rcu_dereference(tcptw->ao_info); - if (ao_info) { - const struct tcp_ao_hdr *aoh; + if (static_branch_unlikely(&tcp_ao_needed.key)) { - /* Invalid TCP option size or twice included auth */ - if (tcp_parse_auth_options(tcp_hdr(skb), NULL, &aoh)) - goto out; - if (aoh) { - key.ao_key = tcp_ao_established_key(ao_info, - aoh->rnext_keyid, -1); + /* FIXME: the segment to-be-acked is not verified yet */ + ao_info = rcu_dereference(tcptw->ao_info); + if (ao_info) { + const struct tcp_ao_hdr *aoh; + + /* Invalid TCP option size or twice included auth */ + if (tcp_parse_auth_options(tcp_hdr(skb), NULL, &aoh)) + goto out; + if (aoh) + key.ao_key = tcp_ao_established_key(ao_info, + aoh->rnext_keyid, -1); } } if (key.ao_key) { @@ -1206,7 +1208,8 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, struct tcp_key key = {}; #ifdef CONFIG_TCP_AO - if (tcp_rsk_used_ao(req)) { + if (static_branch_unlikely(&tcp_ao_needed.key) && + tcp_rsk_used_ao(req)) { const struct in6_addr *addr = &ipv6_hdr(skb)->saddr; const struct tcp_ao_hdr *aoh; int l3index; |