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 #ifdef CONFIG_TCP_NATA_URC
tcp_set_nata_urc(struct sock * sk,sockptr_t optval,int optlen)15 int tcp_set_nata_urc(struct sock *sk, sockptr_t optval, int optlen)
16 {
17 int err = -EINVAL;
18 struct tcp_nata_urc opt = {};
19 struct inet_connection_sock *icsk = inet_csk(sk);
20
21 if (optlen != sizeof(struct tcp_nata_urc))
22 return err;
23
24 if (copy_from_sockptr(&opt, optval, optlen))
25 return err;
26
27 if (!opt.nata_urc_enabled) {
28 icsk->nata_retries_enabled = opt.nata_urc_enabled;
29 icsk->nata_retries_type = NATA_NA;
30 icsk->icsk_syn_retries = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syn_retries);
31 icsk->nata_data_retries = 0;
32 icsk->nata_syn_rto = TCP_TIMEOUT_INIT;
33 icsk->nata_data_rto = TCP_TIMEOUT_INIT;
34 return 0;
35 }
36
37 if (opt.nata_rto_ms < NATA_URC_RTO_MS_MIN ||
38 opt.nata_rto_ms > NATA_URC_RTO_MS_MAX )
39 return err;
40
41 if (opt.nata_data_retries > NATA_DATA_RETRIES_MAX ||
42 opt.nata_syn_retries > NATA_SYN_RETRIES_MAX)
43 return err;
44
45 icsk->nata_retries_enabled = opt.nata_urc_enabled;
46 icsk->nata_retries_type = NATA_URC;
47 icsk->icsk_syn_retries = opt.nata_syn_retries;
48 icsk->nata_data_retries = opt.nata_data_retries;
49 icsk->nata_data_rto = opt.nata_rto_ms * HZ / NATA_URC_RTO_MS_TO_HZ;
50 icsk->nata_syn_rto = icsk->nata_data_rto;
51 return 0;
52 }
53 #endif /* CONFIG_TCP_NATA_URC */
54
55 #ifdef CONFIG_TCP_NATA_STL
tcp_set_nata_stl(struct sock * sk,sockptr_t optval,int optlen)56 int tcp_set_nata_stl(struct sock *sk, sockptr_t optval, int optlen)
57 {
58 int err = -EINVAL;
59 struct tcp_nata_stl opt = {};
60 struct inet_connection_sock *icsk = inet_csk(sk);
61
62 if (optlen != sizeof(struct tcp_nata_stl))
63 return err;
64
65 if (copy_from_sockptr(&opt, optval, optlen))
66 return err;
67
68 if (!opt.nata_stl_enabled) {
69 icsk->nata_retries_enabled = opt.nata_stl_enabled;
70 icsk->nata_retries_type = NATA_NA;
71 icsk->icsk_syn_retries = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syn_retries);
72 icsk->nata_data_retries = 0;
73 icsk->nata_syn_rto = TCP_TIMEOUT_INIT;
74 icsk->nata_data_rto = TCP_TIMEOUT_INIT;
75 return 0;
76 }
77
78 if ((opt.nata_syn_rto_ms < NATA_STL_SYN_RTO_MS_MIN ||
79 opt.nata_syn_rto_ms > NATA_STL_RTO_MS_MAX ||
80 opt.nata_data_rto_ms < NATA_STL_DATA_RTO_MS_MIN ||
81 opt.nata_data_rto_ms > NATA_STL_RTO_MS_MAX))
82 return err;
83
84 if (opt.nata_data_retries > NATA_DATA_RETRIES_MAX ||
85 opt.nata_syn_retries > NATA_SYN_RETRIES_MAX)
86 return err;
87
88 icsk->nata_retries_enabled = opt.nata_stl_enabled;
89 icsk->nata_retries_type = NATA_STL;
90 icsk->icsk_syn_retries = opt.nata_syn_retries;
91 icsk->nata_data_retries = opt.nata_data_retries;
92 icsk->nata_syn_rto = opt.nata_syn_rto_ms * HZ / NATA_STL_RTO_MS_TO_HZ;
93 icsk->nata_data_rto = opt.nata_data_rto_ms * HZ / NATA_STL_RTO_MS_TO_HZ;
94 return 0;
95 }
96 #endif /* CONFIG_TCP_NATA_STL */
97 #endif