mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	socket: Add SO_TIMESTAMPING_NEW
Add SO_TIMESTAMPING_NEW variant of socket timestamp options. This is the y2038 safe versions of the SO_TIMESTAMPING_OLD for all architectures. Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com> Acked-by: Willem de Bruijn <willemb@google.com> Cc: chris@zankel.net Cc: fenghua.yu@intel.com Cc: rth@twiddle.net Cc: tglx@linutronix.de Cc: ubraun@linux.ibm.com Cc: linux-alpha@vger.kernel.org Cc: linux-arch@vger.kernel.org Cc: linux-ia64@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: linux-s390@vger.kernel.org Cc: linux-xtensa@linux-xtensa.org Cc: sparclinux@vger.kernel.org Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									887feae36a
								
							
						
					
					
						commit
						9718475e69
					
				
					 12 changed files with 88 additions and 30 deletions
				
			
		| 
						 | 
					@ -117,19 +117,20 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TIMESTAMP_NEW        63
 | 
					#define SO_TIMESTAMP_NEW        63
 | 
				
			||||||
#define SO_TIMESTAMPNS_NEW      64
 | 
					#define SO_TIMESTAMPNS_NEW      64
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING_NEW     65
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(__KERNEL__)
 | 
					#if !defined(__KERNEL__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __BITS_PER_LONG == 64
 | 
					#if __BITS_PER_LONG == 64
 | 
				
			||||||
#define SO_TIMESTAMP		SO_TIMESTAMP_OLD
 | 
					#define SO_TIMESTAMP		SO_TIMESTAMP_OLD
 | 
				
			||||||
#define SO_TIMESTAMPNS		SO_TIMESTAMPNS_OLD
 | 
					#define SO_TIMESTAMPNS		SO_TIMESTAMPNS_OLD
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING         SO_TIMESTAMPING_OLD
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
 | 
					#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)
 | 
					#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TIMESTAMPING         SO_TIMESTAMPING_OLD
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SCM_TIMESTAMP           SO_TIMESTAMP
 | 
					#define SCM_TIMESTAMP           SO_TIMESTAMP
 | 
				
			||||||
#define SCM_TIMESTAMPNS         SO_TIMESTAMPNS
 | 
					#define SCM_TIMESTAMPNS         SO_TIMESTAMPNS
 | 
				
			||||||
#define SCM_TIMESTAMPING        SO_TIMESTAMPING
 | 
					#define SCM_TIMESTAMPING        SO_TIMESTAMPING
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -128,19 +128,20 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TIMESTAMP_NEW        63
 | 
					#define SO_TIMESTAMP_NEW        63
 | 
				
			||||||
#define SO_TIMESTAMPNS_NEW      64
 | 
					#define SO_TIMESTAMPNS_NEW      64
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING_NEW     65
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(__KERNEL__)
 | 
					#if !defined(__KERNEL__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __BITS_PER_LONG == 64
 | 
					#if __BITS_PER_LONG == 64
 | 
				
			||||||
#define SO_TIMESTAMP		SO_TIMESTAMP_OLD
 | 
					#define SO_TIMESTAMP		SO_TIMESTAMP_OLD
 | 
				
			||||||
#define SO_TIMESTAMPNS		SO_TIMESTAMPNS_OLD
 | 
					#define SO_TIMESTAMPNS		SO_TIMESTAMPNS_OLD
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING		SO_TIMESTAMPING_OLD
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
 | 
					#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)
 | 
					#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TIMESTAMPING         SO_TIMESTAMPING_OLD
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SCM_TIMESTAMP           SO_TIMESTAMP
 | 
					#define SCM_TIMESTAMP           SO_TIMESTAMP
 | 
				
			||||||
#define SCM_TIMESTAMPNS         SO_TIMESTAMPNS
 | 
					#define SCM_TIMESTAMPNS         SO_TIMESTAMPNS
 | 
				
			||||||
#define SCM_TIMESTAMPING        SO_TIMESTAMPING
 | 
					#define SCM_TIMESTAMPING        SO_TIMESTAMPING
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,19 +109,20 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TIMESTAMP_NEW        0x4038
 | 
					#define SO_TIMESTAMP_NEW        0x4038
 | 
				
			||||||
#define SO_TIMESTAMPNS_NEW      0x4039
 | 
					#define SO_TIMESTAMPNS_NEW      0x4039
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING_NEW     0x403A
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(__KERNEL__)
 | 
					#if !defined(__KERNEL__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __BITS_PER_LONG == 64
 | 
					#if __BITS_PER_LONG == 64
 | 
				
			||||||
#define SO_TIMESTAMP		SO_TIMESTAMP_OLD
 | 
					#define SO_TIMESTAMP		SO_TIMESTAMP_OLD
 | 
				
			||||||
#define SO_TIMESTAMPNS		SO_TIMESTAMPNS_OLD
 | 
					#define SO_TIMESTAMPNS		SO_TIMESTAMPNS_OLD
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING         SO_TIMESTAMPING_OLD
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
 | 
					#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)
 | 
					#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TIMESTAMPING         SO_TIMESTAMPING_OLD
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SCM_TIMESTAMP           SO_TIMESTAMP
 | 
					#define SCM_TIMESTAMP           SO_TIMESTAMP
 | 
				
			||||||
#define SCM_TIMESTAMPNS         SO_TIMESTAMPNS
 | 
					#define SCM_TIMESTAMPNS         SO_TIMESTAMPNS
 | 
				
			||||||
#define SCM_TIMESTAMPING        SO_TIMESTAMPING
 | 
					#define SCM_TIMESTAMPING        SO_TIMESTAMPING
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -110,19 +110,20 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TIMESTAMP_NEW         0x0041
 | 
					#define SO_TIMESTAMP_NEW         0x0041
 | 
				
			||||||
#define SO_TIMESTAMPNS_NEW       0x0042
 | 
					#define SO_TIMESTAMPNS_NEW       0x0042
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING_NEW      0x0043
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(__KERNEL__)
 | 
					#if !defined(__KERNEL__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __BITS_PER_LONG == 64
 | 
					#if __BITS_PER_LONG == 64
 | 
				
			||||||
#define SO_TIMESTAMP		SO_TIMESTAMP_OLD
 | 
					#define SO_TIMESTAMP		SO_TIMESTAMP_OLD
 | 
				
			||||||
#define SO_TIMESTAMPNS		SO_TIMESTAMPNS_OLD
 | 
					#define SO_TIMESTAMPNS		SO_TIMESTAMPNS_OLD
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING		SO_TIMESTAMPING_OLD
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
 | 
					#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)
 | 
					#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TIMESTAMPING        SO_TIMESTAMPING_OLD
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SCM_TIMESTAMP          SO_TIMESTAMP
 | 
					#define SCM_TIMESTAMP          SO_TIMESTAMP
 | 
				
			||||||
#define SCM_TIMESTAMPNS        SO_TIMESTAMPNS
 | 
					#define SCM_TIMESTAMPNS        SO_TIMESTAMPNS
 | 
				
			||||||
#define SCM_TIMESTAMPING       SO_TIMESTAMPING
 | 
					#define SCM_TIMESTAMPING       SO_TIMESTAMPING
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -349,9 +349,17 @@ struct ucred {
 | 
				
			||||||
extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr);
 | 
					extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr);
 | 
				
			||||||
extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
 | 
					extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct timespec64;
 | 
				
			||||||
struct __kernel_timespec;
 | 
					struct __kernel_timespec;
 | 
				
			||||||
struct old_timespec32;
 | 
					struct old_timespec32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct scm_timestamping_internal {
 | 
				
			||||||
 | 
						struct timespec64 ts[3];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_internal *tss);
 | 
				
			||||||
 | 
					extern void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_internal *tss);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* The __sys_...msg variants allow MSG_CMSG_COMPAT iff
 | 
					/* The __sys_...msg variants allow MSG_CMSG_COMPAT iff
 | 
				
			||||||
 * forbid_cmsg_compat==false
 | 
					 * forbid_cmsg_compat==false
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,6 +112,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TIMESTAMP_NEW        63
 | 
					#define SO_TIMESTAMP_NEW        63
 | 
				
			||||||
#define SO_TIMESTAMPNS_NEW      64
 | 
					#define SO_TIMESTAMPNS_NEW      64
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING_NEW     65
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(__KERNEL__)
 | 
					#if !defined(__KERNEL__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,13 +120,13 @@
 | 
				
			||||||
/* on 64-bit and x32, avoid the ?: operator */
 | 
					/* on 64-bit and x32, avoid the ?: operator */
 | 
				
			||||||
#define SO_TIMESTAMP		SO_TIMESTAMP_OLD
 | 
					#define SO_TIMESTAMP		SO_TIMESTAMP_OLD
 | 
				
			||||||
#define SO_TIMESTAMPNS		SO_TIMESTAMPNS_OLD
 | 
					#define SO_TIMESTAMPNS		SO_TIMESTAMPNS_OLD
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING		SO_TIMESTAMPING_OLD
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define SO_TIMESTAMP (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMP_OLD : SO_TIMESTAMP_NEW)
 | 
					#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)
 | 
					#define SO_TIMESTAMPNS (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPNS_OLD : SO_TIMESTAMPNS_NEW)
 | 
				
			||||||
 | 
					#define SO_TIMESTAMPING (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_TIMESTAMPING_OLD : SO_TIMESTAMPING_NEW)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SO_TIMESTAMPING         SO_TIMESTAMPING_OLD
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SCM_TIMESTAMP           SO_TIMESTAMP
 | 
					#define SCM_TIMESTAMP           SO_TIMESTAMP
 | 
				
			||||||
#define SCM_TIMESTAMPNS         SO_TIMESTAMPNS
 | 
					#define SCM_TIMESTAMPNS         SO_TIMESTAMPNS
 | 
				
			||||||
#define SCM_TIMESTAMPING        SO_TIMESTAMPING
 | 
					#define SCM_TIMESTAMPING        SO_TIMESTAMPING
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,10 @@ struct scm_timestamping {
 | 
				
			||||||
	struct timespec ts[3];
 | 
						struct timespec ts[3];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct scm_timestamping64 {
 | 
				
			||||||
 | 
						struct __kernel_timespec ts[3];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* The type of scm_timestamping, passed in sock_extended_err ee_info.
 | 
					/* The type of scm_timestamping, passed in sock_extended_err ee_info.
 | 
				
			||||||
 * This defines the type of ts[0]. For SCM_TSTAMP_SND only, if ts[0]
 | 
					 * This defines the type of ts[0]. For SCM_TSTAMP_SND only, if ts[0]
 | 
				
			||||||
 * is zero, then this is a hardware timestamp and recorded in ts[2].
 | 
					 * is zero, then this is a hardware timestamp and recorded in ts[2].
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,7 @@
 | 
				
			||||||
#include <linux/pid.h>
 | 
					#include <linux/pid.h>
 | 
				
			||||||
#include <linux/nsproxy.h>
 | 
					#include <linux/nsproxy.h>
 | 
				
			||||||
#include <linux/slab.h>
 | 
					#include <linux/slab.h>
 | 
				
			||||||
 | 
					#include <linux/errqueue.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/uaccess.h>
 | 
					#include <linux/uaccess.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -252,6 +253,32 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(put_cmsg);
 | 
					EXPORT_SYMBOL(put_cmsg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_internal *tss_internal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct scm_timestamping64 tss;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_SIZE(tss.ts); i++) {
 | 
				
			||||||
 | 
							tss.ts[i].tv_sec = tss_internal->ts[i].tv_sec;
 | 
				
			||||||
 | 
							tss.ts[i].tv_nsec = tss_internal->ts[i].tv_nsec;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_NEW, sizeof(tss), &tss);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(put_cmsg_scm_timestamping64);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_internal *tss_internal)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct scm_timestamping tss;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_SIZE(tss.ts); i++)
 | 
				
			||||||
 | 
							tss.ts[i] = timespec64_to_timespec(tss_internal->ts[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_OLD, sizeof(tss), &tss);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(put_cmsg_scm_timestamping);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
 | 
					void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cmsghdr __user *cm
 | 
						struct cmsghdr __user *cm
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -890,6 +890,8 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case SO_TIMESTAMPING_NEW:
 | 
				
			||||||
 | 
							sock_set_flag(sk, SOCK_TSTAMP_NEW);
 | 
				
			||||||
	case SO_TIMESTAMPING_OLD:
 | 
						case SO_TIMESTAMPING_OLD:
 | 
				
			||||||
		if (val & ~SOF_TIMESTAMPING_MASK) {
 | 
							if (val & ~SOF_TIMESTAMPING_MASK) {
 | 
				
			||||||
			ret = -EINVAL;
 | 
								ret = -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -921,9 +923,13 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
 | 
				
			||||||
		if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
 | 
							if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
 | 
				
			||||||
			sock_enable_timestamp(sk,
 | 
								sock_enable_timestamp(sk,
 | 
				
			||||||
					      SOCK_TIMESTAMPING_RX_SOFTWARE);
 | 
										      SOCK_TIMESTAMPING_RX_SOFTWARE);
 | 
				
			||||||
		else
 | 
							else {
 | 
				
			||||||
 | 
								if (optname == SO_TIMESTAMPING_NEW)
 | 
				
			||||||
 | 
									sock_reset_flag(sk, SOCK_TSTAMP_NEW);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sock_disable_timestamp(sk,
 | 
								sock_disable_timestamp(sk,
 | 
				
			||||||
					       (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE));
 | 
										       (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SO_RCVLOWAT:
 | 
						case SO_RCVLOWAT:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1844,22 +1844,22 @@ static int tcp_zerocopy_receive(struct sock *sk,
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void tcp_update_recv_tstamps(struct sk_buff *skb,
 | 
					static void tcp_update_recv_tstamps(struct sk_buff *skb,
 | 
				
			||||||
				    struct scm_timestamping *tss)
 | 
									    struct scm_timestamping_internal *tss)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (skb->tstamp)
 | 
						if (skb->tstamp)
 | 
				
			||||||
		tss->ts[0] = ktime_to_timespec(skb->tstamp);
 | 
							tss->ts[0] = ktime_to_timespec64(skb->tstamp);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		tss->ts[0] = (struct timespec) {0};
 | 
							tss->ts[0] = (struct timespec64) {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (skb_hwtstamps(skb)->hwtstamp)
 | 
						if (skb_hwtstamps(skb)->hwtstamp)
 | 
				
			||||||
		tss->ts[2] = ktime_to_timespec(skb_hwtstamps(skb)->hwtstamp);
 | 
							tss->ts[2] = ktime_to_timespec64(skb_hwtstamps(skb)->hwtstamp);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		tss->ts[2] = (struct timespec) {0};
 | 
							tss->ts[2] = (struct timespec64) {0};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Similar to __sock_recv_timestamp, but does not require an skb */
 | 
					/* Similar to __sock_recv_timestamp, but does not require an skb */
 | 
				
			||||||
static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
 | 
					static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
 | 
				
			||||||
			       struct scm_timestamping *tss)
 | 
								       struct scm_timestamping_internal *tss)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
 | 
						int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
 | 
				
			||||||
	bool has_timestamping = false;
 | 
						bool has_timestamping = false;
 | 
				
			||||||
| 
						 | 
					@ -1873,8 +1873,10 @@ static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
 | 
				
			||||||
					put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
 | 
										put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
 | 
				
			||||||
						 sizeof(kts), &kts);
 | 
											 sizeof(kts), &kts);
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
 | 
										struct timespec ts_old = timespec64_to_timespec(tss->ts[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
 | 
										put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
 | 
				
			||||||
						 sizeof(tss->ts[0]), &tss->ts[0]);
 | 
											 sizeof(ts_old), &ts_old);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				if (new_tstamp) {
 | 
									if (new_tstamp) {
 | 
				
			||||||
| 
						 | 
					@ -1898,20 +1900,22 @@ static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
 | 
				
			||||||
		if (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE)
 | 
							if (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE)
 | 
				
			||||||
			has_timestamping = true;
 | 
								has_timestamping = true;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			tss->ts[0] = (struct timespec) {0};
 | 
								tss->ts[0] = (struct timespec64) {0};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (tss->ts[2].tv_sec || tss->ts[2].tv_nsec) {
 | 
						if (tss->ts[2].tv_sec || tss->ts[2].tv_nsec) {
 | 
				
			||||||
		if (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)
 | 
							if (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)
 | 
				
			||||||
			has_timestamping = true;
 | 
								has_timestamping = true;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			tss->ts[2] = (struct timespec) {0};
 | 
								tss->ts[2] = (struct timespec64) {0};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (has_timestamping) {
 | 
						if (has_timestamping) {
 | 
				
			||||||
		tss->ts[1] = (struct timespec) {0};
 | 
							tss->ts[1] = (struct timespec64) {0};
 | 
				
			||||||
		put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_OLD,
 | 
							if (sock_flag(sk, SOCK_TSTAMP_NEW))
 | 
				
			||||||
			 sizeof(*tss), tss);
 | 
								put_cmsg_scm_timestamping64(msg, tss);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								put_cmsg_scm_timestamping(msg, tss);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1952,7 +1956,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
 | 
				
			||||||
	long timeo;
 | 
						long timeo;
 | 
				
			||||||
	struct sk_buff *skb, *last;
 | 
						struct sk_buff *skb, *last;
 | 
				
			||||||
	u32 urg_hole = 0;
 | 
						u32 urg_hole = 0;
 | 
				
			||||||
	struct scm_timestamping tss;
 | 
						struct scm_timestamping_internal tss;
 | 
				
			||||||
	bool has_tss = false;
 | 
						bool has_tss = false;
 | 
				
			||||||
	bool has_cmsg;
 | 
						bool has_cmsg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -291,7 +291,8 @@ static void smc_copy_sock_settings(struct sock *nsk, struct sock *osk,
 | 
				
			||||||
			     (1UL << SOCK_RXQ_OVFL) | \
 | 
								     (1UL << SOCK_RXQ_OVFL) | \
 | 
				
			||||||
			     (1UL << SOCK_WIFI_STATUS) | \
 | 
								     (1UL << SOCK_WIFI_STATUS) | \
 | 
				
			||||||
			     (1UL << SOCK_NOFCS) | \
 | 
								     (1UL << SOCK_NOFCS) | \
 | 
				
			||||||
			     (1UL << SOCK_FILTER_LOCKED))
 | 
								     (1UL << SOCK_FILTER_LOCKED) | \
 | 
				
			||||||
 | 
								     (1UL << SOCK_TSTAMP_NEW))
 | 
				
			||||||
/* copy only relevant settings and flags of SOL_SOCKET level from smc to
 | 
					/* copy only relevant settings and flags of SOL_SOCKET level from smc to
 | 
				
			||||||
 * clc socket (since smc is not called for these options from net/core)
 | 
					 * clc socket (since smc is not called for these options from net/core)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								net/socket.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								net/socket.c
									
									
									
									
									
								
							| 
						 | 
					@ -706,7 +706,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
 | 
						int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
 | 
				
			||||||
	int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
 | 
						int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
 | 
				
			||||||
	struct scm_timestamping tss;
 | 
						struct scm_timestamping_internal tss;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int empty = 1, false_tstamp = 0;
 | 
						int empty = 1, false_tstamp = 0;
 | 
				
			||||||
	struct skb_shared_hwtstamps *shhwtstamps =
 | 
						struct skb_shared_hwtstamps *shhwtstamps =
 | 
				
			||||||
		skb_hwtstamps(skb);
 | 
							skb_hwtstamps(skb);
 | 
				
			||||||
| 
						 | 
					@ -752,20 +753,22 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&tss, 0, sizeof(tss));
 | 
						memset(&tss, 0, sizeof(tss));
 | 
				
			||||||
	if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
 | 
						if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
 | 
				
			||||||
	    ktime_to_timespec_cond(skb->tstamp, tss.ts + 0))
 | 
						    ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0))
 | 
				
			||||||
		empty = 0;
 | 
							empty = 0;
 | 
				
			||||||
	if (shhwtstamps &&
 | 
						if (shhwtstamps &&
 | 
				
			||||||
	    (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
 | 
						    (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
 | 
				
			||||||
	    !skb_is_swtx_tstamp(skb, false_tstamp) &&
 | 
						    !skb_is_swtx_tstamp(skb, false_tstamp) &&
 | 
				
			||||||
	    ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
 | 
						    ktime_to_timespec64_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
 | 
				
			||||||
		empty = 0;
 | 
							empty = 0;
 | 
				
			||||||
		if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
 | 
							if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
 | 
				
			||||||
		    !skb_is_err_queue(skb))
 | 
							    !skb_is_err_queue(skb))
 | 
				
			||||||
			put_ts_pktinfo(msg, skb);
 | 
								put_ts_pktinfo(msg, skb);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!empty) {
 | 
						if (!empty) {
 | 
				
			||||||
		put_cmsg(msg, SOL_SOCKET,
 | 
							if (sock_flag(sk, SOCK_TSTAMP_NEW))
 | 
				
			||||||
			 SO_TIMESTAMPING_OLD, sizeof(tss), &tss);
 | 
								put_cmsg_scm_timestamping64(msg, &tss);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								put_cmsg_scm_timestamping(msg, &tss);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (skb_is_err_queue(skb) && skb->len &&
 | 
							if (skb_is_err_queue(skb) && skb->len &&
 | 
				
			||||||
		    SKB_EXT_ERR(skb)->opt_stats)
 | 
							    SKB_EXT_ERR(skb)->opt_stats)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue