lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu,  3 Jul 2014 15:39:34 -0400
From:	Willem de Bruijn <willemb@...gle.com>
To:	netdev@...r.kernel.org
Cc:	davem@...emloft.net, eric.dumazet@...il.com,
	richardcochran@...ail.com, stephen@...workplumber.org,
	Willem de Bruijn <willemb@...gle.com>
Subject: [PATCH net-next v2 2/8] net-timestamp: MSG_TSTAMP one-shot tx timestamps

The kernel support datagram tx timestamping through socket option
SO_TIMESTAMPING. This patch add send() flag MSG_TSTAMP to allow
selectively requesting a timestamp for a single packet.

MSG_TSTAMP does not depend on SO_TIMESTAMPING. Enabling both
concurrently is redundant, but safe.

This patch adds support for IPv4 and IPv6 UDP sendmsg().

The feature maintains semantics of the socket option: with IP
fragmentation, only the first fragment is timestamped. This
should not happen, but can be forced, e.g., by disabling PMTU
on UDP.

Signed-off-by: Willem de Bruijn <willemb@...gle.com>
---
 include/linux/skbuff.h | 10 ++++++++++
 include/linux/socket.h |  1 +
 include/net/sock.h     |  5 +++--
 net/ipv4/udp.c         |  1 +
 net/ipv6/ip6_output.c  |  4 +++-
 net/socket.c           |  3 ++-
 6 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c74aab5..977596d 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2738,6 +2738,16 @@ static inline void skb_tx_timestamp(struct sk_buff *skb)
 	sw_tx_timestamp(skb);
 }
 
+static inline u8 skbflags_tx_tstamp(int flags)
+{
+	u8 tx_flags = 0;
+
+	if (unlikely(flags & MSG_TSTAMP))
+		tx_flags |= SKBTX_SW_TSTAMP;
+
+	return tx_flags;
+}
+
 /**
  * skb_complete_wifi_ack - deliver skb with wifi status
  *
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 8e98297..ce4101e 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -253,6 +253,7 @@ struct ucred {
 #define MSG_MORE	0x8000	/* Sender will send more */
 #define MSG_WAITFORONE	0x10000	/* recvmmsg(): block until 1+ packets avail */
 #define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
+#define MSG_TSTAMP	0x100000
 #define MSG_EOF         MSG_FIN
 
 #define MSG_FASTOPEN	0x20000000	/* Send data in TCP SYN */
diff --git a/include/net/sock.h b/include/net/sock.h
index 8d4c947..62bcaa9 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2140,14 +2140,15 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
 	 * - receive time stamping in software requested (SOCK_RCVTSTAMP
 	 *   or SOCK_TIMESTAMPING_RX_SOFTWARE)
 	 * - software time stamp available and wanted
-	 *   (SOCK_TIMESTAMPING_SOFTWARE)
+	 *   (SOCK_TIMESTAMPING_SOFTWARE || SKBTX_SW_TSTAMP)
 	 * - hardware time stamps available and wanted
 	 *   (SOCK_TIMESTAMPING_SYS_HARDWARE or
 	 *   SOCK_TIMESTAMPING_RAW_HARDWARE)
 	 */
 	if (sock_flag(sk, SOCK_RCVTSTAMP) ||
 	    sock_flag(sk, SOCK_TIMESTAMPING_RX_SOFTWARE) ||
-	    (kt.tv64 && sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE)) ||
+	    (kt.tv64 && (sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE) ||
+	     skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP)) ||
 	    (hwtstamps->hwtstamp.tv64 &&
 	     sock_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE)) ||
 	    (hwtstamps->syststamp.tv64 &&
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index d92f94b..9127aab 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -967,6 +967,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 	ipc.oif = sk->sk_bound_dev_if;
 
 	sock_tx_timestamp(sk, &ipc.tx_flags);
+	ipc.tx_flags |= skbflags_tx_tstamp(msg->msg_flags);
 
 	if (msg->msg_controllen) {
 		err = ip_cmsg_send(sock_net(sk), msg, &ipc,
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index cb9df0e..7306c5d 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1270,8 +1270,10 @@ emsgsize:
 	}
 
 	/* For UDP, check if TX timestamp is enabled */
-	if (sk->sk_type == SOCK_DGRAM)
+	if (sk->sk_type == SOCK_DGRAM) {
 		sock_tx_timestamp(sk, &tx_flags);
+		tx_flags |= skbflags_tx_tstamp(flags);
+	}
 
 	/*
 	 * Let's try using as much space as possible.
diff --git a/net/socket.c b/net/socket.c
index a31138d..9f69a25 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -724,7 +724,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
 	}
 
 	memset(&tss, 0, sizeof(tss));
-	if (sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE) &&
+	if ((sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE) ||
+	     skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP) &&
 	    ktime_to_timespec_cond(skb->tstamp, tss.ts + 0))
 		tstype |= is_tx ? serr->ee.ee_info : SCM_TSTAMP_RCV;
 	if (shhwtstamps) {
-- 
2.0.0.526.g5318336

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists