Page MenuHomeFreeBSD

D55882.id173764.diff
No OneTemporary

D55882.id173764.diff

diff --git a/sys/compat/linux/linux_socket.h b/sys/compat/linux/linux_socket.h
--- a/sys/compat/linux/linux_socket.h
+++ b/sys/compat/linux/linux_socket.h
@@ -356,6 +356,98 @@
} 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.
*/
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -589,9 +589,7 @@
case LINUX_TCP_KEEPCNT:
return (TCP_KEEPCNT);
case LINUX_TCP_INFO:
- LINUX_RATELIMIT_MSG_OPT1(
- "unsupported TCP socket option TCP_INFO (%d)", opt);
- return (-2);
+ return (TCP_INFO);
case LINUX_TCP_MD5SIG:
return (TCP_MD5SIG);
}
@@ -2281,6 +2279,76 @@
return (linux_sockopt_copyout(td, &ling, len, args));
}
+static socklen_t
+linux_tcp_info_length(struct thread *td)
+{
+ int version = linux_kernver(td);
+
+ if (version >= LINUX_KERNVER(6,17,0))
+ return (sizeof(struct l_tcp_info));
+ else if (version >= LINUX_KERNVER(6,6,0))
+ return (offsetof(struct l_tcp_info, tcpi_received_ce));
+ else if (version >= LINUX_KERNVER(6,1,0))
+ return (offsetof(struct l_tcp_info, tcpi_total_rto));
+ else if (version >= LINUX_KERNVER(5,3,0))
+ return (offsetof(struct l_tcp_info, tcpi_rcv_wnd));
+ else if (version >= LINUX_KERNVER(4,18,0))
+ return (offsetof(struct l_tcp_info, tcpi_rcv_ooopack));
+ else if (version >= LINUX_KERNVER(4,16,0))
+ return (offsetof(struct l_tcp_info, tcpi_bytes_sent));
+ else if (version >= LINUX_KERNVER(4,9,0))
+ return (offsetof(struct l_tcp_info, tcpi_delivered));
+ else if (version >= LINUX_KERNVER(4,8,0))
+ return (offsetof(struct l_tcp_info, tcpi_busy_time));
+ else if (version >= LINUX_KERNVER(4,5,0))
+ return (offsetof(struct l_tcp_info, tcpi_delivery_rate));
+ else if (version >= LINUX_KERNVER(4,1,0))
+ return (offsetof(struct l_tcp_info, tcpi_notsent_bytes));
+ else if (version >= LINUX_KERNVER(3,14,0))
+ return (offsetof(struct l_tcp_info, tcpi_bytes_acked));
+ else if (version >= LINUX_KERNVER(3,6,0))
+ return (offsetof(struct l_tcp_info, tcpi_pacing_rate));
+ else
+ return (offsetof(struct l_tcp_info, tcpi_total_retrans));
+}
+
+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;
+
+ len = linux_tcp_info_length(td);
+ return (linux_sockopt_copyout(td, &l_tinfo, len, args));
+}
+
int
linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
{
@@ -2377,6 +2445,13 @@
name = linux_to_bsd_ip6_sockopt(args->optname);
break;
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);
break;
default:

File Metadata

Mime Type
text/plain
Expires
Thu, May 14, 10:56 PM (6 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29841227
Default Alt Text
D55882.id173764.diff (6 KB)

Event Timeline