-
Notifications
You must be signed in to change notification settings - Fork 842
Expand file tree
/
Copy pathethtool_linux.go
More file actions
67 lines (58 loc) · 1.94 KB
/
Copy pathethtool_linux.go
File metadata and controls
67 lines (58 loc) · 1.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package netlink
import (
"errors"
"fmt"
"syscall"
"github.com/vishvananda/netlink/nl"
"golang.org/x/sys/unix"
)
func (h *Handle) ethtoolRequest(command uint8, flags int, attrs []*nl.RtAttr) ([][]syscall.NetlinkRouteAttr, error) {
family, err := h.GenlFamilyGet(nl.ETHTOOL_GENL_NAME)
if err != nil {
return nil, err
}
req := h.newNetlinkRequest(int(family.ID), flags)
req.AddData(&nl.Genlmsg{
Command: command,
Version: nl.ETHTOOL_GENL_VERSION,
})
for _, attr := range attrs {
req.AddData(attr)
}
msgs, executeErr := req.Execute(unix.NETLINK_GENERIC, 0)
if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) {
return nil, executeErr
}
parsed := make([][]syscall.NetlinkRouteAttr, 0, len(msgs))
for _, msg := range msgs {
if len(msg) < nl.SizeofGenlmsg {
return nil, fmt.Errorf("netlink: short ethtool response: got %d bytes, want at least %d", len(msg), nl.SizeofGenlmsg)
}
attrs, err := nl.ParseRouteAttr(msg[nl.SizeofGenlmsg:])
if err != nil {
return nil, err
}
parsed = append(parsed, attrs)
}
return parsed, executeErr
}
func newEthtoolHeader(attrType, ifIndex int) (*nl.RtAttr, error) {
if ifIndex <= 0 || uint64(ifIndex) > uint64(^uint32(0)) {
return nil, fmt.Errorf("netlink: invalid interface index %d", ifIndex)
}
header := nl.NewRtAttr(unix.NLA_F_NESTED|attrType, nil)
header.AddRtAttr(nl.ETHTOOL_A_HEADER_DEV_INDEX, nl.Uint32Attr(uint32(ifIndex)))
return header, nil
}
func readEthtoolUint8(attr syscall.NetlinkRouteAttr) (uint8, error) {
if len(attr.Value) != 1 {
return 0, fmt.Errorf("netlink: ethtool attribute %d has %d bytes, want 1", attr.Attr.Type&nl.NLA_TYPE_MASK, len(attr.Value))
}
return attr.Value[0], nil
}
func readEthtoolUint32(attr syscall.NetlinkRouteAttr) (uint32, error) {
if len(attr.Value) != 4 {
return 0, fmt.Errorf("netlink: ethtool attribute %d has %d bytes, want 4", attr.Attr.Type&nl.NLA_TYPE_MASK, len(attr.Value))
}
return native.Uint32(attr.Value), nil
}