All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg()
@ 2021-05-17  9:44 François Legal
  2021-07-23  7:04 ` François Legal
  2021-07-26 12:01 ` Jan Kiszka
  0 siblings, 2 replies; 7+ messages in thread
From: François Legal @ 2021-05-17  9:44 UTC (permalink / raw)
  To: xenomai

This patch enables retrieving, in realtime application, of RTNET enabled adapters packet timestamps.
It uses the linux semantic SO_TIMESTAMPNS, and the linux code to put the timestamp in the control_msg structure.

I tested this patch with af_packet sockets only. UDP  & TCP might be a little bit trickier as many fragment/segments get reassembled in a single recvmsg. I believe the linux code I used to put the timestamps in the control structure should be OK though.

Signed-off-by: François LEGAL <devel@thom.fr.eu.org>
---
 kernel/drivers/net/stack/Kconfig              |  8 +++
 .../drivers/net/stack/include/rtnet_socket.h  |  7 +++
 kernel/drivers/net/stack/ipv4/tcp/tcp.c       |  8 +++
 kernel/drivers/net/stack/ipv4/udp/udp.c       |  7 +++
 kernel/drivers/net/stack/packet/af_packet.c   |  7 +++
 kernel/drivers/net/stack/socket.c             | 59 +++++++++++++++++++
 6 files changed, 96 insertions(+)

diff --git a/kernel/drivers/net/stack/Kconfig b/kernel/drivers/net/stack/Kconfig
index 830cec5ad..f8ee0f1ad 100644
--- a/kernel/drivers/net/stack/Kconfig
+++ b/kernel/drivers/net/stack/Kconfig
@@ -12,6 +12,14 @@ config XENO_DRIVERS_NET_RX_FIFO_SIZE
     of two! Effectively, only CONFIG_RTNET_RX_FIFO_SIZE-1 slots will
     be usable.

+config XENO_DRIVERS_NET_PACKET_TIMESTAMP
+    bool "Enable packet timestamping (SO_TIMESTAMPNS)"
+    depends on XENO_DRIVERS_NET
+    ---help---
+    Enable userland access to low level packet timestamps using SO_TIMESTAMPNS
+    ioctl on socket. Timestamp are then returned in recvmsg calls in msg_control
+    structure inside msghdr structure.
+
 config XENO_DRIVERS_NET_ETH_P_ALL
     depends on XENO_DRIVERS_NET
     bool "Support for ETH_P_ALL"
diff --git a/kernel/drivers/net/stack/include/rtnet_socket.h b/kernel/drivers/net/stack/include/rtnet_socket.h
index d2caab649..dc488a58a 100644
--- a/kernel/drivers/net/stack/include/rtnet_socket.h
+++ b/kernel/drivers/net/stack/include/rtnet_socket.h
@@ -29,6 +29,7 @@

 #include <asm/atomic.h>
 #include <linux/list.h>
+#include <net/sock.h>

 #include <rtdev.h>
 #include <rtdm/net.h>
@@ -77,6 +78,12 @@ struct rtsocket {
 	} prot;
 };

+#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
+#define SOCKET_FLAG_TIMESTAMP   SOCK_RCVTSTAMPNS
+int rtnet_put_cmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int level,
+					int type, int len, void *data);
+#endif
+
 static inline struct rtdm_fd *rt_socket_fd(struct rtsocket *sock)
 {
 	return rtdm_private_to_fd(sock);
diff --git a/kernel/drivers/net/stack/ipv4/tcp/tcp.c b/kernel/drivers/net/stack/ipv4/tcp/tcp.c
index d8c189c88..c8b21c521 100644
--- a/kernel/drivers/net/stack/ipv4/tcp/tcp.c
+++ b/kernel/drivers/net/stack/ipv4/tcp/tcp.c
@@ -2027,6 +2027,14 @@ static ssize_t rt_tcp_read(struct rtdm_fd *fd, void *buf, size_t nbyte)
 			kfree_rtskb(first_skb); /* or store the data? */
 			return -EFAULT;
 		}
+
+#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
+		if (test_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags))
+			rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
+					sizeof(nanosecs_abs_t),
+					(void *) &skb->time_stamp);
+#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
+
 		rtdm_lock_get_irqsave(&ts->socket_lock, context);
 		if (ts->sync.window) {
 			ts->sync.window += block_size;
diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c
index 546b35855..ac6448027 100644
--- a/kernel/drivers/net/stack/ipv4/udp/udp.c
+++ b/kernel/drivers/net/stack/ipv4/udp/udp.c
@@ -463,6 +463,13 @@ ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg,
 	do {
 		rtskb_trim(skb, data_len);

+#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
+		if (test_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags))
+			rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
+					sizeof(nanosecs_abs_t),
+					(void *) &skb->time_stamp);
+#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
+
 		block_size = skb->len;
 		copied += block_size;
 		data_len -= block_size;
diff --git a/kernel/drivers/net/stack/packet/af_packet.c b/kernel/drivers/net/stack/packet/af_packet.c
index cc7487303..10e8113fe 100644
--- a/kernel/drivers/net/stack/packet/af_packet.c
+++ b/kernel/drivers/net/stack/packet/af_packet.c
@@ -364,6 +364,13 @@ static ssize_t rt_packet_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg,
 	if (rtdm_fd_to_context(fd)->device->driver->socket_type != SOCK_DGRAM)
 		rtskb_push(rtskb, rtskb->data - rtskb->mac.raw);

+#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
+		if (test_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags))
+			rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
+					sizeof(nanosecs_abs_t),
+					(void *) &rtskb->time_stamp);
+#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
+
 	/* The data must not be longer than the available buffer size */
 	copy_len = rtskb->len;
 	len = rtdm_get_iov_flatlen(iov, msg->msg_iovlen);
diff --git a/kernel/drivers/net/stack/socket.c b/kernel/drivers/net/stack/socket.c
index f030663be..5a9702975 100644
--- a/kernel/drivers/net/stack/socket.c
+++ b/kernel/drivers/net/stack/socket.c
@@ -273,6 +273,15 @@ int rt_socket_if_ioctl(struct rtdm_fd *fd, int request, void __user *arg)
 		return rtnet_put_arg(fd, &u_ifc->ifc_len, &size, sizeof(size));
 	}

+#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
+	if (request == SO_TIMESTAMPNS) {
+		struct rtsocket *sock = rtdm_fd_to_private(fd);
+
+		set_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags);
+		return 0;
+	}
+#endif
+
 	u_ifr = arg;
 	ifr = rtnet_get_arg(fd, &_ifr, u_ifr, sizeof(_ifr));
 	if (IS_ERR(ifr))
@@ -393,3 +402,53 @@ int rtnet_put_arg(struct rtdm_fd *fd, void *dst, const void *src, size_t len)
 	return rtdm_copy_to_user(fd, dst, src, len);
 }
 EXPORT_SYMBOL_GPL(rtnet_put_arg);
+
+#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
+int rtnet_put_cmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int level,
+					int type, int len, void *data)
+{
+	struct cmsghdr __user *cm = msg->msg_control;
+	struct cmsghdr cmhdr;
+	int cmlen = CMSG_LEN(len);
+	int err;
+
+	if (MSG_CMSG_COMPAT & msg->msg_flags)
+		return 0; /* XXX: return error? check spec. */
+
+	if ((cm == NULL) || (msg->msg_controllen < sizeof(*cm))) {
+		msg->msg_flags |= MSG_CTRUNC;
+		return 0; /* XXX: return error? check spec. */
+	}
+	if (msg->msg_controllen < cmlen) {
+		msg->msg_flags |= MSG_CTRUNC;
+		cmlen = msg->msg_controllen;
+	}
+	cmhdr.cmsg_level = level;
+	cmhdr.cmsg_type = type;
+	cmhdr.cmsg_len = cmlen;
+
+	err = -EFAULT;
+
+	if (!rtdm_fd_is_user(fd)) {
+		memcpy(cm, &cmhdr, sizeof(struct cmsghdr));
+		memcpy(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr));
+		err = 0;
+	} else {
+		if (rtdm_copy_to_user(fd, cm, &cmhdr, sizeof(struct cmsghdr)))
+			goto out;
+		if (rtdm_copy_to_user(fd, CMSG_DATA(cm), data,
+					cmlen - sizeof(struct cmsghdr)))
+			goto out;
+		cmlen = CMSG_SPACE(len);
+		if (msg->msg_controllen < cmlen)
+			cmlen = msg->msg_controllen;
+		msg->msg_control += cmlen;
+		msg->msg_controllen -= cmlen;
+		err = 0;
+	}
+out:
+	return err;
+}
+EXPORT_SYMBOL(rtdm_put_cmsg);
+
+#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
--
2.20.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Enable retrieving  of RTNET network packet timestamp OOB using recvmsg()
  2021-05-17  9:44 [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg() François Legal
@ 2021-07-23  7:04 ` François Legal
  2021-07-26 12:01 ` Jan Kiszka
  1 sibling, 0 replies; 7+ messages in thread
From: François Legal @ 2021-07-23  7:04 UTC (permalink / raw)
  To: xenomai

Hello,

I wanted to raise this one too, if it's of any interest for the community.

François

Le Lundi, Mai 17, 2021 11:44 CEST, François Legal via Xenomai <xenomai@xenomai.org> a écrit:

> This patch enables retrieving, in realtime application, of RTNET enabled adapters packet timestamps.
> It uses the linux semantic SO_TIMESTAMPNS, and the linux code to put the timestamp in the control_msg structure.
>
> I tested this patch with af_packet sockets only. UDP  & TCP might be a little bit trickier as many fragment/segments get reassembled in a single recvmsg. I believe the linux code I used to put the timestamps in the control structure should be OK though.
>
> Signed-off-by: François LEGAL <devel@thom.fr.eu.org>
> ---
>  kernel/drivers/net/stack/Kconfig              |  8 +++
>  .../drivers/net/stack/include/rtnet_socket.h  |  7 +++
>  kernel/drivers/net/stack/ipv4/tcp/tcp.c       |  8 +++
>  kernel/drivers/net/stack/ipv4/udp/udp.c       |  7 +++
>  kernel/drivers/net/stack/packet/af_packet.c   |  7 +++
>  kernel/drivers/net/stack/socket.c             | 59 +++++++++++++++++++ 6 files changed, 96 insertions(+)
>
> diff --git a/kernel/drivers/net/stack/Kconfig b/kernel/drivers/net/stack/Kconfig
> index 830cec5ad..f8ee0f1ad 100644
> --- a/kernel/drivers/net/stack/Kconfig
> +++ b/kernel/drivers/net/stack/Kconfig
> @@ -12,6 +12,14 @@ config XENO_DRIVERS_NET_RX_FIFO_SIZE
>      of two! Effectively, only CONFIG_RTNET_RX_FIFO_SIZE-1 slots will
>      be usable.
>
> +config XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +    bool "Enable packet timestamping (SO_TIMESTAMPNS)"
> +    depends on XENO_DRIVERS_NET
> +    ---help---
> +    Enable userland access to low level packet timestamps using SO_TIMESTAMPNS
> +    ioctl on socket. Timestamp are then returned in recvmsg calls in msg_control
> +    structure inside msghdr structure.
> +
>  config XENO_DRIVERS_NET_ETH_P_ALL
>      depends on XENO_DRIVERS_NET
>      bool "Support for ETH_P_ALL"
> diff --git a/kernel/drivers/net/stack/include/rtnet_socket.h b/kernel/drivers/net/stack/include/rtnet_socket.h
> index d2caab649..dc488a58a 100644
> --- a/kernel/drivers/net/stack/include/rtnet_socket.h
> +++ b/kernel/drivers/net/stack/include/rtnet_socket.h
> @@ -29,6 +29,7 @@
>
>  #include <asm/atomic.h>
>  #include <linux/list.h>
> +#include <net/sock.h>
>
>  #include <rtdev.h>
>  #include <rtdm/net.h>
> @@ -77,6 +78,12 @@ struct rtsocket {
>  	} prot;
>  };
>
> +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +#define SOCKET_FLAG_TIMESTAMP   SOCK_RCVTSTAMPNS
> +int rtnet_put_cmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int level,
> +					int type, int len, void *data);
> +#endif
> +
>  static inline struct rtdm_fd *rt_socket_fd(struct rtsocket *sock)
>  {
>  	return rtdm_private_to_fd(sock);
> diff --git a/kernel/drivers/net/stack/ipv4/tcp/tcp.c b/kernel/drivers/net/stack/ipv4/tcp/tcp.c
> index d8c189c88..c8b21c521 100644
> --- a/kernel/drivers/net/stack/ipv4/tcp/tcp.c
> +++ b/kernel/drivers/net/stack/ipv4/tcp/tcp.c
> @@ -2027,6 +2027,14 @@ static ssize_t rt_tcp_read(struct rtdm_fd *fd, void *buf, size_t nbyte)
>  			kfree_rtskb(first_skb); /* or store the data? */
>  			return -EFAULT;
>  		}
> +
> +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +		if (test_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags))
> +			rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> +					sizeof(nanosecs_abs_t),
> +					(void *) &skb->time_stamp);
> +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> +
>  		rtdm_lock_get_irqsave(&ts->socket_lock, context);
>  		if (ts->sync.window) {
>  			ts->sync.window += block_size;
> diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c
> index 546b35855..ac6448027 100644
> --- a/kernel/drivers/net/stack/ipv4/udp/udp.c
> +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c
> @@ -463,6 +463,13 @@ ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg,
>  	do {
>  		rtskb_trim(skb, data_len);
>
> +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +		if (test_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags))
> +			rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> +					sizeof(nanosecs_abs_t),
> +					(void *) &skb->time_stamp);
> +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> +
>  		block_size = skb->len;
>  		copied += block_size;
>  		data_len -= block_size;
> diff --git a/kernel/drivers/net/stack/packet/af_packet.c b/kernel/drivers/net/stack/packet/af_packet.c
> index cc7487303..10e8113fe 100644
> --- a/kernel/drivers/net/stack/packet/af_packet.c
> +++ b/kernel/drivers/net/stack/packet/af_packet.c
> @@ -364,6 +364,13 @@ static ssize_t rt_packet_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg,
>  	if (rtdm_fd_to_context(fd)->device->driver->socket_type != SOCK_DGRAM)
>  		rtskb_push(rtskb, rtskb->data - rtskb->mac.raw);
>
> +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +		if (test_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags))
> +			rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> +					sizeof(nanosecs_abs_t),
> +					(void *) &rtskb->time_stamp);
> +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> +
>  	/* The data must not be longer than the available buffer size */
>  	copy_len = rtskb->len;
>  	len = rtdm_get_iov_flatlen(iov, msg->msg_iovlen);
> diff --git a/kernel/drivers/net/stack/socket.c b/kernel/drivers/net/stack/socket.c
> index f030663be..5a9702975 100644
> --- a/kernel/drivers/net/stack/socket.c
> +++ b/kernel/drivers/net/stack/socket.c
> @@ -273,6 +273,15 @@ int rt_socket_if_ioctl(struct rtdm_fd *fd, int request, void __user *arg)
>  		return rtnet_put_arg(fd, &u_ifc->ifc_len, &size, sizeof(size));
>  	}
>
> +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +	if (request == SO_TIMESTAMPNS) {
> +		struct rtsocket *sock = rtdm_fd_to_private(fd);
> +
> +		set_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags);
> +		return 0;
> +	}
> +#endif
> +
>  	u_ifr = arg;
>  	ifr = rtnet_get_arg(fd, &_ifr, u_ifr, sizeof(_ifr));
>  	if (IS_ERR(ifr))
> @@ -393,3 +402,53 @@ int rtnet_put_arg(struct rtdm_fd *fd, void *dst, const void *src, size_t len)
>  	return rtdm_copy_to_user(fd, dst, src, len);
>  }
>  EXPORT_SYMBOL_GPL(rtnet_put_arg);
> +
> +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +int rtnet_put_cmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int level,
> +					int type, int len, void *data)
> +{
> +	struct cmsghdr __user *cm = msg->msg_control;
> +	struct cmsghdr cmhdr;
> +	int cmlen = CMSG_LEN(len);
> +	int err;
> +
> +	if (MSG_CMSG_COMPAT & msg->msg_flags)
> +		return 0; /* XXX: return error? check spec. */
> +
> +	if ((cm == NULL) || (msg->msg_controllen < sizeof(*cm))) {
> +		msg->msg_flags |= MSG_CTRUNC;
> +		return 0; /* XXX: return error? check spec. */
> +	}
> +	if (msg->msg_controllen < cmlen) {
> +		msg->msg_flags |= MSG_CTRUNC;
> +		cmlen = msg->msg_controllen;
> +	}
> +	cmhdr.cmsg_level = level;
> +	cmhdr.cmsg_type = type;
> +	cmhdr.cmsg_len = cmlen;
> +
> +	err = -EFAULT;
> +
> +	if (!rtdm_fd_is_user(fd)) {
> +		memcpy(cm, &cmhdr, sizeof(struct cmsghdr));
> +		memcpy(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr));
> +		err = 0;
> +	} else {
> +		if (rtdm_copy_to_user(fd, cm, &cmhdr, sizeof(struct cmsghdr)))+			goto out;
> +		if (rtdm_copy_to_user(fd, CMSG_DATA(cm), data,
> +					cmlen - sizeof(struct cmsghdr)))
> +			goto out;
> +		cmlen = CMSG_SPACE(len);
> +		if (msg->msg_controllen < cmlen)
> +			cmlen = msg->msg_controllen;
> +		msg->msg_control += cmlen;
> +		msg->msg_controllen -= cmlen;
> +		err = 0;
> +	}
> +out:
> +	return err;
> +}
> +EXPORT_SYMBOL(rtdm_put_cmsg);
> +
> +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> --
> 2.20.1
>
>



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg()
  2021-05-17  9:44 [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg() François Legal
  2021-07-23  7:04 ` François Legal
@ 2021-07-26 12:01 ` Jan Kiszka
  2021-07-27 12:13   ` François Legal
  1 sibling, 1 reply; 7+ messages in thread
From: Jan Kiszka @ 2021-07-26 12:01 UTC (permalink / raw)
  To: François Legal, xenomai

On 17.05.21 11:44, François Legal via Xenomai wrote:
> This patch enables retrieving, in realtime application, of RTNET enabled adapters packet timestamps.
> It uses the linux semantic SO_TIMESTAMPNS, and the linux code to put the timestamp in the control_msg structure.
> 
> I tested this patch with af_packet sockets only. UDP  & TCP might be a little bit trickier as many fragment/segments get reassembled in a single recvmsg. I believe the linux code I used to put the timestamps in the control structure should be OK though.

One of my question on v1 is still open: How does Linux handle stamping
the context of fragmented UDP and TCP packets? And given that you enable
it for those protocols as well, we should likely test that too.

> 
> Signed-off-by: François LEGAL <devel@thom.fr.eu.org>
> ---
>  kernel/drivers/net/stack/Kconfig              |  8 +++
>  .../drivers/net/stack/include/rtnet_socket.h  |  7 +++
>  kernel/drivers/net/stack/ipv4/tcp/tcp.c       |  8 +++
>  kernel/drivers/net/stack/ipv4/udp/udp.c       |  7 +++
>  kernel/drivers/net/stack/packet/af_packet.c   |  7 +++
>  kernel/drivers/net/stack/socket.c             | 59 +++++++++++++++++++
>  6 files changed, 96 insertions(+)
> 
> diff --git a/kernel/drivers/net/stack/Kconfig b/kernel/drivers/net/stack/Kconfig
> index 830cec5ad..f8ee0f1ad 100644
> --- a/kernel/drivers/net/stack/Kconfig
> +++ b/kernel/drivers/net/stack/Kconfig
> @@ -12,6 +12,14 @@ config XENO_DRIVERS_NET_RX_FIFO_SIZE
>      of two! Effectively, only CONFIG_RTNET_RX_FIFO_SIZE-1 slots will
>      be usable.
>  
> +config XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +    bool "Enable packet timestamping (SO_TIMESTAMPNS)"
> +    depends on XENO_DRIVERS_NET
> +    ---help---
> +    Enable userland access to low level packet timestamps using SO_TIMESTAMPNS
> +    ioctl on socket. Timestamp are then returned in recvmsg calls in msg_control
> +    structure inside msghdr structure.
> +

Why do we need a config option? All it adds in the off-case is a single
bit test.

>  config XENO_DRIVERS_NET_ETH_P_ALL
>      depends on XENO_DRIVERS_NET
>      bool "Support for ETH_P_ALL"
> diff --git a/kernel/drivers/net/stack/include/rtnet_socket.h b/kernel/drivers/net/stack/include/rtnet_socket.h
> index d2caab649..dc488a58a 100644
> --- a/kernel/drivers/net/stack/include/rtnet_socket.h
> +++ b/kernel/drivers/net/stack/include/rtnet_socket.h
> @@ -29,6 +29,7 @@
>  
>  #include <asm/atomic.h>
>  #include <linux/list.h>
> +#include <net/sock.h>
>  
>  #include <rtdev.h>
>  #include <rtdm/net.h>
> @@ -77,6 +78,12 @@ struct rtsocket {
>  	} prot;
>  };
>  
> +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +#define SOCKET_FLAG_TIMESTAMP   SOCK_RCVTSTAMPNS
> +int rtnet_put_cmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int level,
> +					int type, int len, void *data);
> +#endif
> +
>  static inline struct rtdm_fd *rt_socket_fd(struct rtsocket *sock)
>  {
>  	return rtdm_private_to_fd(sock);
> diff --git a/kernel/drivers/net/stack/ipv4/tcp/tcp.c b/kernel/drivers/net/stack/ipv4/tcp/tcp.c
> index d8c189c88..c8b21c521 100644
> --- a/kernel/drivers/net/stack/ipv4/tcp/tcp.c
> +++ b/kernel/drivers/net/stack/ipv4/tcp/tcp.c
> @@ -2027,6 +2027,14 @@ static ssize_t rt_tcp_read(struct rtdm_fd *fd, void *buf, size_t nbyte)
>  			kfree_rtskb(first_skb); /* or store the data? */
>  			return -EFAULT;
>  		}
> +
> +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +		if (test_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags))
> +			rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> +					sizeof(nanosecs_abs_t),
> +					(void *) &skb->time_stamp);
> +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> +
>  		rtdm_lock_get_irqsave(&ts->socket_lock, context);
>  		if (ts->sync.window) {
>  			ts->sync.window += block_size;
> diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c
> index 546b35855..ac6448027 100644
> --- a/kernel/drivers/net/stack/ipv4/udp/udp.c
> +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c
> @@ -463,6 +463,13 @@ ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg,
>  	do {
>  		rtskb_trim(skb, data_len);
>  
> +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +		if (test_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags))
> +			rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> +					sizeof(nanosecs_abs_t),
> +					(void *) &skb->time_stamp);
> +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> +
>  		block_size = skb->len;
>  		copied += block_size;
>  		data_len -= block_size;
> diff --git a/kernel/drivers/net/stack/packet/af_packet.c b/kernel/drivers/net/stack/packet/af_packet.c
> index cc7487303..10e8113fe 100644
> --- a/kernel/drivers/net/stack/packet/af_packet.c
> +++ b/kernel/drivers/net/stack/packet/af_packet.c
> @@ -364,6 +364,13 @@ static ssize_t rt_packet_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg,
>  	if (rtdm_fd_to_context(fd)->device->driver->socket_type != SOCK_DGRAM)
>  		rtskb_push(rtskb, rtskb->data - rtskb->mac.raw);
>  
> +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +		if (test_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags))
> +			rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> +					sizeof(nanosecs_abs_t),
> +					(void *) &rtskb->time_stamp);
> +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> +
>  	/* The data must not be longer than the available buffer size */
>  	copy_len = rtskb->len;
>  	len = rtdm_get_iov_flatlen(iov, msg->msg_iovlen);
> diff --git a/kernel/drivers/net/stack/socket.c b/kernel/drivers/net/stack/socket.c
> index f030663be..5a9702975 100644
> --- a/kernel/drivers/net/stack/socket.c
> +++ b/kernel/drivers/net/stack/socket.c
> @@ -273,6 +273,15 @@ int rt_socket_if_ioctl(struct rtdm_fd *fd, int request, void __user *arg)
>  		return rtnet_put_arg(fd, &u_ifc->ifc_len, &size, sizeof(size));
>  	}
>  
> +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +	if (request == SO_TIMESTAMPNS) {
> +		struct rtsocket *sock = rtdm_fd_to_private(fd);
> +
> +		set_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags);
> +		return 0;
> +	}
> +#endif
> +
>  	u_ifr = arg;
>  	ifr = rtnet_get_arg(fd, &_ifr, u_ifr, sizeof(_ifr));
>  	if (IS_ERR(ifr))
> @@ -393,3 +402,53 @@ int rtnet_put_arg(struct rtdm_fd *fd, void *dst, const void *src, size_t len)
>  	return rtdm_copy_to_user(fd, dst, src, len);
>  }
>  EXPORT_SYMBOL_GPL(rtnet_put_arg);
> +
> +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> +int rtnet_put_cmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int level,
> +					int type, int len, void *data)
> +{
> +	struct cmsghdr __user *cm = msg->msg_control;
> +	struct cmsghdr cmhdr;
> +	int cmlen = CMSG_LEN(len);
> +	int err;
> +
> +	if (MSG_CMSG_COMPAT & msg->msg_flags)
> +		return 0; /* XXX: return error? check spec. */
> +
> +	if ((cm == NULL) || (msg->msg_controllen < sizeof(*cm))) {
> +		msg->msg_flags |= MSG_CTRUNC;
> +		return 0; /* XXX: return error? check spec. */

Please resolve the "XXX" cases. The first one indicates that this does
not work with 32-bit compat apps.

> +	}
> +	if (msg->msg_controllen < cmlen) {
> +		msg->msg_flags |= MSG_CTRUNC;
> +		cmlen = msg->msg_controllen;
> +	}
> +	cmhdr.cmsg_level = level;
> +	cmhdr.cmsg_type = type;
> +	cmhdr.cmsg_len = cmlen;
> +
> +	err = -EFAULT;
> +
> +	if (!rtdm_fd_is_user(fd)) {
> +		memcpy(cm, &cmhdr, sizeof(struct cmsghdr));
> +		memcpy(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr));
> +		err = 0;

This path does not update msg like below.

> +	} else {
> +		if (rtdm_copy_to_user(fd, cm, &cmhdr, sizeof(struct cmsghdr)))
> +			goto out;
> +		if (rtdm_copy_to_user(fd, CMSG_DATA(cm), data,
> +					cmlen - sizeof(struct cmsghdr)))
> +			goto out;

Could also be folded into a "if (... || ...)".

> +		cmlen = CMSG_SPACE(len);
> +		if (msg->msg_controllen < cmlen)
> +			cmlen = msg->msg_controllen;
> +		msg->msg_control += cmlen;
> +		msg->msg_controllen -= cmlen;
> +		err = 0;
> +	}
> +out:
> +	return err;
> +}
> +EXPORT_SYMBOL(rtdm_put_cmsg);
> +
> +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> 

Jan

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Enable retrieving  of RTNET network packet timestamp OOB using recvmsg()
  2021-07-26 12:01 ` Jan Kiszka
@ 2021-07-27 12:13   ` François Legal
  2021-07-27 16:44     ` Jan Kiszka
  0 siblings, 1 reply; 7+ messages in thread
From: François Legal @ 2021-07-27 12:13 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai

Le Lundi, Juillet 26, 2021 14:01 CEST, Jan Kiszka <jan.kiszka@siemens.com> a écrit:

> On 17.05.21 11:44, François Legal via Xenomai wrote:
> > This patch enables retrieving, in realtime application, of RTNET enabled adapters packet timestamps.
> > It uses the linux semantic SO_TIMESTAMPNS, and the linux code to put the timestamp in the control_msg structure.
> >
> > I tested this patch with af_packet sockets only. UDP  & TCP might be a little bit trickier as many fragment/segments get reassembled in a single recvmsg. I believe the linux code I used to put the timestamps in the control structure should be OK though.
>
> One of my question on v1 is still open: How does Linux handle stamping
> the context of fragmented UDP and TCP packets? And given that you enable
> it for those protocols as well, we should likely test that too.

I thought I already gave an answer to this. Sorry.
Linux does not handle time stamping of UDP and TCP as far as I understand.
I certainly plan to use the UDP timestamping feature at some point in the future, but maybe I can exclude UDP and TCP for the moment, and stick to af_packet which has be tested by myself. I'll resubmit another patch with (at least) udp support whenever I need it and have time to test it.

What do you think ?

François

>
> >
> > Signed-off-by: François LEGAL <devel@thom.fr.eu.org>
> > ---
> >  kernel/drivers/net/stack/Kconfig              |  8 +++
> >  .../drivers/net/stack/include/rtnet_socket.h  |  7 +++
> >  kernel/drivers/net/stack/ipv4/tcp/tcp.c       |  8 +++
> >  kernel/drivers/net/stack/ipv4/udp/udp.c       |  7 +++
> >  kernel/drivers/net/stack/packet/af_packet.c   |  7 +++
> >  kernel/drivers/net/stack/socket.c             | 59 +++++++++++++++++++
> >  6 files changed, 96 insertions(+)
> >
> > diff --git a/kernel/drivers/net/stack/Kconfig b/kernel/drivers/net/stack/Kconfig
> > index 830cec5ad..f8ee0f1ad 100644
> > --- a/kernel/drivers/net/stack/Kconfig
> > +++ b/kernel/drivers/net/stack/Kconfig
> > @@ -12,6 +12,14 @@ config XENO_DRIVERS_NET_RX_FIFO_SIZE
> >      of two! Effectively, only CONFIG_RTNET_RX_FIFO_SIZE-1 slots will
> >      be usable.
> >
> > +config XENO_DRIVERS_NET_PACKET_TIMESTAMP
> > +    bool "Enable packet timestamping (SO_TIMESTAMPNS)"
> > +    depends on XENO_DRIVERS_NET
> > +    ---help---
> > +    Enable userland access to low level packet timestamps using SO_TIMESTAMPNS
> > +    ioctl on socket. Timestamp are then returned in recvmsg calls in msg_control
> > +    structure inside msghdr structure.
> > +
>
> Why do we need a config option? All it adds in the off-case is a single
> bit test.
>
> >  config XENO_DRIVERS_NET_ETH_P_ALL
> >      depends on XENO_DRIVERS_NET
> >      bool "Support for ETH_P_ALL"
> > diff --git a/kernel/drivers/net/stack/include/rtnet_socket.h b/kernel/drivers/net/stack/include/rtnet_socket.h
> > index d2caab649..dc488a58a 100644
> > --- a/kernel/drivers/net/stack/include/rtnet_socket.h
> > +++ b/kernel/drivers/net/stack/include/rtnet_socket.h
> > @@ -29,6 +29,7 @@
> >
> >  #include <asm/atomic.h>
> >  #include <linux/list.h>
> > +#include <net/sock.h>
> >
> >  #include <rtdev.h>
> >  #include <rtdm/net.h>
> > @@ -77,6 +78,12 @@ struct rtsocket {
> >  	} prot;
> >  };
> >
> > +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> > +#define SOCKET_FLAG_TIMESTAMP   SOCK_RCVTSTAMPNS
> > +int rtnet_put_cmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int level,
> > +					int type, int len, void *data);
> > +#endif
> > +
> >  static inline struct rtdm_fd *rt_socket_fd(struct rtsocket *sock)
> >  {
> >  	return rtdm_private_to_fd(sock);
> > diff --git a/kernel/drivers/net/stack/ipv4/tcp/tcp.c b/kernel/drivers/net/stack/ipv4/tcp/tcp.c
> > index d8c189c88..c8b21c521 100644
> > --- a/kernel/drivers/net/stack/ipv4/tcp/tcp.c
> > +++ b/kernel/drivers/net/stack/ipv4/tcp/tcp.c
> > @@ -2027,6 +2027,14 @@ static ssize_t rt_tcp_read(struct rtdm_fd *fd, void *buf, size_t nbyte)
> >  			kfree_rtskb(first_skb); /* or store the data? */
> >  			return -EFAULT;
> >  		}
> > +
> > +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> > +		if (test_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags))
> > +			rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> > +					sizeof(nanosecs_abs_t),
> > +					(void *) &skb->time_stamp);
> > +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> > +
> >  		rtdm_lock_get_irqsave(&ts->socket_lock, context);
> >  		if (ts->sync.window) {
> >  			ts->sync.window += block_size;
> > diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c
> > index 546b35855..ac6448027 100644
> > --- a/kernel/drivers/net/stack/ipv4/udp/udp.c
> > +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c
> > @@ -463,6 +463,13 @@ ssize_t rt_udp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg,
> >  	do {
> >  		rtskb_trim(skb, data_len);
> >
> > +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> > +		if (test_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags))
> > +			rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> > +					sizeof(nanosecs_abs_t),
> > +					(void *) &skb->time_stamp);
> > +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> > +
> >  		block_size = skb->len;
> >  		copied += block_size;
> >  		data_len -= block_size;
> > diff --git a/kernel/drivers/net/stack/packet/af_packet.c b/kernel/drivers/net/stack/packet/af_packet.c
> > index cc7487303..10e8113fe 100644
> > --- a/kernel/drivers/net/stack/packet/af_packet.c
> > +++ b/kernel/drivers/net/stack/packet/af_packet.c
> > @@ -364,6 +364,13 @@ static ssize_t rt_packet_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg,
> >  	if (rtdm_fd_to_context(fd)->device->driver->socket_type != SOCK_DGRAM)
> >  		rtskb_push(rtskb, rtskb->data - rtskb->mac.raw);
> >
> > +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> > +		if (test_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags))
> > +			rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> > +					sizeof(nanosecs_abs_t),
> > +					(void *) &rtskb->time_stamp);
> > +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> > +
> >  	/* The data must not be longer than the available buffer size */
> >  	copy_len = rtskb->len;
> >  	len = rtdm_get_iov_flatlen(iov, msg->msg_iovlen);
> > diff --git a/kernel/drivers/net/stack/socket.c b/kernel/drivers/net/stack/socket.c
> > index f030663be..5a9702975 100644
> > --- a/kernel/drivers/net/stack/socket.c
> > +++ b/kernel/drivers/net/stack/socket.c
> > @@ -273,6 +273,15 @@ int rt_socket_if_ioctl(struct rtdm_fd *fd, int request, void __user *arg)
> >  		return rtnet_put_arg(fd, &u_ifc->ifc_len, &size, sizeof(size));
> >  	}
> >
> > +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> > +	if (request == SO_TIMESTAMPNS) {
> > +		struct rtsocket *sock = rtdm_fd_to_private(fd);
> > +
> > +		set_bit(SOCKET_FLAG_TIMESTAMP, &sock->flags);
> > +		return 0;
> > +	}
> > +#endif
> > +
> >  	u_ifr = arg;
> >  	ifr = rtnet_get_arg(fd, &_ifr, u_ifr, sizeof(_ifr));
> >  	if (IS_ERR(ifr))
> > @@ -393,3 +402,53 @@ int rtnet_put_arg(struct rtdm_fd *fd, void *dst, const void *src, size_t len)
> >  	return rtdm_copy_to_user(fd, dst, src, len);
> >  }
> >  EXPORT_SYMBOL_GPL(rtnet_put_arg);
> > +
> > +#ifdef CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP
> > +int rtnet_put_cmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int level,
> > +					int type, int len, void *data)
> > +{
> > +	struct cmsghdr __user *cm = msg->msg_control;
> > +	struct cmsghdr cmhdr;
> > +	int cmlen = CMSG_LEN(len);
> > +	int err;
> > +
> > +	if (MSG_CMSG_COMPAT & msg->msg_flags)
> > +		return 0; /* XXX: return error? check spec. */
> > +
> > +	if ((cm == NULL) || (msg->msg_controllen < sizeof(*cm))) {
> > +		msg->msg_flags |= MSG_CTRUNC;
> > +		return 0; /* XXX: return error? check spec. */
>
> Please resolve the "XXX" cases. The first one indicates that this does
> not work with 32-bit compat apps.
>
> > +	}
> > +	if (msg->msg_controllen < cmlen) {
> > +		msg->msg_flags |= MSG_CTRUNC;
> > +		cmlen = msg->msg_controllen;
> > +	}
> > +	cmhdr.cmsg_level = level;
> > +	cmhdr.cmsg_type = type;
> > +	cmhdr.cmsg_len = cmlen;
> > +
> > +	err = -EFAULT;
> > +
> > +	if (!rtdm_fd_is_user(fd)) {
> > +		memcpy(cm, &cmhdr, sizeof(struct cmsghdr));
> > +		memcpy(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr));
> > +		err = 0;
>
> This path does not update msg like below.
>
> > +	} else {
> > +		if (rtdm_copy_to_user(fd, cm, &cmhdr, sizeof(struct cmsghdr)))
> > +			goto out;
> > +		if (rtdm_copy_to_user(fd, CMSG_DATA(cm), data,
> > +					cmlen - sizeof(struct cmsghdr)))
> > +			goto out;
>
> Could also be folded into a "if (... || ...)".
>
> > +		cmlen = CMSG_SPACE(len);
> > +		if (msg->msg_controllen < cmlen)
> > +			cmlen = msg->msg_controllen;
> > +		msg->msg_control += cmlen;
> > +		msg->msg_controllen -= cmlen;
> > +		err = 0;
> > +	}
> > +out:
> > +	return err;
> > +}
> > +EXPORT_SYMBOL(rtdm_put_cmsg);
> > +
> > +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> >
>
> Jan
>
> --
> Siemens AG, T RDA IOT
> Corporate Competence Center Embedded Linux



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg()
  2021-07-27 12:13   ` François Legal
@ 2021-07-27 16:44     ` Jan Kiszka
  2021-07-29  7:32       ` François Legal
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Kiszka @ 2021-07-27 16:44 UTC (permalink / raw)
  To: François Legal; +Cc: xenomai

On 27.07.21 14:13, François Legal wrote:
> Le Lundi, Juillet 26, 2021 14:01 CEST, Jan Kiszka <jan.kiszka@siemens.com> a écrit: 
>  
>> On 17.05.21 11:44, François Legal via Xenomai wrote:
>>> This patch enables retrieving, in realtime application, of RTNET enabled adapters packet timestamps.
>>> It uses the linux semantic SO_TIMESTAMPNS, and the linux code to put the timestamp in the control_msg structure.
>>>
>>> I tested this patch with af_packet sockets only. UDP  & TCP might be a little bit trickier as many fragment/segments get reassembled in a single recvmsg. I believe the linux code I used to put the timestamps in the control structure should be OK though.
>>
>> One of my question on v1 is still open: How does Linux handle stamping
>> the context of fragmented UDP and TCP packets? And given that you enable
>> it for those protocols as well, we should likely test that too.
> 
> I thought I already gave an answer to this. Sorry.
> Linux does not handle time stamping of UDP and TCP as far as I understand.

Does Linux return an error when you try to enable this for UDP or TCP
sockets?

> I certainly plan to use the UDP timestamping feature at some point in the future, but maybe I can exclude UDP and TCP for the moment, and stick to af_packet which has be tested by myself. I'll resubmit another patch with (at least) udp support whenever I need it and have time to test it.
> 
> What do you think ?

We need at least a plan how to evolve that interface. Actually doing
that can then happen in steps, yes.

Jan

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Enable retrieving  of RTNET network packet timestamp OOB using recvmsg()
  2021-07-27 16:44     ` Jan Kiszka
@ 2021-07-29  7:32       ` François Legal
  2021-08-02  8:16         ` Jan Kiszka
  0 siblings, 1 reply; 7+ messages in thread
From: François Legal @ 2021-07-29  7:32 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai

Le Mardi, Juillet 27, 2021 18:44 CEST, Jan Kiszka <jan.kiszka@siemens.com> a écrit:

> On 27.07.21 14:13, François Legal wrote:
> > Le Lundi, Juillet 26, 2021 14:01 CEST, Jan Kiszka <jan.kiszka@siemens.com> a écrit:
> >
> >> On 17.05.21 11:44, François Legal via Xenomai wrote:
> >>> This patch enables retrieving, in realtime application, of RTNET enabled adapters packet timestamps.
> >>> It uses the linux semantic SO_TIMESTAMPNS, and the linux code to put the timestamp in the control_msg structure.
> >>>
> >>> I tested this patch with af_packet sockets only. UDP  & TCP might be a little bit trickier as many fragment/segments get reassembled in a single recvmsg. I believe the linux code I used to put the timestamps in the control structure should be OK though.
> >>
> >> One of my question on v1 is still open: How does Linux handle stamping
> >> the context of fragmented UDP and TCP packets? And given that you enable
> >> it for those protocols as well, we should likely test that too.
> >
> > I thought I already gave an answer to this. Sorry.
> > Linux does not handle time stamping of UDP and TCP as far as I understand.
>
> Does Linux return an error when you try to enable this for UDP or TCP
> sockets?

Alright so I rechecked everything again. Linux does not return an error when requesting timestamping for UDP or TCP (or any other kind of socket it seems).

Despite my previous assertion, timestamping is supported for UDP  and if I understood the code correctly, only one timestamp is returned in any case (the time stamp of the last received datagram). This is done in reassembly queues, where the queue always keep the timestamp of the last received datagram, and when doing the reassembly, this last timestamp is reported to the re created skb.

For TCP it is definitely not supported.

So I should modify the patch to make it comply with what linux does I guess ?

>
> > I certainly plan to use the UDP timestamping feature at some point in the future, but maybe I can exclude UDP and TCP for the moment, and stick to af_packet which has be tested by myself. I'll resubmit another patch with (at least) udp support whenever I need it and have time to test it.
> >
> > What do you think ?
>
> We need at least a plan how to evolve that interface. Actually doing
> that can then happen in steps, yes.
>
> Jan
>
> --
> Siemens AG, T RDA IOT
> Corporate Competence Center Embedded Linux



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg()
  2021-07-29  7:32       ` François Legal
@ 2021-08-02  8:16         ` Jan Kiszka
  0 siblings, 0 replies; 7+ messages in thread
From: Jan Kiszka @ 2021-08-02  8:16 UTC (permalink / raw)
  To: François Legal; +Cc: xenomai

On 29.07.21 09:32, François Legal wrote:
> Le Mardi, Juillet 27, 2021 18:44 CEST, Jan Kiszka <jan.kiszka@siemens.com> a écrit: 
>  
>> On 27.07.21 14:13, François Legal wrote:
>>> Le Lundi, Juillet 26, 2021 14:01 CEST, Jan Kiszka <jan.kiszka@siemens.com> a écrit: 
>>>  
>>>> On 17.05.21 11:44, François Legal via Xenomai wrote:
>>>>> This patch enables retrieving, in realtime application, of RTNET enabled adapters packet timestamps.
>>>>> It uses the linux semantic SO_TIMESTAMPNS, and the linux code to put the timestamp in the control_msg structure.
>>>>>
>>>>> I tested this patch with af_packet sockets only. UDP  & TCP might be a little bit trickier as many fragment/segments get reassembled in a single recvmsg. I believe the linux code I used to put the timestamps in the control structure should be OK though.
>>>>
>>>> One of my question on v1 is still open: How does Linux handle stamping
>>>> the context of fragmented UDP and TCP packets? And given that you enable
>>>> it for those protocols as well, we should likely test that too.
>>>
>>> I thought I already gave an answer to this. Sorry.
>>> Linux does not handle time stamping of UDP and TCP as far as I understand.
>>
>> Does Linux return an error when you try to enable this for UDP or TCP
>> sockets?
> 
> Alright so I rechecked everything again. Linux does not return an error when requesting timestamping for UDP or TCP (or any other kind of socket it seems).
> 
> Despite my previous assertion, timestamping is supported for UDP  and if I understood the code correctly, only one timestamp is returned in any case (the time stamp of the last received datagram). This is done in reassembly queues, where the queue always keep the timestamp of the last received datagram, and when doing the reassembly, this last timestamp is reported to the re created skb.
> 
> For TCP it is definitely not supported.
> 
> So I should modify the patch to make it comply with what linux does I guess ?
> 

Yes, unless there is any good (RT/Xenomai-specific) reason speaking
against alignment, we should do this - least surprise.

Jan

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-08-02  8:16 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-17  9:44 [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg() François Legal
2021-07-23  7:04 ` François Legal
2021-07-26 12:01 ` Jan Kiszka
2021-07-27 12:13   ` François Legal
2021-07-27 16:44     ` Jan Kiszka
2021-07-29  7:32       ` François Legal
2021-08-02  8:16         ` Jan Kiszka

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.