Page MenuHomeFreeBSD

D56168.id174578.diff
No OneTemporary

D56168.id174578.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
@@ -322,6 +322,7 @@
#define LINUX_TCP_KEEPCNT 6
#define LINUX_TCP_INFO 11
#define LINUX_TCP_MD5SIG 14
+#define LINUX_TCP_USER_TIMEOUT 18
struct l_ifmap {
l_ulong mem_start;
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
@@ -594,10 +594,34 @@
return (-2);
case LINUX_TCP_MD5SIG:
return (TCP_MD5SIG);
+ case LINUX_TCP_USER_TIMEOUT:
+ return (TCP_MAXUNACKTIME);
}
return (-1);
}
+static u_int
+linux_to_bsd_tcp_user_timeout(l_uint linux_timeout)
+{
+
+ /*
+ * Linux exposes TCP_USER_TIMEOUT in milliseconds while
+ * TCP_MAXUNACKTIME uses whole seconds. Round up partial
+ * seconds so a non-zero Linux timeout never becomes zero.
+ */
+ return (howmany(linux_timeout, 1000U));
+}
+
+static l_uint
+bsd_to_linux_tcp_user_timeout(u_int bsd_timeout)
+{
+
+ if (bsd_timeout > UINT_MAX / 1000U)
+ return (UINT_MAX);
+
+ return (bsd_timeout * 1000U);
+}
+
static int
linux_to_bsd_msg_flags(int flags)
{
@@ -2057,8 +2081,10 @@
struct proc *p = td->td_proc;
struct linux_pemuldata *pem;
l_timeval linux_tv;
+ l_uint linux_timeout;
struct sockaddr *sa;
struct timeval tv;
+ u_int bsd_timeout;
socklen_t len;
int error, level, name, val;
@@ -2146,6 +2172,20 @@
return (ENOPROTOOPT);
}
+ if (level == IPPROTO_TCP && args->optname == LINUX_TCP_USER_TIMEOUT) {
+ if (args->optlen < sizeof(linux_timeout))
+ return (EINVAL);
+
+ error = copyin(PTRIN(args->optval), &linux_timeout,
+ sizeof(linux_timeout));
+ if (error != 0)
+ return (error);
+
+ bsd_timeout = linux_to_bsd_tcp_user_timeout(linux_timeout);
+ return (kern_setsockopt(td, args->s, level, name,
+ &bsd_timeout, UIO_SYSSPACE, sizeof(bsd_timeout)));
+ }
+
switch (name) {
case IPV6_NEXTHOP: {
len = args->optlen;
@@ -2279,10 +2319,12 @@
int
linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
{
+ l_uint linux_timeout;
l_timeval linux_tv;
struct timeval tv;
socklen_t tv_len, xulen, len;
struct sockaddr *sa;
+ u_int bsd_timeout;
struct xucred xu;
struct l_ucred lxu;
int error, level, name, newval;
@@ -2386,6 +2428,18 @@
return (EINVAL);
}
+ if (level == IPPROTO_TCP && args->optname == LINUX_TCP_USER_TIMEOUT) {
+ len = sizeof(bsd_timeout);
+ error = kern_getsockopt(td, args->s, level, name,
+ &bsd_timeout, UIO_SYSSPACE, &len);
+ if (error != 0)
+ return (error);
+
+ linux_timeout = bsd_to_linux_tcp_user_timeout(bsd_timeout);
+ return (linux_sockopt_copyout(td, &linux_timeout,
+ sizeof(linux_timeout), args));
+ }
+
if (name == IPV6_NEXTHOP) {
error = copyin(PTRIN(args->optlen), &len, sizeof(len));
if (error != 0)

File Metadata

Mime Type
text/plain
Expires
Sat, Apr 25, 6:13 PM (5 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30642422
Default Alt Text
D56168.id174578.diff (2 KB)

Event Timeline