summaryrefslogtreecommitdiff
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
authorDmitry Safonov <dima@arista.com>2023-10-23 20:22:14 +0100
committerDavid S. Miller <davem@davemloft.net>2023-10-27 10:35:46 +0100
commitfaadfaba5e018ca0f9595f17115ff48416b7b85e (patch)
tree537959a9c4010f3cdc0f07efdbdbafe7b04de766 /net/ipv4/tcp.c
parent248411b8cb8974a1e1c8e43123c1e682fbd64969 (diff)
net/tcp: Add TCP_AO_REPAIR
Add TCP_AO_REPAIR setsockopt(), getsockopt(). They let a user to repair TCP-AO ISNs/SNEs. Also let the user hack around when (tp->repair) is on and add ao_info on a socket in any supported state. As SNEs now can be read/written at any moment, use WRITE_ONCE()/READ_ONCE() to set/read them. 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.c')
-rw-r--r--net/ipv4/tcp.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index ce33eee9d0f2..53bcc17c91e4 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3593,20 +3593,28 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
__tcp_sock_set_quickack(sk, val);
break;
+ case TCP_AO_REPAIR:
+ err = tcp_ao_set_repair(sk, optval, optlen);
+ break;
#ifdef CONFIG_TCP_AO
case TCP_AO_ADD_KEY:
case TCP_AO_DEL_KEY:
case TCP_AO_INFO: {
/* If this is the first TCP-AO setsockopt() on the socket,
- * sk_state has to be LISTEN or CLOSE
+ * sk_state has to be LISTEN or CLOSE. Allow TCP_REPAIR
+ * in any state.
*/
- if (((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) ||
- rcu_dereference_protected(tcp_sk(sk)->ao_info,
+ if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))
+ goto ao_parse;
+ if (rcu_dereference_protected(tcp_sk(sk)->ao_info,
lockdep_sock_is_held(sk)))
- err = tp->af_specific->ao_parse(sk, optname, optval,
- optlen);
- else
- err = -EISCONN;
+ goto ao_parse;
+ if (tp->repair)
+ goto ao_parse;
+ err = -EISCONN;
+ break;
+ao_parse:
+ err = tp->af_specific->ao_parse(sk, optname, optval, optlen);
break;
}
#endif
@@ -4284,6 +4292,8 @@ zerocopy_rcv_out:
return err;
}
#endif
+ case TCP_AO_REPAIR:
+ return tcp_ao_get_repair(sk, optval, optlen);
case TCP_AO_GET_KEYS:
case TCP_AO_INFO: {
int err;