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