Re: [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg()

2021-08-02 Thread Jan Kiszka via Xenomai
On 29.07.21 09:32, François Legal wrote:
> Le Mardi, Juillet 27, 2021 18:44 CEST, Jan Kiszka  a 
> écrit: 
>  
>> On 27.07.21 14:13, François Legal wrote:
>>> Le Lundi, Juillet 26, 2021 14:01 CEST, Jan Kiszka  
>>> 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



Re: [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg()

2021-07-29 Thread François Legal via Xenomai
Le Mardi, Juillet 27, 2021 18:44 CEST, Jan Kiszka  a 
écrit:

> On 27.07.21 14:13, François Legal wrote:
> > Le Lundi, Juillet 26, 2021 14:01 CEST, Jan Kiszka  
> > 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




Re: [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg()

2021-07-27 Thread Jan Kiszka via Xenomai
On 27.07.21 14:13, François Legal wrote:
> Le Lundi, Juillet 26, 2021 14:01 CEST, Jan Kiszka  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



Re: [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg()

2021-07-27 Thread François Legal via Xenomai
Le Lundi, Juillet 26, 2021 14:01 CEST, Jan Kiszka  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 
> > ---
> >  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 
> >  #include 
> > +#include 
> >
> >  #include 
> >  #include 
> > @@ -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, >flags))
> > +   rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> > +   sizeof(nanosecs_abs_t),
> > +   (void *) >time_stamp);
> > +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> > +
> > rtdm_lock_get_irqsave(>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);
> >
> 

Re: [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg()

2021-07-26 Thread Jan Kiszka via 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 
> ---
>  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 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> @@ -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, >flags))
> + rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> + sizeof(nanosecs_abs_t),
> + (void *) >time_stamp);
> +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> +
>   rtdm_lock_get_irqsave(>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, >flags))
> + rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> + sizeof(nanosecs_abs_t),
> + (void *) >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
> --- 

Re: [PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg()

2021-07-23 Thread François Legal via 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 
 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 
> ---
>  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 
>  #include 
> +#include 
>
>  #include 
>  #include 
> @@ -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, >flags))
> + rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> + sizeof(nanosecs_abs_t),
> + (void *) >time_stamp);
> +#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
> +
>   rtdm_lock_get_irqsave(>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, >flags))
> + rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
> + sizeof(nanosecs_abs_t),
> + (void *) >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 

[PATCH v2] Enable retrieving of RTNET network packet timestamp OOB using recvmsg()

2021-05-17 Thread François Legal via 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 
---
 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 
 #include 
+#include 

 #include 
 #include 
@@ -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, >flags))
+   rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
+   sizeof(nanosecs_abs_t),
+   (void *) >time_stamp);
+#endif /* CONFIG_XENO_DRIVERS_NET_PACKET_TIMESTAMP */
+
rtdm_lock_get_irqsave(>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, >flags))
+   rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
+   sizeof(nanosecs_abs_t),
+   (void *) >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, >flags))
+   rtnet_put_cmsg(fd, msg, SOL_SOCKET, SCM_TIMESTAMPNS,
+