Linux kernel UDP receive time

I read the network binding timestamping documentation on the linux kernel, and there is something that I don't understand.

Where is the timestamp provided by SO_TIMESTAMPNS ? In hardware or in the kernel? If so, then as soon as a new package is interrupted?

SO_TIMESTAMPING should also allow the generation of time stamps of equipment. Is it supported by all network adapters? How is SO_TIMESTAMPING with parameters SOF_TIMESTAMPING_RX_HARDWARE and SO_TIMESTAMPNS ? In this case, is the hardware timestamp related to the system clock or NIC clock? In the second case, how to restore the NIC clock to calculate elapsed time?

+6
source share
1 answer

The socket attribute used for the software timestamp is SO_TIMESTAMPNS. This socket attribute returns the time from the system clock. It is not generated in hardware; rather, it is a snapshot of the system time when an interrupt is processed in software. We can access this timestamp using ancillary data (CMSG) that are not part of the socket payload using:

 int level, type; struct cmsghdr *cm; struct timespec *ts = NULL; for (cm = CMSG_FIRSTHDR(&msg); cm != NULL; cm = CMSG_NXTHDR(&msg, cm)) { level = cm->cmsg_level; type = cm->cmsg_type; if (SOL_SOCKET == level && SO_TIMESTAMPNS == type) { ts = (struct timespec *) CMSG_DATA(cm); printf("SW TIMESTAMP %ld.%09ld\n", (long)ts[0].tv_sec, (long)ts[0].tv_nsec); } } 

The socket parameter SO_TIMESTAMPING offers many different flags, some of them,

 SOF_TIMESTAMPING_TX_HARDWARE // Transmit timestamp generated in hardware by NIC clock SOF_TIMESTAMPING_RX_HARDWARE // Receive timestamp generated in hardware by NIC clock SOF_TIMESTAMPING_TX_SOFTWARE // Transmit timestamp generated in kernel driver by NIC clock SOF_TIMESTAMPING_RX_SOFTWARE // Receive timestamp generated in kernel driver by NIC clock 

This socket option is not supported by all network interfaces (NICs). Currently, many network adapters support SO_TIMESTAMPING. To find out if any driver supports the SO_TIMESTAMPING interface, use:

 ethtool -T ethX // where X corresponds to your particular interface 

This will return all socket attributes. Support, thanks for the timestamping.

To use the timestamping hardware feature provided by a particular network adapter, use the code:

 int flags; flags = SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_RAW_HARDWARE; if (setsockopt(sd, SOL_SOCKET, SO_TIMESTAMPING, &flags, sizeof(flags)) < 0) printf("ERROR: setsockopt SO_TIMESTAMPING\n"); int level, type; struct cmsghdr *cm; struct timespec *ts = NULL; for (cm = CMSG_FIRSTHDR(&msg); cm != NULL; cm = CMSG_NXTHDR(&msg, cm)) { if (SOL_SOCKET == level && SO_TIMESTAMPING == type) { ts = (struct timespec *) CMSG_DATA(cm); printf("HW TIMESTAMP %ld.%09ld\n", (long)ts[2].tv_sec, (long)ts[2].tv_nsec); } } 
+4
source

Source: https://habr.com/ru/post/1014317/


All Articles