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
nata_thin_stream_check(struct sock * sk)15 bool 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
29 int na_push_rto_ms __read_mostly = 200;
30 module_param(na_push_rto_ms, int, 0644);
31 MODULE_PARM_DESC(na_push_rto_ms, "config the max rto, default 200ms, < 150 means disable");
32 EXPORT_SYMBOL(na_push_rto_ms);
33
34 int na_push_data_retries __read_mostly = 10;
35 module_param(na_push_data_retries, int, 0644);
36 MODULE_PARM_DESC(na_push_data_retries, "config the data-pkt fast retransmit change times, default 10, 0 means disable, cannot greater than 50");
37 EXPORT_SYMBOL(na_push_data_retries);
38
39 int na_push_syn_retries __read_mostly = 16;
40 module_param(na_push_syn_retries, int, 0644);
41 MODULE_PARM_DESC(na_push_syn_retries, "config the syn-pkt max reties, default 16, 0 means disable, cannot greater than 50");
42 EXPORT_SYMBOL(na_push_syn_retries);
43
44 static int na_push_port_list[PUSH_PORT_CNT_MAX] __read_mostly = {0};
45 static int na_push_port_count = PUSH_PORT_CNT_MAX;
46 module_param_array(na_push_port_list, int, &na_push_port_count, 0644);
47 MODULE_PARM_DESC(na_push_port_list, "config listen port list, up to 10 elms");
48
na_push_port_check(__u16 port)49 bool na_push_port_check(__u16 port)
50 {
51 int i;
52 for (i = 0; i < na_push_port_count; i++) {
53 if (na_push_port_list[i] && na_push_port_list[i] == port)
54 return true;
55 }
56
57 return false;
58 }
59
tcp_set_nata_push_urc(struct sock * sk)60 void tcp_set_nata_push_urc(struct sock *sk)
61 {
62 struct inet_connection_sock *icsk = inet_csk(sk);
63
64 if (!na_push_port_check(ntohs(icsk->icsk_inet.inet_dport)))
65 return ;
66
67 if (na_push_rto_ms < NATA_URC_RTO_MS_MIN) {
68 na_push_rto_ms = NATA_URC_RTO_MS_MIN;
69 } else if (na_push_rto_ms > NATA_URC_RTO_MS_MAX) {
70 na_push_rto_ms = NATA_URC_RTO_MS_MAX;
71 }
72
73 if (na_push_data_retries > NATA_DATA_RETRIES_MAX)
74 na_push_data_retries = NATA_DATA_RETRIES_MAX;
75
76 if (na_push_syn_retries > NATA_SYN_RETRIES_MAX)
77 na_push_syn_retries = NATA_SYN_RETRIES_MAX;
78
79 icsk->nata_retries_enabled = true;
80 icsk->nata_retries_type = NATA_URC;
81 icsk->icsk_syn_retries = na_push_syn_retries;
82 icsk->nata_data_retries = na_push_data_retries;
83 icsk->nata_data_rto = na_push_rto_ms * HZ / NATA_URC_RTO_MS_TO_HZ;
84 icsk->nata_syn_rto = na_push_rto_ms;
85 }
86
tcp_set_nata_urc(struct sock * sk,sockptr_t optval,int optlen)87 int tcp_set_nata_urc(struct sock *sk, sockptr_t optval, int optlen)
88 {
89 int err = -EINVAL;
90 struct tcp_nata_urc opt = {};
91 struct inet_connection_sock *icsk = inet_csk(sk);
92
93 if (optlen != sizeof(struct tcp_nata_urc))
94 return err;
95
96 if (copy_from_sockptr(&opt, optval, optlen))
97 return err;
98
99 if (!opt.nata_urc_enabled) {
100 icsk->nata_retries_enabled = opt.nata_urc_enabled;
101 icsk->nata_retries_type = NATA_NA;
102 icsk->icsk_syn_retries = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syn_retries);
103 icsk->nata_data_retries = 0;
104 icsk->nata_syn_rto = TCP_TIMEOUT_INIT;
105 icsk->nata_data_rto = TCP_TIMEOUT_INIT;
106 return 0;
107 }
108
109 if (opt.nata_rto_ms < NATA_URC_RTO_MS_MIN ||
110 opt.nata_rto_ms > NATA_URC_RTO_MS_MAX )
111 return err;
112
113 if (opt.nata_data_retries > NATA_DATA_RETRIES_MAX ||
114 opt.nata_syn_retries > NATA_SYN_RETRIES_MAX)
115 return err;
116
117 icsk->nata_retries_enabled = opt.nata_urc_enabled;
118 icsk->nata_retries_type = NATA_URC;
119 icsk->icsk_syn_retries = opt.nata_syn_retries;
120 icsk->nata_data_retries = opt.nata_data_retries;
121 icsk->nata_data_rto = opt.nata_rto_ms * HZ / NATA_URC_RTO_MS_TO_HZ;
122 icsk->nata_syn_rto = icsk->nata_data_rto;
123 return 0;
124 }
125 #endif /* CONFIG_TCP_NATA_URC */
126
127 #ifdef CONFIG_TCP_NATA_STL
tcp_set_nata_stl(struct sock * sk,sockptr_t optval,int optlen)128 int tcp_set_nata_stl(struct sock *sk, sockptr_t optval, int optlen)
129 {
130 int err = -EINVAL;
131 struct tcp_nata_stl opt = {};
132 struct inet_connection_sock *icsk = inet_csk(sk);
133
134 if (optlen != sizeof(struct tcp_nata_stl))
135 return err;
136
137 if (copy_from_sockptr(&opt, optval, optlen))
138 return err;
139
140 if (!opt.nata_stl_enabled) {
141 icsk->nata_retries_enabled = opt.nata_stl_enabled;
142 icsk->nata_retries_type = NATA_NA;
143 icsk->icsk_syn_retries = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syn_retries);
144 icsk->nata_data_retries = 0;
145 icsk->nata_syn_rto = TCP_TIMEOUT_INIT;
146 icsk->nata_data_rto = TCP_TIMEOUT_INIT;
147 return 0;
148 }
149
150 if ((opt.nata_syn_rto_ms < NATA_STL_SYN_RTO_MS_MIN ||
151 opt.nata_syn_rto_ms > NATA_STL_RTO_MS_MAX ||
152 opt.nata_data_rto_ms < NATA_STL_DATA_RTO_MS_MIN ||
153 opt.nata_data_rto_ms > NATA_STL_RTO_MS_MAX))
154 return err;
155
156 if (opt.nata_data_retries > NATA_DATA_RETRIES_MAX ||
157 opt.nata_syn_retries > NATA_SYN_RETRIES_MAX)
158 return err;
159
160 icsk->nata_retries_enabled = opt.nata_stl_enabled;
161 icsk->nata_retries_type = NATA_STL;
162 icsk->icsk_syn_retries = opt.nata_syn_retries;
163 icsk->nata_data_retries = opt.nata_data_retries;
164 icsk->nata_syn_rto = opt.nata_syn_rto_ms * HZ / NATA_STL_RTO_MS_TO_HZ;
165 icsk->nata_data_rto = opt.nata_data_rto_ms * HZ / NATA_STL_RTO_MS_TO_HZ;
166 return 0;
167 }
168 #endif /* CONFIG_TCP_NATA_STL */
169 #endif