Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F156481652
D55882.id173764.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D55882.id173764.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Thu, May 14, 11:41 PM (5 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29841227
Default Alt Text
D55882.id173764.diff (6 KB)
Attached To
Mode
D55882: linux: Add TCP_INFO support
Attached
Detach File
Event Timeline
Log In to Comment