• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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