mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	socket: Add SO_TIMESTAMP[NS]_NEW
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 <deepa.kernel@gmail.com> Acked-by: Willem de Bruijn <willemb@google.com> 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 Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									98bb03c865
								
							
						
					
					
						commit
						887feae36a
					
				
					 12 changed files with 171 additions and 32 deletions
				
			
		| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
#define _UAPI_ASM_SOCKET_H
 | 
			
		||||
 | 
			
		||||
#include <asm/sockios.h>
 | 
			
		||||
#include <asm/bitsperlong.h>
 | 
			
		||||
 | 
			
		||||
/* For setsockopt(2) */
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -114,10 +115,19 @@
 | 
			
		|||
#define SO_TIMESTAMPNS_OLD      35
 | 
			
		||||
#define SO_TIMESTAMPING_OLD     37
 | 
			
		||||
 | 
			
		||||
#define SO_TIMESTAMP_NEW        63
 | 
			
		||||
#define SO_TIMESTAMPNS_NEW      64
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@
 | 
			
		|||
#define _UAPI_ASM_SOCKET_H
 | 
			
		||||
 | 
			
		||||
#include <asm/sockios.h>
 | 
			
		||||
#include <asm/bitsperlong.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * For setsockopt(2)
 | 
			
		||||
| 
						 | 
				
			
			@ -125,10 +126,19 @@
 | 
			
		|||
#define SO_TIMESTAMPNS_OLD      35
 | 
			
		||||
#define SO_TIMESTAMPING_OLD     37
 | 
			
		||||
 | 
			
		||||
#define SO_TIMESTAMP_NEW        63
 | 
			
		||||
#define SO_TIMESTAMPNS_NEW      64
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
#define _UAPI_ASM_SOCKET_H
 | 
			
		||||
 | 
			
		||||
#include <asm/sockios.h>
 | 
			
		||||
#include <asm/bitsperlong.h>
 | 
			
		||||
 | 
			
		||||
/* For setsockopt(2) */
 | 
			
		||||
#define SOL_SOCKET	0xffff
 | 
			
		||||
| 
						 | 
				
			
			@ -106,10 +107,19 @@
 | 
			
		|||
#define SO_TIMESTAMPNS_OLD      0x4013
 | 
			
		||||
#define SO_TIMESTAMPING_OLD     0x4020
 | 
			
		||||
 | 
			
		||||
#define SO_TIMESTAMP_NEW        0x4038
 | 
			
		||||
#define SO_TIMESTAMPNS_NEW      0x4039
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
#define _ASM_SOCKET_H
 | 
			
		||||
 | 
			
		||||
#include <asm/sockios.h>
 | 
			
		||||
#include <asm/bitsperlong.h>
 | 
			
		||||
 | 
			
		||||
/* For setsockopt(2) */
 | 
			
		||||
#define SOL_SOCKET	0xffff
 | 
			
		||||
| 
						 | 
				
			
			@ -107,10 +108,19 @@
 | 
			
		|||
#define SO_TIMESTAMPNS_OLD       0x0021
 | 
			
		||||
#define SO_TIMESTAMPING_OLD      0x0023
 | 
			
		||||
 | 
			
		||||
#define SO_TIMESTAMP_NEW         0x0041
 | 
			
		||||
#define SO_TIMESTAMPNS_NEW       0x0042
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3498,12 +3498,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();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
#define __ASM_GENERIC_SOCKET_H
 | 
			
		||||
 | 
			
		||||
#include <asm/sockios.h>
 | 
			
		||||
#include <asm/bitsperlong.h>
 | 
			
		||||
 | 
			
		||||
/* For setsockopt(2) */
 | 
			
		||||
#define SOL_SOCKET	1
 | 
			
		||||
| 
						 | 
				
			
			@ -109,10 +110,20 @@
 | 
			
		|||
#define SO_TIMESTAMPNS_OLD      35
 | 
			
		||||
#define SO_TIMESTAMPING_OLD     37
 | 
			
		||||
 | 
			
		||||
#define SO_TIMESTAMP_NEW        63
 | 
			
		||||
#define SO_TIMESTAMPNS_NEW      64
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -868,9 +868,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);
 | 
			
		||||
| 
						 | 
				
			
			@ -879,6 +886,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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1245,11 +1253,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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1861,20 +1861,37 @@ 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;
 | 
			
		||||
	int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
 | 
			
		||||
	bool has_timestamping = false;
 | 
			
		||||
 | 
			
		||||
	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_TIMESTAMP_OLD,
 | 
			
		||||
					 sizeof(tv), &tv);
 | 
			
		||||
					put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
 | 
			
		||||
						 sizeof(kts), &kts);
 | 
			
		||||
				} else {
 | 
			
		||||
					put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
 | 
			
		||||
						 sizeof(tss->ts[0]), &tss->ts[0]);
 | 
			
		||||
				}
 | 
			
		||||
			} 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);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										35
									
								
								net/socket.c
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								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);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue