xref: /kernel/linux/linux-5.10/net/ipv4/nata.c (revision 8c2ecf20)
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2024 Huawei Device Co., Ltd.
4 *
5 * Network and Application-driven Transport Augmentation (NATA).
6 * Authors: yangyanjun
7 */
8#if defined(CONFIG_TCP_NATA_URC) || defined(CONFIG_TCP_NATA_STL)
9#include <net/inet_sock.h>
10#include <net/sock.h>
11#include <net/nata.h>
12#include <net/tcp.h>
13
14#define NATA_THIN_STREAM 4
15bool nata_thin_stream_check(struct sock *sk)
16{
17	struct tcp_sock *tp = tcp_sk(sk);
18	/* The server side focuses on syn-ack retransmission,
19	 * and the client side focuses on syn retransmission.
20	 */
21	if ((sk->sk_state == TCP_ESTABLISHED &&
22	    tp->packets_out <= NATA_THIN_STREAM) ||
23	    sk->sk_state == TCP_SYN_SENT)
24		return true;
25	return false;
26}
27
28#ifdef CONFIG_TCP_NATA_URC
29int tcp_set_nata_urc(struct sock *sk, sockptr_t optval, int optlen)
30{
31	int err = -EINVAL;
32	struct tcp_nata_urc opt = {};
33	struct inet_connection_sock *icsk = inet_csk(sk);
34
35	if (optlen != sizeof(struct tcp_nata_urc))
36		return err;
37
38	if (copy_from_sockptr(&opt, optval, optlen))
39		return err;
40
41	if (!opt.nata_urc_enabled) {
42		icsk->nata_retries_enabled = opt.nata_urc_enabled;
43		icsk->nata_retries_type = NATA_NA;
44		icsk->icsk_syn_retries = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syn_retries);
45		icsk->nata_data_retries = 0;
46		icsk->nata_syn_rto = TCP_TIMEOUT_INIT;
47		icsk->nata_data_rto = TCP_TIMEOUT_INIT;
48		return 0;
49	}
50
51	if (opt.nata_rto_ms < NATA_URC_RTO_MS_MIN ||
52		opt.nata_rto_ms > NATA_URC_RTO_MS_MAX )
53		return err;
54
55	if (opt.nata_data_retries > NATA_DATA_RETRIES_MAX ||
56		opt.nata_syn_retries > NATA_SYN_RETRIES_MAX)
57		return err;
58
59	icsk->nata_retries_enabled = opt.nata_urc_enabled;
60	icsk->nata_retries_type = NATA_URC;
61	icsk->icsk_syn_retries = opt.nata_syn_retries;
62	icsk->nata_data_retries = opt.nata_data_retries;
63	icsk->nata_data_rto = opt.nata_rto_ms * HZ / NATA_URC_RTO_MS_TO_HZ;
64	icsk->nata_syn_rto = icsk->nata_data_rto;
65	return 0;
66}
67#endif /* CONFIG_TCP_NATA_URC */
68
69#ifdef CONFIG_TCP_NATA_STL
70int tcp_set_nata_stl(struct sock *sk, sockptr_t optval, int optlen)
71{
72	int err = -EINVAL;
73	struct tcp_nata_stl opt = {};
74	struct inet_connection_sock *icsk = inet_csk(sk);
75
76	if (optlen != sizeof(struct tcp_nata_stl))
77		return err;
78
79	if (copy_from_sockptr(&opt, optval, optlen))
80		return err;
81
82	if (!opt.nata_stl_enabled) {
83		icsk->nata_retries_enabled = opt.nata_stl_enabled;
84		icsk->nata_retries_type = NATA_NA;
85		icsk->icsk_syn_retries = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syn_retries);
86		icsk->nata_data_retries = 0;
87		icsk->nata_syn_rto = TCP_TIMEOUT_INIT;
88		icsk->nata_data_rto = TCP_TIMEOUT_INIT;
89		return 0;
90	}
91
92	if ((opt.nata_syn_rto_ms < NATA_STL_SYN_RTO_MS_MIN ||
93		opt.nata_syn_rto_ms > NATA_STL_RTO_MS_MAX ||
94		opt.nata_data_rto_ms < NATA_STL_DATA_RTO_MS_MIN ||
95		opt.nata_data_rto_ms > NATA_STL_RTO_MS_MAX))
96		return err;
97
98	if (opt.nata_data_retries > NATA_DATA_RETRIES_MAX ||
99		opt.nata_syn_retries > NATA_SYN_RETRIES_MAX)
100		return err;
101
102	icsk->nata_retries_enabled = opt.nata_stl_enabled;
103	icsk->nata_retries_type = NATA_STL;
104	icsk->icsk_syn_retries = opt.nata_syn_retries;
105	icsk->nata_data_retries = opt.nata_data_retries;
106	icsk->nata_syn_rto = opt.nata_syn_rto_ms * HZ / NATA_STL_RTO_MS_TO_HZ;
107	icsk->nata_data_rto = opt.nata_data_rto_ms * HZ / NATA_STL_RTO_MS_TO_HZ;
108	return 0;
109}
110#endif /* CONFIG_TCP_NATA_STL */
111#endif