unix: add IoctlGetEthtoolTsInfo

The function fetches ethtool timestamping and PHC association for a
network interface. Its primary usage is to query the mapping between
the interface and its corresponding PTP clock number in /dev/ptp𝑛.
This commit is contained in:
Yaroslav Kolomiiets
2024-10-10 11:56:00 +01:00
parent 7143f4a4e1
commit 3743a3a650
4 changed files with 65 additions and 0 deletions

View File

@@ -58,6 +58,21 @@ func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) {
return &value, err
}
// IoctlGetEthtoolTsInfo fetches ethtool timestamping and PHC
// association for the network device specified by ifname.
func IoctlGetEthtoolTsInfo(fd int, ifname string) (*EthtoolTsInfo, error) {
ifr, err := NewIfreq(ifname)
if err != nil {
return nil, err
}
value := EthtoolTsInfo{Cmd: ETHTOOL_GET_TS_INFO}
ifrd := ifr.withData(unsafe.Pointer(&value))
err = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd)
return &value, err
}
// IoctlGetWatchdogInfo fetches information about a watchdog device from the
// Linux watchdog API. For more information, see:
// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.

View File

@@ -4090,6 +4090,8 @@ const SPEED_UNKNOWN = C.SPEED_UNKNOWN
type EthtoolDrvinfo C.struct_ethtool_drvinfo
type EthtoolTsInfo C.struct_ethtool_ts_info
type (
HIDRawReportDescriptor C.struct_hidraw_report_descriptor
HIDRawDevInfo C.struct_hidraw_devinfo

View File

@@ -68,6 +68,44 @@ func TestIoctlGetEthtoolDrvinfo(t *testing.T) {
}
}
func TestIoctlGetEthtoolTsInfo(t *testing.T) {
if runtime.GOOS == "android" {
t.Skip("ethtool driver info is not available on android, skipping test")
}
s, err := unix.Socket(unix.AF_INET, unix.SOCK_STREAM, 0)
if err != nil {
t.Fatalf("failed to open socket: %v", err)
}
defer unix.Close(s)
ifis, err := net.Interfaces()
if err != nil {
t.Fatalf("failed to get network interfaces: %v", err)
}
// Print the interface name and associated PHC information for each
// network interface supported by ethtool.
for _, ifi := range ifis {
tsi, err := unix.IoctlGetEthtoolTsInfo(s, ifi.Name)
if err != nil {
if err == unix.EOPNOTSUPP {
continue
}
if err == unix.EBUSY {
// See https://go.dev/issues/67350
t.Logf("%s: ethtool driver busy, possible kernel bug", ifi.Name)
continue
}
t.Fatalf("failed to get ethtool PHC info for %q: %v", ifi.Name, err)
}
t.Logf("%s: ptp%d", ifi.Name, tsi.Phc_index)
}
}
func TestIoctlGetInt(t *testing.T) {
f, err := os.Open("/dev/random")
if err != nil {

View File

@@ -4110,6 +4110,16 @@ type EthtoolDrvinfo struct {
Regdump_len uint32
}
type EthtoolTsInfo struct {
Cmd uint32
So_timestamping uint32
Phc_index int32
Tx_types uint32
Tx_reserved [3]uint32
Rx_filters uint32
Rx_reserved [3]uint32
}
type (
HIDRawReportDescriptor struct {
Size uint32