[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1403624632-17327-3-git-send-email-willemb@google.com>
Date: Tue, 24 Jun 2014 11:43:47 -0400
From: Willem de Bruijn <willemb@...gle.com>
To: netdev@...r.kernel.org
Cc: eric.dumazet@...il.com, richardcochran@...il.com,
davem@...emloft.net, Willem de Bruijn <willemb@...gle.com>
Subject: [PATCH net-next 2/7] 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 ec89301..bec3ded 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2736,6 +2736,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 07b7fcd..32cd1be 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2138,14 +2138,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 c001746..18ab44a 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -723,7 +723,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_sw)) {
empty = 0;
tss.ts_type = SCM_TSTAMP_SND;
--
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