From patchwork Tue Jan 8 03:26:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepa Dinamani X-Patchwork-Id: 10751367 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2FEB817D2 for ; Tue, 8 Jan 2019 03:28:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 20499208C2 for ; Tue, 8 Jan 2019 03:28:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 13E7D28A3F; Tue, 8 Jan 2019 03:28:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9E69528A53 for ; Tue, 8 Jan 2019 03:28:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727747AbfAHD1x (ORCPT ); Mon, 7 Jan 2019 22:27:53 -0500 Received: from mail-pf1-f194.google.com ([209.85.210.194]:33082 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727423AbfAHD1w (ORCPT ); Mon, 7 Jan 2019 22:27:52 -0500 Received: by mail-pf1-f194.google.com with SMTP id c123so1216868pfb.0; Mon, 07 Jan 2019 19:27:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=n6LaIK/I0WtTdwZzUGayiTYIbKGKG8L+BLqXPg6YPPc=; b=sOt7vmgAHNojXxtjvRVtqrqz7lmYsPJZqLRbedOnXMg76AymfptJ8YS6V5r1dizTKq ljQhx5daac+FCnbH42eubUrcTMwKyUnqyFOfN1PKLzyQxw4Ws34RiAoHUfde1QjhCPNH ZoCiiHMbXfo/sCsMjezQQwTjtzUThmASN20y1wVOF+nOXJd/imvSRDZAj5dPF+EMotLj T7Pa85oCCozCVSJwU0xhifdi1J7dBfc9EgptyB/r5LRGKiXM/zT1N3WfAewA9IXABK+/ fpYUHLWT8Y+/EZ13qmdkKtfq2tV7DvCpVZU5Ch9oGjBuz+NrVc8Eg6CkSylrh9cCeDRy WjVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=n6LaIK/I0WtTdwZzUGayiTYIbKGKG8L+BLqXPg6YPPc=; b=jagVFW67Yn1ZRjstwcQ8yLrR0qCI0aNIM9LNr6PChw4ZSJnUZxjexgmTBaWvB5oKIY ZPB+IicSzhDcEr0+tYFkFv3DM9/kHTrwJFXO51YGLBqliAs6BepHSwFGC/idLTvZvScw oIkKmg611j5Csqkq1pLppXssbJ3xLOUEVyPVJQ+TCR+dOLFcFXkVSMDaaxu9mdfSfG3l b2YaytsRMPUvPCorM1PWPzL+gMSeS62tEgQiTfeKsAoyiGkRU2lL5ncZuG0eTRKEKKeJ bFyZOz0lueoMp1kRpTxhVNIA/xtVyAFa8LHmYTbwRMjBl44uqSjjhGNpItWNotwFtc9g Ipmg== X-Gm-Message-State: AJcUukegwpqV8H3x13XFaE2tPUqTLJ+coKhYLTsd7S7zPIv9KoyLzFRI lPctx8V+ZNmQb78x3dnipl8= X-Google-Smtp-Source: ALg8bN5b0SjC6qkz+SUM+1lo4T7uF2lBRChK0CSMVGm142MiqfQn9ZgrofH/zaC4c9jy8ixx8UUeZw== X-Received: by 2002:a63:5346:: with SMTP id t6mr108260pgl.40.1546918070774; Mon, 07 Jan 2019 19:27:50 -0800 (PST) Received: from deepa-ubuntu.lan (c-98-234-52-230.hsd1.ca.comcast.net. [98.234.52.230]) by smtp.gmail.com with ESMTPSA id v5sm117327735pgn.5.2019.01.07.19.27.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 07 Jan 2019 19:27:50 -0800 (PST) From: Deepa Dinamani To: davem@davemloft.net, linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org, arnd@arndb.de, y2038@lists.linaro.org, jejb@parisc-linux.org, ralf@linux-mips.org, rth@twiddle.net, linux-alpha@vger.kernel.org, linux-mips@linux-mips.org, linux-parisc@vger.kernel.org, linux-rdma@vger.kernel.org, sparclinux@vger.kernel.org Subject: [PATCH v3 6/8] socket: Add SO_TIMESTAMP[NS]_NEW Date: Mon, 7 Jan 2019 19:26:55 -0800 Message-Id: <20190108032657.8331-7-deepa.kernel@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190108032657.8331-1-deepa.kernel@gmail.com> References: <20190108032657.8331-1-deepa.kernel@gmail.com> Sender: linux-parisc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-parisc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add SO_TIMESTAMP_NEW and SO_TIMESTAMPNS_NEW variants of socket timestamp options. These are the y2038 safe versions of the SO_TIMESTAMP_OLD and SO_TIMESTAMPNS_OLD for all architectures. Note that the format of scm_timestamping.ts[0] is not changed in this patch. Signed-off-by: Deepa Dinamani Cc: jejb@parisc-linux.org Cc: ralf@linux-mips.org Cc: rth@twiddle.net Cc: linux-alpha@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: linux-parisc@vger.kernel.org Cc: linux-rdma@vger.kernel.org Cc: netdev@vger.kernel.org Cc: sparclinux@vger.kernel.org --- arch/alpha/include/uapi/asm/socket.h | 15 ++++++++++-- arch/mips/include/uapi/asm/socket.h | 14 +++++++++-- arch/parisc/include/uapi/asm/socket.h | 14 +++++++++-- arch/sparc/include/uapi/asm/socket.h | 14 +++++++++-- include/linux/skbuff.h | 18 ++++++++++++++ include/net/sock.h | 1 + include/uapi/asm-generic/socket.h | 15 ++++++++++-- net/core/sock.c | 21 ++++++++++++++-- net/ipv4/tcp.c | 35 +++++++++++++++++++++------ net/rds/af_rds.c | 8 ++++-- net/rds/recv.c | 16 ++++++++++-- net/socket.c | 35 +++++++++++++++++++++------ 12 files changed, 174 insertions(+), 32 deletions(-) diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index 00e45c80e574..352e3dc0b3d9 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -3,6 +3,7 @@ #define _UAPI_ASM_SOCKET_H #include +#include /* For setsockopt(2) */ /* @@ -110,12 +111,22 @@ #define SO_TIMESTAMP_OLD 29 #define SO_TIMESTAMPNS_OLD 35 + #define SO_TIMESTAMPING_OLD 37 +#define SO_TIMESTAMP_NEW 62 +#define SO_TIMESTAMPNS_NEW 63 + #if !defined(__KERNEL__) -#define SO_TIMESTAMP SO_TIMESTAMP_OLD -#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD +#if __BITS_PER_LONG == 64 +#define SO_TIMESTAMP SO_TIMESTAMP_OLD +#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD +#else +#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW) +#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW) +#endif + #define SO_TIMESTAMPING SO_TIMESTAMPING_OLD #define SCM_TIMESTAMP SO_TIMESTAMP diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index b9553f770346..d1752e3f1248 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h @@ -11,6 +11,7 @@ #define _UAPI_ASM_SOCKET_H #include +#include /* * For setsockopt(2) @@ -123,10 +124,19 @@ #define SO_TIMESTAMPNS_OLD 35 #define SO_TIMESTAMPING_OLD 37 +#define SO_TIMESTAMP_NEW 62 +#define SO_TIMESTAMPNS_NEW 63 + #if !defined(__KERNEL__) -#define SO_TIMESTAMP SO_TIMESTAMP_OLD -#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD +#if __BITS_PER_LONG == 64 +#define SO_TIMESTAMP SO_TIMESTAMP_OLD +#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD +#else +#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW) +#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW) +#endif + #define SO_TIMESTAMPING SO_TIMESTAMPING_OLD #define SCM_TIMESTAMP SO_TIMESTAMP diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index 37cdfe64bb27..0a45b668abd1 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -3,6 +3,7 @@ #define _UAPI_ASM_SOCKET_H #include +#include /* For setsockopt(2) */ #define SOL_SOCKET 0xffff @@ -104,10 +105,19 @@ #define SO_TIMESTAMPNS_OLD 0x4013 #define SO_TIMESTAMPING_OLD 0x4020 +#define SO_TIMESTAMP_NEW 0x4037 +#define SO_TIMESTAMPNS_NEW 0x4038 + #if !defined(__KERNEL__) -#define SO_TIMESTAMP SO_TIMESTAMP_OLD -#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD +#if __BITS_PER_LONG == 64 +#define SO_TIMESTAMP SO_TIMESTAMP_OLD +#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD +#else +#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW) +#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW) +#endif + #define SO_TIMESTAMPING SO_TIMESTAMPING_OLD #define SCM_TIMESTAMP SO_TIMESTAMP diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index ca573641fc6c..dc8527cae5a7 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -3,6 +3,7 @@ #define _ASM_SOCKET_H #include +#include /* For setsockopt(2) */ #define SOL_SOCKET 0xffff @@ -105,10 +106,19 @@ #define SO_TIMESTAMPNS_OLD 0x0021 #define SO_TIMESTAMPING_OLD 0x0023 +#define SO_TIMESTAMP_NEW 0x0040 +#define SO_TIMESTAMPNS_NEW 0x0041 + #if !defined(__KERNEL__) -#define SO_TIMESTAMP SO_TIMESTAMP_OLD -#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD +#if __BITS_PER_LONG == 64 +#define SO_TIMESTAMP SO_TIMESTAMP_OLD +#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD +#else +#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW) +#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW) +#endif + #define SO_TIMESTAMPING SO_TIMESTAMPING_OLD #define SCM_TIMESTAMP SO_TIMESTAMP diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 85f6226d106f..31c45d4f3896 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -3492,12 +3492,30 @@ static inline void skb_get_timestamp(const struct sk_buff *skb, *stamp = ns_to_kernel_old_timeval(skb->tstamp); } +static inline void skb_get_new_timestamp(const struct sk_buff *skb, + struct __kernel_sock_timeval *stamp) +{ + struct timespec64 ts = ktime_to_timespec64(skb->tstamp); + + stamp->tv_sec = ts.tv_sec; + stamp->tv_usec = ts.tv_nsec / 1000; +} + static inline void skb_get_timestampns(const struct sk_buff *skb, struct timespec *stamp) { *stamp = ktime_to_timespec(skb->tstamp); } +static inline void skb_get_new_timestampns(const struct sk_buff *skb, + struct __kernel_timespec *stamp) +{ + struct timespec64 ts = ktime_to_timespec64(skb->tstamp); + + stamp->tv_sec = ts.tv_sec; + stamp->tv_nsec = ts.tv_nsec; +} + static inline void __net_timestamp(struct sk_buff *skb) { skb->tstamp = ktime_get_real(); diff --git a/include/net/sock.h b/include/net/sock.h index 2b229f7be8eb..6679f3c120b0 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -805,6 +805,7 @@ enum sock_flags { SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */ SOCK_TXTIME, SOCK_XDP, /* XDP is attached */ + SOCK_TSTAMP_NEW, /* Indicates 64 bit timestamps always */ }; #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index dc704e41203d..0b0fae6b57a9 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h @@ -3,6 +3,7 @@ #define __ASM_GENERIC_SOCKET_H #include +#include /* For setsockopt(2) */ #define SOL_SOCKET 1 @@ -107,10 +108,20 @@ #define SO_TIMESTAMPNS_OLD 35 #define SO_TIMESTAMPING_OLD 37 +#define SO_TIMESTAMP_NEW 62 +#define SO_TIMESTAMPNS_NEW 63 + #if !defined(__KERNEL__) -#define SO_TIMESTAMP SO_TIMESTAMP_OLD -#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD +#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__)) +/* on 64-bit and x32, avoid the ?: operator */ +#define SO_TIMESTAMP SO_TIMESTAMP_OLD +#define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD +#else +#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW) +#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW) +#endif + #define SO_TIMESTAMPING SO_TIMESTAMPING_OLD #define SCM_TIMESTAMP SO_TIMESTAMP diff --git a/net/core/sock.c b/net/core/sock.c index 492a8407130a..35c7cd9b2793 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -816,9 +816,16 @@ int sock_setsockopt(struct socket *sock, int level, int optname, break; case SO_TIMESTAMP_OLD: + case SO_TIMESTAMP_NEW: case SO_TIMESTAMPNS_OLD: + case SO_TIMESTAMPNS_NEW: if (valbool) { - if (optname == SO_TIMESTAMP_OLD) + if (optname == SO_TIMESTAMP_NEW || optname == SO_TIMESTAMPNS_NEW) + sock_set_flag(sk, SOCK_TSTAMP_NEW); + else + sock_reset_flag(sk, SOCK_TSTAMP_NEW); + + if (optname == SO_TIMESTAMP_OLD || optname == SO_TIMESTAMP_NEW) sock_reset_flag(sk, SOCK_RCVTSTAMPNS); else sock_set_flag(sk, SOCK_RCVTSTAMPNS); @@ -827,6 +834,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, } else { sock_reset_flag(sk, SOCK_RCVTSTAMP); sock_reset_flag(sk, SOCK_RCVTSTAMPNS); + sock_reset_flag(sk, SOCK_TSTAMP_NEW); } break; @@ -1188,11 +1196,20 @@ int sock_getsockopt(struct socket *sock, int level, int optname, case SO_TIMESTAMP_OLD: v.val = sock_flag(sk, SOCK_RCVTSTAMP) && + !sock_flag(sk, SOCK_TSTAMP_NEW) && !sock_flag(sk, SOCK_RCVTSTAMPNS); break; case SO_TIMESTAMPNS_OLD: - v.val = sock_flag(sk, SOCK_RCVTSTAMPNS); + v.val = sock_flag(sk, SOCK_RCVTSTAMPNS) && !sock_flag(sk, SOCK_TSTAMP_NEW); + break; + + case SO_TIMESTAMP_NEW: + v.val = sock_flag(sk, SOCK_RCVTSTAMP) && sock_flag(sk, SOCK_TSTAMP_NEW); + break; + + case SO_TIMESTAMPNS_NEW: + v.val = sock_flag(sk, SOCK_RCVTSTAMPNS) && sock_flag(sk, SOCK_TSTAMP_NEW); break; case SO_TIMESTAMPING_OLD: diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index e6e2ea0ac0f4..44fe307af09c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1864,20 +1864,39 @@ static void tcp_update_recv_tstamps(struct sk_buff *skb, static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk, struct scm_timestamping *tss) { - struct __kernel_old_timeval tv; bool has_timestamping = false; + int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW); if (tss->ts[0].tv_sec || tss->ts[0].tv_nsec) { if (sock_flag(sk, SOCK_RCVTSTAMP)) { if (sock_flag(sk, SOCK_RCVTSTAMPNS)) { - put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD, - sizeof(tss->ts[0]), &tss->ts[0]); - } else { - tv.tv_sec = tss->ts[0].tv_sec; - tv.tv_usec = tss->ts[0].tv_nsec / 1000; + if (new_tstamp) { + struct __kernel_timespec kts = {tss->ts[0].tv_sec, tss->ts[0].tv_nsec}; + + put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW, + sizeof(kts), &kts); + } else { + struct timespec ts_old = tss->ts[0]; - put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD, - sizeof(tv), &tv); + put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD, + sizeof(ts_old), &ts_old); + } + } else { + if (new_tstamp) { + struct __kernel_sock_timeval stv; + + stv.tv_sec = tss->ts[0].tv_sec; + stv.tv_usec = tss->ts[0].tv_nsec / 1000; + put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW, + sizeof(stv), &stv); + } else { + struct __kernel_old_timeval tv; + + tv.tv_sec = tss->ts[0].tv_sec; + tv.tv_usec = tss->ts[0].tv_nsec / 1000; + put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD, + sizeof(tv), &tv); + } } } diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index eeb4639adbe5..65571a6273c3 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -348,7 +348,7 @@ static int rds_set_transport(struct rds_sock *rs, char __user *optval, } static int rds_enable_recvtstamp(struct sock *sk, char __user *optval, - int optlen) + int optlen, int optname) { int val, valbool; @@ -360,6 +360,9 @@ static int rds_enable_recvtstamp(struct sock *sk, char __user *optval, valbool = val ? 1 : 0; + if (optname == SO_TIMESTAMP_NEW) + sock_set_flag(sk, SOCK_TSTAMP_NEW); + if (valbool) sock_set_flag(sk, SOCK_RCVTSTAMP); else @@ -431,8 +434,9 @@ static int rds_setsockopt(struct socket *sock, int level, int optname, release_sock(sock->sk); break; case SO_TIMESTAMP_OLD: + case SO_TIMESTAMP_NEW: lock_sock(sock->sk); - ret = rds_enable_recvtstamp(sock->sk, optval, optlen); + ret = rds_enable_recvtstamp(sock->sk, optval, optlen, optname); release_sock(sock->sk); break; case SO_RDS_MSG_RXPATH_LATENCY: diff --git a/net/rds/recv.c b/net/rds/recv.c index 435bf2320cd3..6bb6b16ca270 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c @@ -550,8 +550,20 @@ static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg, if ((inc->i_rx_tstamp != 0) && sock_flag(rds_rs_to_sk(rs), SOCK_RCVTSTAMP)) { struct __kernel_old_timeval tv = ns_to_kernel_old_timeval(inc->i_rx_tstamp); - ret = put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD, - sizeof(tv), &tv); + + if (!sock_flag(rds_rs_to_sk(rs), SOCK_TSTAMP_NEW)) { + ret = put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD, + sizeof(tv), &tv); + } else { + struct __kernel_sock_timeval sk_tv; + + sk_tv.tv_sec = tv.tv_sec; + sk_tv.tv_usec = tv.tv_usec; + + ret = put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW, + sizeof(sk_tv), &sk_tv); + } + if (ret) goto out; } diff --git a/net/socket.c b/net/socket.c index 9cc281cdb9d9..1de96abd78d3 100644 --- a/net/socket.c +++ b/net/socket.c @@ -705,6 +705,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) { int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP); + int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW); struct scm_timestamping tss; int empty = 1, false_tstamp = 0; struct skb_shared_hwtstamps *shhwtstamps = @@ -719,15 +720,33 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, if (need_software_tstamp) { if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) { - struct __kernel_old_timeval tv; - skb_get_timestamp(skb, &tv); - put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD, - sizeof(tv), &tv); + if (new_tstamp) { + struct __kernel_sock_timeval tv; + + skb_get_new_timestamp(skb, &tv); + put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW, + sizeof(tv), &tv); + } else { + struct __kernel_old_timeval tv; + + skb_get_timestamp(skb, &tv); + put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD, + sizeof(tv), &tv); + } } else { - struct timespec ts; - skb_get_timestampns(skb, &ts); - put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD, - sizeof(ts), &ts); + if (new_tstamp) { + struct __kernel_timespec ts; + + skb_get_new_timestampns(skb, &ts); + put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW, + sizeof(ts), &ts); + } else { + struct timespec ts; + + skb_get_timestampns(skb, &ts); + put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD, + sizeof(ts), &ts); + } } }