summaryrefslogtreecommitdiff
path: root/net/ipv6
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 /net/ipv6
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 'net/ipv6')
-rw-r--r--net/ipv6/tcp_ipv6.c25
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;