linux: Add TCP_INFO support
Implement the getsockopt for TCP_INFO by mapping FreeBSD's version to what Linux expects. MFC after: 1 month Relnotes: yes Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D55882
This commit is contained in:
@@ -591,9 +591,7 @@ linux_to_bsd_tcp_sockopt(int opt)
|
|||||||
case LINUX_TCP_KEEPCNT:
|
case LINUX_TCP_KEEPCNT:
|
||||||
return (TCP_KEEPCNT);
|
return (TCP_KEEPCNT);
|
||||||
case LINUX_TCP_INFO:
|
case LINUX_TCP_INFO:
|
||||||
LINUX_RATELIMIT_MSG_OPT1(
|
return (TCP_INFO);
|
||||||
"unsupported TCP socket option TCP_INFO (%d)", opt);
|
|
||||||
return (-2);
|
|
||||||
case LINUX_TCP_MD5SIG:
|
case LINUX_TCP_MD5SIG:
|
||||||
return (TCP_MD5SIG);
|
return (TCP_MD5SIG);
|
||||||
case LINUX_TCP_USER_TIMEOUT:
|
case LINUX_TCP_USER_TIMEOUT:
|
||||||
@@ -2407,6 +2405,42 @@ linux_getsockopt_so_linger(struct thread *td,
|
|||||||
return (linux_sockopt_copyout(td, &ling, len, args));
|
return (linux_sockopt_copyout(td, &ling, len, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
linux_getsockopt_tcp_info(struct thread *td,
|
||||||
|
struct linux_getsockopt_args *args)
|
||||||
|
{
|
||||||
|
struct tcp_info tinfo;
|
||||||
|
struct l_tcp_info l_tinfo;
|
||||||
|
socklen_t len;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
len = sizeof(tinfo);
|
||||||
|
error = kern_getsockopt(td, args->s, IPPROTO_TCP, TCP_INFO, &tinfo,
|
||||||
|
UIO_SYSSPACE, &len);
|
||||||
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
|
memset(&l_tinfo, 0, sizeof(l_tinfo));
|
||||||
|
l_tinfo.tcpi_state = tinfo.tcpi_state;
|
||||||
|
l_tinfo.tcpi_options = tinfo.tcpi_options;
|
||||||
|
l_tinfo.tcpi_snd_wscale = tinfo.tcpi_snd_wscale;
|
||||||
|
l_tinfo.tcpi_rcv_wscale = tinfo.tcpi_rcv_wscale;
|
||||||
|
l_tinfo.tcpi_rto = tinfo.tcpi_rto;
|
||||||
|
l_tinfo.tcpi_snd_mss = tinfo.tcpi_snd_mss;
|
||||||
|
l_tinfo.tcpi_rcv_mss = tinfo.tcpi_rcv_mss;
|
||||||
|
l_tinfo.tcpi_last_data_recv = tinfo.tcpi_last_data_recv;
|
||||||
|
l_tinfo.tcpi_rtt = tinfo.tcpi_rtt;
|
||||||
|
l_tinfo.tcpi_rttvar = tinfo.tcpi_rttvar;
|
||||||
|
l_tinfo.tcpi_snd_ssthresh = tinfo.tcpi_snd_ssthresh;
|
||||||
|
l_tinfo.tcpi_snd_cwnd = tinfo.tcpi_snd_cwnd;
|
||||||
|
l_tinfo.tcpi_rcv_space = tinfo.tcpi_rcv_space;
|
||||||
|
l_tinfo.tcpi_snd_wnd = tinfo.tcpi_snd_wnd;
|
||||||
|
l_tinfo.tcpi_rcv_ooopack = tinfo.tcpi_rcv_ooopack;
|
||||||
|
/* Eqivalent */
|
||||||
|
l_tinfo.tcpi_total_retrans = tinfo.tcpi_snd_rexmitpack;
|
||||||
|
|
||||||
|
return (linux_sockopt_copyout(td, &l_tinfo, len, args));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
|
linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
|
||||||
{
|
{
|
||||||
@@ -2505,6 +2539,13 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
|
|||||||
name = linux_to_bsd_ip6_sockopt(args->optname);
|
name = linux_to_bsd_ip6_sockopt(args->optname);
|
||||||
break;
|
break;
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
|
switch (args->optname) {
|
||||||
|
case LINUX_TCP_INFO:
|
||||||
|
return (linux_getsockopt_tcp_info(td, args));
|
||||||
|
/* NOTREACHED */
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
name = linux_to_bsd_tcp_sockopt(args->optname);
|
name = linux_to_bsd_tcp_sockopt(args->optname);
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case TCP_MAXUNACKTIME:
|
case TCP_MAXUNACKTIME:
|
||||||
|
|||||||
@@ -359,6 +359,98 @@ struct l_ifreq {
|
|||||||
} ifr_ifru;
|
} ifr_ifru;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Linux TCP_INFO structure as of v6.19.8
|
||||||
|
*
|
||||||
|
* Comments indicate last field for the given kernel version
|
||||||
|
*/
|
||||||
|
struct l_tcp_info {
|
||||||
|
uint8_t tcpi_state;
|
||||||
|
uint8_t tcpi_ca_state;
|
||||||
|
uint8_t tcpi_retransmits;
|
||||||
|
uint8_t tcpi_probes;
|
||||||
|
uint8_t tcpi_backoff;
|
||||||
|
uint8_t tcpi_options;
|
||||||
|
uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
|
||||||
|
uint8_t tcpi_delivery_rate_app_limited:1, tcpi_fastopen_client_fail:2;
|
||||||
|
|
||||||
|
uint32_t tcpi_rto;
|
||||||
|
uint32_t tcpi_ato;
|
||||||
|
uint32_t tcpi_snd_mss;
|
||||||
|
uint32_t tcpi_rcv_mss;
|
||||||
|
|
||||||
|
uint32_t tcpi_unacked;
|
||||||
|
uint32_t tcpi_sacked;
|
||||||
|
uint32_t tcpi_lost;
|
||||||
|
uint32_t tcpi_retrans;
|
||||||
|
uint32_t tcpi_fackets;
|
||||||
|
|
||||||
|
uint32_t tcpi_last_data_sent;
|
||||||
|
uint32_t tcpi_last_ack_sent;
|
||||||
|
uint32_t tcpi_last_data_recv;
|
||||||
|
uint32_t tcpi_last_ack_recv;
|
||||||
|
|
||||||
|
uint32_t tcpi_pmtu;
|
||||||
|
uint32_t tcpi_rcv_ssthresh;
|
||||||
|
uint32_t tcpi_rtt;
|
||||||
|
uint32_t tcpi_rttvar;
|
||||||
|
uint32_t tcpi_snd_ssthresh;
|
||||||
|
uint32_t tcpi_snd_cwnd;
|
||||||
|
uint32_t tcpi_advmss;
|
||||||
|
uint32_t tcpi_reordering;
|
||||||
|
|
||||||
|
uint32_t tcpi_rcv_rtt;
|
||||||
|
uint32_t tcpi_rcv_space;
|
||||||
|
|
||||||
|
uint32_t tcpi_total_retrans; /* v3.6 */
|
||||||
|
|
||||||
|
uint64_t tcpi_pacing_rate;
|
||||||
|
uint64_t tcpi_max_pacing_rate; /* v3.14 */
|
||||||
|
uint64_t tcpi_bytes_acked;
|
||||||
|
uint64_t tcpi_bytes_received;
|
||||||
|
uint32_t tcpi_segs_out;
|
||||||
|
uint32_t tcpi_segs_in; /* v4.1 */
|
||||||
|
|
||||||
|
uint32_t tcpi_notsent_bytes;
|
||||||
|
uint32_t tcpi_min_rtt;
|
||||||
|
uint32_t tcpi_data_segs_in;
|
||||||
|
uint32_t tcpi_data_segs_out; /* v4.5 */
|
||||||
|
|
||||||
|
uint64_t tcpi_delivery_rate; /* v4.8 */
|
||||||
|
|
||||||
|
uint64_t tcpi_busy_time;
|
||||||
|
uint64_t tcpi_rwnd_limited;
|
||||||
|
uint64_t tcpi_sndbuf_limited; /* v4.9 */
|
||||||
|
|
||||||
|
uint32_t tcpi_delivered;
|
||||||
|
uint32_t tcpi_delivered_ce; /* v4.16 */
|
||||||
|
|
||||||
|
uint64_t tcpi_bytes_sent;
|
||||||
|
uint64_t tcpi_bytes_retrans;
|
||||||
|
uint32_t tcpi_dsack_dups;
|
||||||
|
uint32_t tcpi_reord_seen; /* v4.18 */
|
||||||
|
|
||||||
|
uint32_t tcpi_rcv_ooopack;
|
||||||
|
|
||||||
|
uint32_t tcpi_snd_wnd; /* v5.3 */
|
||||||
|
uint32_t tcpi_rcv_wnd;
|
||||||
|
|
||||||
|
uint32_t tcpi_rehash; /* v6.1 */
|
||||||
|
|
||||||
|
uint16_t tcpi_total_rto;
|
||||||
|
uint16_t tcpi_total_rto_recoveries;
|
||||||
|
uint32_t tcpi_total_rto_time; /* v6.6 */
|
||||||
|
uint32_t tcpi_received_ce;
|
||||||
|
uint32_t tcpi_delivered_e1_bytes;
|
||||||
|
uint32_t tcpi_delivered_e0_bytes;
|
||||||
|
uint32_t tcpi_delivered_ce_bytes;
|
||||||
|
uint32_t tcpi_received_e1_bytes;
|
||||||
|
uint32_t tcpi_received_e0_bytes;
|
||||||
|
uint32_t tcpi_received_ce_bytes;
|
||||||
|
uint16_t tcpi_accecn_fail_mode;
|
||||||
|
uint16_t tcpi_accecn_opt_seen; /* v6.17 */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define here members which are not exists in the FreeBSD struct ifreq.
|
* Define here members which are not exists in the FreeBSD struct ifreq.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user