summaryrefslogtreecommitdiff
path: root/net/ipv4/tcp_input.c
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/ipv4/tcp_input.c
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/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 67ca72185f14..50aaa1527150 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3572,41 +3572,55 @@ static inline bool tcp_may_update_window(const struct tcp_sock *tp,
(ack_seq == tp->snd_wl1 && (nwin > tp->snd_wnd || !nwin));
}
-/* If we update tp->snd_una, also update tp->bytes_acked */
-static void tcp_snd_una_update(struct tcp_sock *tp, u32 ack)
+static void tcp_snd_sne_update(struct tcp_sock *tp, u32 ack)
{
- u32 delta = ack - tp->snd_una;
#ifdef CONFIG_TCP_AO
struct tcp_ao_info *ao;
-#endif
- sock_owned_by_me((struct sock *)tp);
- tp->bytes_acked += delta;
-#ifdef CONFIG_TCP_AO
+ if (!static_branch_unlikely(&tcp_ao_needed.key))
+ return;
+
ao = rcu_dereference_protected(tp->ao_info,
lockdep_sock_is_held((struct sock *)tp));
if (ao && ack < tp->snd_una)
ao->snd_sne++;
#endif
+}
+
+/* If we update tp->snd_una, also update tp->bytes_acked */
+static void tcp_snd_una_update(struct tcp_sock *tp, u32 ack)
+{
+ u32 delta = ack - tp->snd_una;
+
+ sock_owned_by_me((struct sock *)tp);
+ tp->bytes_acked += delta;
+ tcp_snd_sne_update(tp, ack);
tp->snd_una = ack;
}
-/* If we update tp->rcv_nxt, also update tp->bytes_received */
-static void tcp_rcv_nxt_update(struct tcp_sock *tp, u32 seq)
+static void tcp_rcv_sne_update(struct tcp_sock *tp, u32 seq)
{
- u32 delta = seq - tp->rcv_nxt;
#ifdef CONFIG_TCP_AO
struct tcp_ao_info *ao;
-#endif
- sock_owned_by_me((struct sock *)tp);
- tp->bytes_received += delta;
-#ifdef CONFIG_TCP_AO
+ if (!static_branch_unlikely(&tcp_ao_needed.key))
+ return;
+
ao = rcu_dereference_protected(tp->ao_info,
lockdep_sock_is_held((struct sock *)tp));
if (ao && seq < tp->rcv_nxt)
ao->rcv_sne++;
#endif
+}
+
+/* If we update tp->rcv_nxt, also update tp->bytes_received */
+static void tcp_rcv_nxt_update(struct tcp_sock *tp, u32 seq)
+{
+ u32 delta = seq - tp->rcv_nxt;
+
+ sock_owned_by_me((struct sock *)tp);
+ tp->bytes_received += delta;
+ tcp_rcv_sne_update(tp, seq);
WRITE_ONCE(tp->rcv_nxt, seq);
}