All of lore.kernel.org
 help / color / mirror / Atom feed
From: Miroslav Lichvar <mlichvar@redhat.com>
To: netdev@vger.kernel.org
Cc: Richard Cochran <richardcochran@gmail.com>,
	Willem de Bruijn <willemb@google.com>,
	Soheil Hassas Yeganeh <soheil@google.com>,
	"Keller, Jacob E" <jacob.e.keller@intel.com>,
	Denny Page <dennypage@me.com>, Jiri Benc <jbenc@redhat.com>
Subject: [RFC PATCH 3/7] net: add option to get information about timestamped packets
Date: Wed, 12 Apr 2017 16:17:33 +0200	[thread overview]
Message-ID: <20170412141737.5881-4-mlichvar@redhat.com> (raw)
In-Reply-To: <20170412141737.5881-1-mlichvar@redhat.com>

Extend the skb_shared_hwtstamps structure with the index of the
real interface which received or transmitted the packet and the length
of the packet at layer 2. Add a SOF_TIMESTAMPING_OPT_PKTINFO flag to
the SO_TIMESTAMPING option to allow applications to get this information
as struct scm_ts_pktinfo in SCM_TIMESTAMPING_PKTINFO control message.

The index is mainly useful with bonding, bridges and other virtual
interfaces, where IP_PKTINFO doesn't provide the index of the real
interface. Applications may need it to determine which PHC made the
timestamp. With the L2 length it is possible to transpose preamble
timestamps to trailer timestamps, which are used in the NTP protocol.

Instead of adding a new check to a common path that might slow down
processing of received packets without hardware timestamps, the new
fields are expected to be set by the drivers together with the hardware
timestamp using the skb_hw_timestamp() function.

CC: Richard Cochran <richardcochran@gmail.com>
CC: Willem de Bruijn <willemb@google.com>
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
---
 Documentation/networking/timestamping.txt |  8 ++++++++
 include/linux/skbuff.h                    | 22 ++++++++++++++++++++++
 include/uapi/asm-generic/socket.h         |  2 ++
 include/uapi/linux/errqueue.h             |  8 ++++++++
 include/uapi/linux/net_tstamp.h           |  3 ++-
 net/core/skbuff.c                         | 12 +++++++++---
 net/socket.c                              | 11 ++++++++++-
 7 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt
index 96f5069..ed04aaa 100644
--- a/Documentation/networking/timestamping.txt
+++ b/Documentation/networking/timestamping.txt
@@ -193,6 +193,14 @@ SOF_TIMESTAMPING_OPT_STATS:
   the transmit timestamps, such as how long a certain block of
   data was limited by peer's receiver window.
 
+SOF_TIMESTAMPING_OPT_PKTINFO:
+
+  Optional information about timestamped packets. It includes the
+  index of the real interface which received or transmitted the
+  packet and its length at layer 2. If the device driver provides
+  this information, it will be attached in struct scm_ts_pktinfo as
+  a separate control message of type SCM_TIMESTAMPING_PKTINFO.
+
 New applications are encouraged to pass SOF_TIMESTAMPING_OPT_ID to
 disambiguate timestamps and SOF_TIMESTAMPING_OPT_TSONLY to operate
 regardless of the setting of sysctl net.core.tstamp_allow_data.
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 741d75c..e91685a 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -349,6 +349,8 @@ static inline void skb_frag_size_sub(skb_frag_t *frag, int delta)
  * struct skb_shared_hwtstamps - hardware time stamps
  * @hwtstamp:	hardware time stamp transformed into duration
  *		since arbitrary point in time
+ * @if_index:	index of the interface which timestamped the packet
+ * @pkt_length:	length of the packet
  *
  * Software time stamps generated by ktime_get_real() are stored in
  * skb->tstamp.
@@ -361,6 +363,8 @@ static inline void skb_frag_size_sub(skb_frag_t *frag, int delta)
  */
 struct skb_shared_hwtstamps {
 	ktime_t	hwtstamp;
+	int if_index;
+	int pkt_length;
 };
 
 /* Definitions for tx_flags in struct skb_shared_info */
@@ -3322,6 +3326,24 @@ static inline void skb_tx_timestamp(struct sk_buff *skb)
 }
 
 /**
+ * skb_hw_timestamp - set hardware timestamp with packet information
+ *
+ * @skb: A socket buffer.
+ * @hwtstamp: The hardware timestamp.
+ * @if_index: The index of the interface which timestamped the packet.
+ * @pkt_len: The length of the packet.
+ */
+static inline void skb_hw_timestamp(struct sk_buff *skb, ktime_t hwtstamp,
+				    int if_index, int pkt_length)
+{
+	struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb);
+
+	hwtstamps->hwtstamp = hwtstamp;
+	hwtstamps->if_index = if_index;
+	hwtstamps->pkt_length = pkt_length;
+}
+
+/**
  * skb_complete_wifi_ack - deliver skb with wifi status
  *
  * @skb: the original outgoing packet
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index 2b48856..a5f6e81 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -100,4 +100,6 @@
 
 #define SO_COOKIE		57
 
+#define SCM_TIMESTAMPING_PKTINFO	58
+
 #endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/include/uapi/linux/errqueue.h b/include/uapi/linux/errqueue.h
index 07bdce1..66d752f 100644
--- a/include/uapi/linux/errqueue.h
+++ b/include/uapi/linux/errqueue.h
@@ -43,4 +43,12 @@ enum {
 	SCM_TSTAMP_ACK,		/* data acknowledged by peer */
 };
 
+/**
+ *	struct scm_ts_pktinfo - information about HW-timestamped packets
+ */
+struct scm_ts_pktinfo {
+	int if_index;
+	int pkt_length;
+};
+
 #endif /* _UAPI_LINUX_ERRQUEUE_H */
diff --git a/include/uapi/linux/net_tstamp.h b/include/uapi/linux/net_tstamp.h
index 0749fb1..8397ecd 100644
--- a/include/uapi/linux/net_tstamp.h
+++ b/include/uapi/linux/net_tstamp.h
@@ -26,8 +26,9 @@ enum {
 	SOF_TIMESTAMPING_OPT_CMSG = (1<<10),
 	SOF_TIMESTAMPING_OPT_TSONLY = (1<<11),
 	SOF_TIMESTAMPING_OPT_STATS = (1<<12),
+	SOF_TIMESTAMPING_OPT_PKTINFO = (1<<13),
 
-	SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_STATS,
+	SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_PKTINFO,
 	SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) |
 				 SOF_TIMESTAMPING_LAST
 };
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 9f78109..7ca251f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3888,10 +3888,16 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
 		skb_shinfo(skb)->tskey = skb_shinfo(orig_skb)->tskey;
 	}
 
-	if (hwtstamps)
-		*skb_hwtstamps(skb) = *hwtstamps;
-	else
+	if (hwtstamps) {
+		skb_hwtstamps(skb)->hwtstamp = hwtstamps->hwtstamp;
+		if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) {
+			skb_hwtstamps(skb)->if_index = orig_skb->dev->ifindex;
+			skb_hwtstamps(skb)->pkt_length = orig_skb->mac_len +
+							 orig_skb->len;
+		}
+	} else {
 		skb->tstamp = ktime_get_real();
+	}
 
 	__skb_complete_tx_timestamp(skb, sk, tstype, opt_stats);
 }
diff --git a/net/socket.c b/net/socket.c
index eea9970..f272019 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -670,6 +670,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
 {
 	int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
 	struct scm_timestamping tss;
+	struct scm_ts_pktinfo ts_pktinfo;
 	int empty = 1;
 	struct skb_shared_hwtstamps *shhwtstamps =
 		skb_hwtstamps(skb);
@@ -699,8 +700,16 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
 		empty = 0;
 	if (shhwtstamps &&
 	    (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
-	    ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2))
+	    ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
+		if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO &&
+		    shhwtstamps->if_index) {
+			ts_pktinfo.if_index = shhwtstamps->if_index;
+			ts_pktinfo.pkt_length = shhwtstamps->pkt_length;
+			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO,
+				 sizeof(ts_pktinfo), &ts_pktinfo);
+		}
 		empty = 0;
+	}
 	if (!empty) {
 		put_cmsg(msg, SOL_SOCKET,
 			 SCM_TIMESTAMPING, sizeof(tss), &tss);
-- 
2.9.3

  parent reply	other threads:[~2017-04-12 14:17 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-12 14:17 [RFC PATCH 0/7] Extend socket timestamping API Miroslav Lichvar
2017-04-12 14:17 ` [RFC PATCH 1/7] net: define receive timestamp filter for NTP Miroslav Lichvar
2017-04-12 14:17 ` [RFC PATCH 2/7] net: ethernet: update drivers to handle HWTSTAMP_FILTER_NTP_ALL Miroslav Lichvar
2017-04-12 19:49   ` Richard Cochran
2017-04-13  9:00   ` Keller, Jacob E
2017-04-12 14:17 ` Miroslav Lichvar [this message]
2017-04-13 14:37   ` [RFC PATCH 3/7] net: add option to get information about timestamped packets Willem de Bruijn
2017-04-13 15:18     ` Miroslav Lichvar
2017-04-13 16:16       ` Willem de Bruijn
2017-04-24  9:00         ` Miroslav Lichvar
2017-04-24 15:18           ` Willem de Bruijn
2017-04-25 13:56             ` Miroslav Lichvar
2017-04-25 17:23               ` Willem de Bruijn
2017-04-12 14:17 ` [RFC PATCH 4/7] net: ethernet: update drivers to provide timestamping packet info Miroslav Lichvar
2017-04-13  9:04   ` Keller, Jacob E
2017-04-12 14:17 ` [RFC PATCH 5/7] net: don't make false software transmit timestamps Miroslav Lichvar
2017-04-12 14:17 ` [RFC PATCH 6/7] net: allow simultaneous SW and HW transmit timestamping Miroslav Lichvar
2017-04-13 14:30   ` Willem de Bruijn
2017-04-13 14:59     ` Miroslav Lichvar
2017-04-13 15:24       ` Keller, Jacob E
2017-04-13 16:17         ` Willem de Bruijn
2017-04-12 14:17 ` [RFC PATCH 7/7] net: ethernet: update drivers to make both SW and HW TX timestamps Miroslav Lichvar
2017-04-13  9:08 ` [RFC PATCH 0/7] Extend socket timestamping API Keller, Jacob E
2017-04-13  9:53   ` Miroslav Lichvar
2017-04-13 10:45     ` Keller, Jacob E

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170412141737.5881-4-mlichvar@redhat.com \
    --to=mlichvar@redhat.com \
    --cc=dennypage@me.com \
    --cc=jacob.e.keller@intel.com \
    --cc=jbenc@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=richardcochran@gmail.com \
    --cc=soheil@google.com \
    --cc=willemb@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.