aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/compat/linux/linux_emul.h1
-rw-r--r--sys/compat/linux/linux_socket.c62
-rw-r--r--sys/compat/linux/linux_socket.h4
3 files changed, 67 insertions, 0 deletions
diff --git a/sys/compat/linux/linux_emul.h b/sys/compat/linux/linux_emul.h
index e801bf09ba72..9b552ab9c720 100644
--- a/sys/compat/linux/linux_emul.h
+++ b/sys/compat/linux/linux_emul.h
@@ -77,6 +77,7 @@ struct linux_pemuldata {
uint32_t ptrace_flags; /* used by ptrace(2) */
uint32_t oom_score_adj; /* /proc/self/oom_score_adj */
uint32_t so_timestamp; /* requested timeval */
+ uint32_t so_timestampns; /* requested timespec */
};
#define LINUX_PEM_XLOCK(p) sx_xlock(&(p)->pem_sx)
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index 3360cf48cb16..14f034eb8037 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -551,6 +551,9 @@ linux_to_bsd_so_sockopt(int opt)
case LINUX_SO_TIMESTAMPO:
case LINUX_SO_TIMESTAMPN:
return (SO_TIMESTAMP);
+ case LINUX_SO_TIMESTAMPNSO:
+ case LINUX_SO_TIMESTAMPNSN:
+ return (SO_BINTIME);
case LINUX_SO_ACCEPTCONN:
return (SO_ACCEPTCONN);
case LINUX_SO_PROTOCOL:
@@ -661,6 +664,8 @@ bsd_to_linux_cmsg_type(struct proc *p, int cmsg_type)
return (LINUX_SCM_CREDENTIALS);
case SCM_TIMESTAMP:
return (pem->so_timestamp);
+ case SCM_BINTIME:
+ return (pem->so_timestampns);
}
return (-1);
}
@@ -1554,6 +1559,7 @@ recvmsg_scm_rights(struct thread *td, l_uint flags, socklen_t *datalen,
return (0);
}
+
static int
recvmsg_scm_creds(socklen_t *datalen, void **data, void **udata)
{
@@ -1632,6 +1638,53 @@ _Static_assert(sizeof(struct timeval) == sizeof(l_timeval),
"scm_timestamp sizeof l_timeval");
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+static int
+recvmsg_scm_timestampns(l_int msg_type, socklen_t *datalen, void **data,
+ void **udata)
+{
+ struct l_timespec64 ts64;
+ struct l_timespec ts32;
+ struct timespec ts;
+ socklen_t len;
+ void *buf;
+
+ if (msg_type == LINUX_SCM_TIMESTAMPNSO)
+ len = sizeof(ts32);
+ else
+ len = sizeof(ts64);
+
+ buf = malloc(len, M_LINUX, M_WAITOK);
+ bintime2timespec(*data, &ts);
+ if (msg_type == LINUX_SCM_TIMESTAMPNSO) {
+ ts32.tv_sec = ts.tv_sec;
+ ts32.tv_nsec = ts.tv_nsec;
+ memmove(buf, &ts32, len);
+ } else {
+ ts64.tv_sec = ts.tv_sec;
+ ts64.tv_nsec = ts.tv_nsec;
+ memmove(buf, &ts64, len);
+ }
+ *data = *udata = buf;
+ *datalen = len;
+ return (0);
+}
+#else
+static int
+recvmsg_scm_timestampns(l_int msg_type, socklen_t *datalen, void **data,
+ void **udata)
+{
+ struct timespec ts;
+
+ bintime2timespec(*data, &ts);
+ memmove(*data, &ts, sizeof(struct timespec));
+ *datalen = sizeof(struct timespec);
+ return (0);
+}
+_Static_assert(sizeof(struct bintime) >= sizeof(struct timespec),
+ "scm_timestampns sizeof timespec");
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
+
static int
linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
l_uint flags, struct msghdr *msg)
@@ -1755,6 +1808,11 @@ linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
&datalen, &data, &udata);
#endif
break;
+
+ case SCM_BINTIME:
+ error = recvmsg_scm_timestampns(linux_cmsg->cmsg_type,
+ &datalen, &data, &udata);
+ break;
}
if (error != 0)
goto bad;
@@ -1960,6 +2018,10 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
pem = pem_find(p);
pem->so_timestamp = args->optname;
break;
+ case SO_BINTIME:
+ pem = pem_find(p);
+ pem->so_timestampns = args->optname;
+ break;
default:
break;
}
diff --git a/sys/compat/linux/linux_socket.h b/sys/compat/linux/linux_socket.h
index 77537afad6ee..ef0c1f24f10a 100644
--- a/sys/compat/linux/linux_socket.h
+++ b/sys/compat/linux/linux_socket.h
@@ -189,6 +189,8 @@ int linux_accept(struct thread *td, struct linux_accept_args *args);
#endif
#define LINUX_SO_TIMESTAMPO 29
#define LINUX_SO_TIMESTAMPN 63
+#define LINUX_SO_TIMESTAMPNSO 35
+#define LINUX_SO_TIMESTAMPNSN 64
#define LINUX_SO_ACCEPTCONN 30
#define LINUX_SO_PEERSEC 31
#define LINUX_SO_SNDBUFFORCE 32
@@ -203,6 +205,8 @@ int linux_accept(struct thread *td, struct linux_accept_args *args);
#define LINUX_SCM_CREDENTIALS 0x02
#define LINUX_SCM_TIMESTAMPO LINUX_SO_TIMESTAMPO
#define LINUX_SCM_TIMESTAMPN LINUX_SO_TIMESTAMPN
+#define LINUX_SCM_TIMESTAMPNSO LINUX_SO_TIMESTAMPNSO
+#define LINUX_SCM_TIMESTAMPNSN LINUX_SO_TIMESTAMPNSN
/* Socket options */
#define LINUX_IP_TOS 1