update ethtool
This commit is contained in:
parent
e8c953999e
commit
addbcd34b4
2
go.mod
2
go.mod
@ -19,7 +19,7 @@ require (
|
|||||||
github.com/mattn/go-shellwords v1.0.3
|
github.com/mattn/go-shellwords v1.0.3
|
||||||
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b
|
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b
|
||||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a
|
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a
|
||||||
github.com/safchain/ethtool v0.0.0-20170622225139-7ff1ba29eca2
|
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8
|
||||||
github.com/sirupsen/logrus v1.0.6 // indirect
|
github.com/sirupsen/logrus v1.0.6 // indirect
|
||||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf
|
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf
|
||||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc // indirect
|
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -36,6 +36,8 @@ github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a h1:KfNOeFvoAssuZLT7Int
|
|||||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||||
github.com/safchain/ethtool v0.0.0-20170622225139-7ff1ba29eca2 h1:f10KcdY8NPt2w0/M2o+O9uCiH8sHpS6OVAHcf4BPL7Y=
|
github.com/safchain/ethtool v0.0.0-20170622225139-7ff1ba29eca2 h1:f10KcdY8NPt2w0/M2o+O9uCiH8sHpS6OVAHcf4BPL7Y=
|
||||||
github.com/safchain/ethtool v0.0.0-20170622225139-7ff1ba29eca2/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
github.com/safchain/ethtool v0.0.0-20170622225139-7ff1ba29eca2/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
||||||
|
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8 h1:2c1EFnZHIPCW8qKWgHMH/fX2PkSabFc5mrVzfUNdg5U=
|
||||||
|
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
||||||
github.com/sirupsen/logrus v1.0.6 h1:hcP1GmhGigz/O7h1WVUM5KklBp1JoNS9FggWKdj/j3s=
|
github.com/sirupsen/logrus v1.0.6 h1:hcP1GmhGigz/O7h1WVUM5KklBp1JoNS9FggWKdj/j3s=
|
||||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf h1:3J37+NPjNyGW/dbfXtj3yWuF9OEepIdGOXRaJGbORV8=
|
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf h1:3J37+NPjNyGW/dbfXtj3yWuF9OEepIdGOXRaJGbORV8=
|
||||||
|
3
vendor/github.com/safchain/ethtool/.gitignore
generated
vendored
3
vendor/github.com/safchain/ethtool/.gitignore
generated
vendored
@ -22,3 +22,6 @@ _testmain.go
|
|||||||
*.exe
|
*.exe
|
||||||
*.test
|
*.test
|
||||||
*.prof
|
*.prof
|
||||||
|
|
||||||
|
# Skip compiled example binary file
|
||||||
|
/example/example
|
||||||
|
4
vendor/github.com/safchain/ethtool/Makefile
generated
vendored
Normal file
4
vendor/github.com/safchain/ethtool/Makefile
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
all: build
|
||||||
|
|
||||||
|
build:
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
|
1
vendor/github.com/safchain/ethtool/README.md
generated
vendored
1
vendor/github.com/safchain/ethtool/README.md
generated
vendored
@ -33,6 +33,7 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
}
|
}
|
||||||
|
defer ethHandle.Close()
|
||||||
|
|
||||||
// Retrieve tx from eth0
|
// Retrieve tx from eth0
|
||||||
stats, err := ethHandle.Stats("eth0")
|
stats, err := ethHandle.Stats("eth0")
|
||||||
|
363
vendor/github.com/safchain/ethtool/ethtool.go
generated
vendored
363
vendor/github.com/safchain/ethtool/ethtool.go
generated
vendored
@ -27,7 +27,9 @@ package ethtool
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@ -46,6 +48,7 @@ const (
|
|||||||
const (
|
const (
|
||||||
ETH_GSTRING_LEN = 32
|
ETH_GSTRING_LEN = 32
|
||||||
ETH_SS_STATS = 1
|
ETH_SS_STATS = 1
|
||||||
|
ETH_SS_FEATURES = 4
|
||||||
ETHTOOL_GDRVINFO = 0x00000003
|
ETHTOOL_GDRVINFO = 0x00000003
|
||||||
ETHTOOL_GSTRINGS = 0x0000001b
|
ETHTOOL_GSTRINGS = 0x0000001b
|
||||||
ETHTOOL_GSTATS = 0x0000001d
|
ETHTOOL_GSTATS = 0x0000001d
|
||||||
@ -54,12 +57,25 @@ const (
|
|||||||
ETHTOOL_SSET = 0x00000002 /* Set settings. */
|
ETHTOOL_SSET = 0x00000002 /* Set settings. */
|
||||||
ETHTOOL_GMSGLVL = 0x00000007 /* Get driver message level */
|
ETHTOOL_GMSGLVL = 0x00000007 /* Get driver message level */
|
||||||
ETHTOOL_SMSGLVL = 0x00000008 /* Set driver msg level. */
|
ETHTOOL_SMSGLVL = 0x00000008 /* Set driver msg level. */
|
||||||
|
/* Get link status for host, i.e. whether the interface *and* the
|
||||||
|
* physical port (if there is one) are up (ethtool_value). */
|
||||||
|
ETHTOOL_GLINK = 0x0000000a
|
||||||
|
ETHTOOL_GMODULEINFO = 0x00000042 /* Get plug-in module information */
|
||||||
|
ETHTOOL_GMODULEEEPROM = 0x00000043 /* Get plug-in module eeprom */
|
||||||
|
ETHTOOL_GPERMADDR = 0x00000020
|
||||||
|
ETHTOOL_GFEATURES = 0x0000003a /* Get device offload settings */
|
||||||
|
ETHTOOL_SFEATURES = 0x0000003b /* Change device offload settings */
|
||||||
|
ETHTOOL_GFLAGS = 0x00000025 /* Get flags bitmap(ethtool_value) */
|
||||||
|
ETHTOOL_GSSET_INFO = 0x00000037 /* Get string set info */
|
||||||
)
|
)
|
||||||
|
|
||||||
// MAX_GSTRINGS maximum number of stats entries that ethtool can
|
// MAX_GSTRINGS maximum number of stats entries that ethtool can
|
||||||
// retrieve currently.
|
// retrieve currently.
|
||||||
const (
|
const (
|
||||||
MAX_GSTRINGS = 1000
|
MAX_GSTRINGS = 1000
|
||||||
|
MAX_FEATURE_BLOCKS = (MAX_GSTRINGS + 32 - 1) / 32
|
||||||
|
EEPROM_LEN = 640
|
||||||
|
PERMADDR_LEN = 32
|
||||||
)
|
)
|
||||||
|
|
||||||
type ifreq struct {
|
type ifreq struct {
|
||||||
@ -67,6 +83,38 @@ type ifreq struct {
|
|||||||
ifr_data uintptr
|
ifr_data uintptr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// following structures comes from uapi/linux/ethtool.h
|
||||||
|
type ethtoolSsetInfo struct {
|
||||||
|
cmd uint32
|
||||||
|
reserved uint32
|
||||||
|
sset_mask uint32
|
||||||
|
data uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
type ethtoolGetFeaturesBlock struct {
|
||||||
|
available uint32
|
||||||
|
requested uint32
|
||||||
|
active uint32
|
||||||
|
never_changed uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type ethtoolGfeatures struct {
|
||||||
|
cmd uint32
|
||||||
|
size uint32
|
||||||
|
blocks [MAX_FEATURE_BLOCKS]ethtoolGetFeaturesBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
type ethtoolSetFeaturesBlock struct {
|
||||||
|
valid uint32
|
||||||
|
requested uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type ethtoolSfeatures struct {
|
||||||
|
cmd uint32
|
||||||
|
size uint32
|
||||||
|
blocks [MAX_FEATURE_BLOCKS]ethtoolSetFeaturesBlock
|
||||||
|
}
|
||||||
|
|
||||||
type ethtoolDrvInfo struct {
|
type ethtoolDrvInfo struct {
|
||||||
cmd uint32
|
cmd uint32
|
||||||
driver [32]byte
|
driver [32]byte
|
||||||
@ -95,11 +143,37 @@ type ethtoolStats struct {
|
|||||||
data [MAX_GSTRINGS]uint64
|
data [MAX_GSTRINGS]uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ethtoolEeprom struct {
|
||||||
|
cmd uint32
|
||||||
|
magic uint32
|
||||||
|
offset uint32
|
||||||
|
len uint32
|
||||||
|
data [EEPROM_LEN]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type ethtoolModInfo struct {
|
||||||
|
cmd uint32
|
||||||
|
tpe uint32
|
||||||
|
eeprom_len uint32
|
||||||
|
reserved [8]uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type ethtoolLink struct {
|
||||||
|
cmd uint32
|
||||||
|
data uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type ethtoolPermAddr struct {
|
||||||
|
cmd uint32
|
||||||
|
size uint32
|
||||||
|
data [PERMADDR_LEN]byte
|
||||||
|
}
|
||||||
|
|
||||||
type Ethtool struct {
|
type Ethtool struct {
|
||||||
fd int
|
fd int
|
||||||
}
|
}
|
||||||
|
|
||||||
// DriverName returns the driver name of the given interface.
|
// DriverName returns the driver name of the given interface name.
|
||||||
func (e *Ethtool) DriverName(intf string) (string, error) {
|
func (e *Ethtool) DriverName(intf string) (string, error) {
|
||||||
info, err := e.getDriverInfo(intf)
|
info, err := e.getDriverInfo(intf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -108,7 +182,7 @@ func (e *Ethtool) DriverName(intf string) (string, error) {
|
|||||||
return string(bytes.Trim(info.driver[:], "\x00")), nil
|
return string(bytes.Trim(info.driver[:], "\x00")), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// BusInfo returns the bus info of the given interface.
|
// BusInfo returns the bus information of the given interface name.
|
||||||
func (e *Ethtool) BusInfo(intf string) (string, error) {
|
func (e *Ethtool) BusInfo(intf string) (string, error) {
|
||||||
info, err := e.getDriverInfo(intf)
|
info, err := e.getDriverInfo(intf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -117,44 +191,259 @@ func (e *Ethtool) BusInfo(intf string) (string, error) {
|
|||||||
return string(bytes.Trim(info.bus_info[:], "\x00")), nil
|
return string(bytes.Trim(info.bus_info[:], "\x00")), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Ethtool) getDriverInfo(intf string) (ethtoolDrvInfo, error) {
|
// ModuleEeprom returns Eeprom information of the given interface name.
|
||||||
drvinfo := ethtoolDrvInfo{
|
func (e *Ethtool) ModuleEeprom(intf string) ([]byte, error) {
|
||||||
cmd: ETHTOOL_GDRVINFO,
|
eeprom, _, err := e.getModuleEeprom(intf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return eeprom.data[:eeprom.len], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModuleEeprom returns Eeprom information of the given interface name.
|
||||||
|
func (e *Ethtool) ModuleEepromHex(intf string) (string, error) {
|
||||||
|
eeprom, _, err := e.getModuleEeprom(intf)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return hex.EncodeToString(eeprom.data[:eeprom.len]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DriverInfo returns driver information of the given interface name.
|
||||||
|
func (e *Ethtool) DriverInfo(intf string) (ethtoolDrvInfo, error) {
|
||||||
|
drvInfo, err := e.getDriverInfo(intf)
|
||||||
|
if err != nil {
|
||||||
|
return ethtoolDrvInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return drvInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PermAddr returns permanent address of the given interface name.
|
||||||
|
func (e *Ethtool) PermAddr(intf string) (string, error) {
|
||||||
|
permAddr, err := e.getPermAddr(intf)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if permAddr.data[0] == 0 && permAddr.data[1] == 0 &&
|
||||||
|
permAddr.data[2] == 0 && permAddr.data[3] == 0 &&
|
||||||
|
permAddr.data[4] == 0 && permAddr.data[5] == 0 {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%x:%x:%x:%x:%x:%x",
|
||||||
|
permAddr.data[0:1],
|
||||||
|
permAddr.data[1:2],
|
||||||
|
permAddr.data[2:3],
|
||||||
|
permAddr.data[3:4],
|
||||||
|
permAddr.data[4:5],
|
||||||
|
permAddr.data[5:6],
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Ethtool) ioctl(intf string, data uintptr) error {
|
||||||
var name [IFNAMSIZ]byte
|
var name [IFNAMSIZ]byte
|
||||||
copy(name[:], []byte(intf))
|
copy(name[:], []byte(intf))
|
||||||
|
|
||||||
ifr := ifreq{
|
ifr := ifreq{
|
||||||
ifr_name: name,
|
ifr_name: name,
|
||||||
ifr_data: uintptr(unsafe.Pointer(&drvinfo)),
|
ifr_data: data,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr)))
|
_, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr)))
|
||||||
if ep != 0 {
|
if ep != 0 {
|
||||||
return ethtoolDrvInfo{}, syscall.Errno(ep)
|
return syscall.Errno(ep)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Ethtool) getDriverInfo(intf string) (ethtoolDrvInfo, error) {
|
||||||
|
drvinfo := ethtoolDrvInfo{
|
||||||
|
cmd: ETHTOOL_GDRVINFO,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := e.ioctl(intf, uintptr(unsafe.Pointer(&drvinfo))); err != nil {
|
||||||
|
return ethtoolDrvInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return drvinfo, nil
|
return drvinfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Ethtool) getPermAddr(intf string) (ethtoolPermAddr, error) {
|
||||||
|
permAddr := ethtoolPermAddr{
|
||||||
|
cmd: ETHTOOL_GPERMADDR,
|
||||||
|
size: PERMADDR_LEN,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := e.ioctl(intf, uintptr(unsafe.Pointer(&permAddr))); err != nil {
|
||||||
|
return ethtoolPermAddr{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return permAddr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Ethtool) getModuleEeprom(intf string) (ethtoolEeprom, ethtoolModInfo, error) {
|
||||||
|
modInfo := ethtoolModInfo{
|
||||||
|
cmd: ETHTOOL_GMODULEINFO,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := e.ioctl(intf, uintptr(unsafe.Pointer(&modInfo))); err != nil {
|
||||||
|
return ethtoolEeprom{}, ethtoolModInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
eeprom := ethtoolEeprom{
|
||||||
|
cmd: ETHTOOL_GMODULEEEPROM,
|
||||||
|
len: modInfo.eeprom_len,
|
||||||
|
offset: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
if modInfo.eeprom_len > EEPROM_LEN {
|
||||||
|
return ethtoolEeprom{}, ethtoolModInfo{}, fmt.Errorf("eeprom size: %d is larger than buffer size: %d", modInfo.eeprom_len, EEPROM_LEN)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := e.ioctl(intf, uintptr(unsafe.Pointer(&eeprom))); err != nil {
|
||||||
|
return ethtoolEeprom{}, ethtoolModInfo{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return eeprom, modInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isFeatureBitSet(blocks [MAX_FEATURE_BLOCKS]ethtoolGetFeaturesBlock, index uint) bool {
|
||||||
|
return (blocks)[index/32].active&(1<<(index%32)) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func setFeatureBit(blocks *[MAX_FEATURE_BLOCKS]ethtoolSetFeaturesBlock, index uint, value bool) {
|
||||||
|
blockIndex, bitIndex := index/32, index%32
|
||||||
|
|
||||||
|
blocks[blockIndex].valid |= 1 << bitIndex
|
||||||
|
|
||||||
|
if value {
|
||||||
|
blocks[blockIndex].requested |= 1 << bitIndex
|
||||||
|
} else {
|
||||||
|
blocks[blockIndex].requested &= ^(1 << bitIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FeatureNames shows supported features by their name.
|
||||||
|
func (e *Ethtool) FeatureNames(intf string) (map[string]uint, error) {
|
||||||
|
ssetInfo := ethtoolSsetInfo{
|
||||||
|
cmd: ETHTOOL_GSSET_INFO,
|
||||||
|
sset_mask: 1 << ETH_SS_FEATURES,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := e.ioctl(intf, uintptr(unsafe.Pointer(&ssetInfo))); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
length := uint32(ssetInfo.data)
|
||||||
|
if length == 0 {
|
||||||
|
return map[string]uint{}, nil
|
||||||
|
} else if length > MAX_GSTRINGS {
|
||||||
|
return nil, fmt.Errorf("ethtool currently doesn't support more than %d entries, received %d", MAX_GSTRINGS, length)
|
||||||
|
}
|
||||||
|
|
||||||
|
gstrings := ethtoolGStrings{
|
||||||
|
cmd: ETHTOOL_GSTRINGS,
|
||||||
|
string_set: ETH_SS_FEATURES,
|
||||||
|
len: length,
|
||||||
|
data: [MAX_GSTRINGS * ETH_GSTRING_LEN]byte{},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := e.ioctl(intf, uintptr(unsafe.Pointer(&gstrings))); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = make(map[string]uint)
|
||||||
|
for i := 0; i != int(length); i++ {
|
||||||
|
b := gstrings.data[i*ETH_GSTRING_LEN : i*ETH_GSTRING_LEN+ETH_GSTRING_LEN]
|
||||||
|
key := string(bytes.Trim(b, "\x00"))
|
||||||
|
if key != "" {
|
||||||
|
result[key] = uint(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Features retrieves features of the given interface name.
|
||||||
|
func (e *Ethtool) Features(intf string) (map[string]bool, error) {
|
||||||
|
names, err := e.FeatureNames(intf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
length := uint32(len(names))
|
||||||
|
if length == 0 {
|
||||||
|
return map[string]bool{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
features := ethtoolGfeatures{
|
||||||
|
cmd: ETHTOOL_GFEATURES,
|
||||||
|
size: (length + 32 - 1) / 32,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := e.ioctl(intf, uintptr(unsafe.Pointer(&features))); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = make(map[string]bool, length)
|
||||||
|
for key, index := range names {
|
||||||
|
result[key] = isFeatureBitSet(features.blocks, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change requests a change in the given device's features.
|
||||||
|
func (e *Ethtool) Change(intf string, config map[string]bool) error {
|
||||||
|
names, err := e.FeatureNames(intf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
length := uint32(len(names))
|
||||||
|
|
||||||
|
features := ethtoolSfeatures{
|
||||||
|
cmd: ETHTOOL_SFEATURES,
|
||||||
|
size: (length + 32 - 1) / 32,
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range config {
|
||||||
|
if index, ok := names[key]; ok {
|
||||||
|
setFeatureBit(&features.blocks, index, value)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("unsupported feature %q", key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.ioctl(intf, uintptr(unsafe.Pointer(&features)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get state of a link.
|
||||||
|
func (e *Ethtool) LinkState(intf string) (uint32, error) {
|
||||||
|
x := ethtoolLink{
|
||||||
|
cmd: ETHTOOL_GLINK,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := e.ioctl(intf, uintptr(unsafe.Pointer(&x))); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return x.data, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Stats retrieves stats of the given interface name.
|
// Stats retrieves stats of the given interface name.
|
||||||
func (e *Ethtool) Stats(intf string) (map[string]uint64, error) {
|
func (e *Ethtool) Stats(intf string) (map[string]uint64, error) {
|
||||||
drvinfo := ethtoolDrvInfo{
|
drvinfo := ethtoolDrvInfo{
|
||||||
cmd: ETHTOOL_GDRVINFO,
|
cmd: ETHTOOL_GDRVINFO,
|
||||||
}
|
}
|
||||||
|
|
||||||
var name [IFNAMSIZ]byte
|
if err := e.ioctl(intf, uintptr(unsafe.Pointer(&drvinfo))); err != nil {
|
||||||
copy(name[:], []byte(intf))
|
return nil, err
|
||||||
|
|
||||||
ifr := ifreq{
|
|
||||||
ifr_name: name,
|
|
||||||
ifr_data: uintptr(unsafe.Pointer(&drvinfo)),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr)))
|
|
||||||
if ep != 0 {
|
|
||||||
return nil, syscall.Errno(ep)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if drvinfo.n_stats*ETH_GSTRING_LEN > MAX_GSTRINGS*ETH_GSTRING_LEN {
|
if drvinfo.n_stats*ETH_GSTRING_LEN > MAX_GSTRINGS*ETH_GSTRING_LEN {
|
||||||
@ -167,11 +456,9 @@ func (e *Ethtool) Stats(intf string) (map[string]uint64, error) {
|
|||||||
len: drvinfo.n_stats,
|
len: drvinfo.n_stats,
|
||||||
data: [MAX_GSTRINGS * ETH_GSTRING_LEN]byte{},
|
data: [MAX_GSTRINGS * ETH_GSTRING_LEN]byte{},
|
||||||
}
|
}
|
||||||
ifr.ifr_data = uintptr(unsafe.Pointer(&gstrings))
|
|
||||||
|
|
||||||
_, _, ep = syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr)))
|
if err := e.ioctl(intf, uintptr(unsafe.Pointer(&gstrings))); err != nil {
|
||||||
if ep != 0 {
|
return nil, err
|
||||||
return nil, syscall.Errno(ep)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stats := ethtoolStats{
|
stats := ethtoolStats{
|
||||||
@ -180,31 +467,32 @@ func (e *Ethtool) Stats(intf string) (map[string]uint64, error) {
|
|||||||
data: [MAX_GSTRINGS]uint64{},
|
data: [MAX_GSTRINGS]uint64{},
|
||||||
}
|
}
|
||||||
|
|
||||||
ifr.ifr_data = uintptr(unsafe.Pointer(&stats))
|
if err := e.ioctl(intf, uintptr(unsafe.Pointer(&stats))); err != nil {
|
||||||
|
return nil, err
|
||||||
_, _, ep = syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr)))
|
|
||||||
if ep != 0 {
|
|
||||||
return nil, syscall.Errno(ep)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = make(map[string]uint64)
|
var result = make(map[string]uint64)
|
||||||
for i := 0; i != int(drvinfo.n_stats); i++ {
|
for i := 0; i != int(drvinfo.n_stats); i++ {
|
||||||
b := gstrings.data[i*ETH_GSTRING_LEN : i*ETH_GSTRING_LEN+ETH_GSTRING_LEN]
|
b := gstrings.data[i*ETH_GSTRING_LEN : i*ETH_GSTRING_LEN+ETH_GSTRING_LEN]
|
||||||
key := string(bytes.Trim(b, "\x00"))
|
key := string(b[:strings.Index(string(b), "\x00")])
|
||||||
|
if len(key) != 0 {
|
||||||
result[key] = stats.data[i]
|
result[key] = stats.data[i]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close closes the ethool handler
|
||||||
func (e *Ethtool) Close() {
|
func (e *Ethtool) Close() {
|
||||||
syscall.Close(e.fd)
|
syscall.Close(e.fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewEthtool returns a new ethtool handler
|
||||||
func NewEthtool() (*Ethtool, error) {
|
func NewEthtool() (*Ethtool, error) {
|
||||||
fd, _, err := syscall.RawSyscall(syscall.SYS_SOCKET, syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_IP)
|
fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_IP)
|
||||||
if err != 0 {
|
if err != nil {
|
||||||
return nil, syscall.Errno(err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Ethtool{
|
return &Ethtool{
|
||||||
@ -212,6 +500,7 @@ func NewEthtool() (*Ethtool, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BusInfo returns bus information of the given interface name.
|
||||||
func BusInfo(intf string) (string, error) {
|
func BusInfo(intf string) (string, error) {
|
||||||
e, err := NewEthtool()
|
e, err := NewEthtool()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -221,6 +510,7 @@ func BusInfo(intf string) (string, error) {
|
|||||||
return e.BusInfo(intf)
|
return e.BusInfo(intf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DriverName returns the driver name of the given interface name.
|
||||||
func DriverName(intf string) (string, error) {
|
func DriverName(intf string) (string, error) {
|
||||||
e, err := NewEthtool()
|
e, err := NewEthtool()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -230,6 +520,7 @@ func DriverName(intf string) (string, error) {
|
|||||||
return e.DriverName(intf)
|
return e.DriverName(intf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stats retrieves stats of the given interface name.
|
||||||
func Stats(intf string) (map[string]uint64, error) {
|
func Stats(intf string) (map[string]uint64, error) {
|
||||||
e, err := NewEthtool()
|
e, err := NewEthtool()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -238,3 +529,13 @@ func Stats(intf string) (map[string]uint64, error) {
|
|||||||
defer e.Close()
|
defer e.Close()
|
||||||
return e.Stats(intf)
|
return e.Stats(intf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PermAddr returns permanent address of the given interface name.
|
||||||
|
func PermAddr(intf string) (string, error) {
|
||||||
|
e, err := NewEthtool()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer e.Close()
|
||||||
|
return e.PermAddr(intf)
|
||||||
|
}
|
||||||
|
7
vendor/github.com/safchain/ethtool/ethtool_cmd.go
generated
vendored
7
vendor/github.com/safchain/ethtool/ethtool_cmd.go
generated
vendored
@ -26,6 +26,7 @@
|
|||||||
package ethtool
|
package ethtool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@ -128,6 +129,9 @@ func (e *Ethtool) CmdGet(ecmd *EthtoolCmd, intf string) (uint32, error) {
|
|||||||
|
|
||||||
var speedval uint32 = (uint32(ecmd.Speed_hi) << 16) |
|
var speedval uint32 = (uint32(ecmd.Speed_hi) << 16) |
|
||||||
(uint32(ecmd.Speed) & 0xffff)
|
(uint32(ecmd.Speed) & 0xffff)
|
||||||
|
if speedval == math.MaxUint16 {
|
||||||
|
speedval = math.MaxUint32
|
||||||
|
}
|
||||||
|
|
||||||
return speedval, nil
|
return speedval, nil
|
||||||
}
|
}
|
||||||
@ -153,6 +157,9 @@ func (e *Ethtool) CmdSet(ecmd *EthtoolCmd, intf string) (uint32, error) {
|
|||||||
|
|
||||||
var speedval uint32 = (uint32(ecmd.Speed_hi) << 16) |
|
var speedval uint32 = (uint32(ecmd.Speed_hi) << 16) |
|
||||||
(uint32(ecmd.Speed) & 0xffff)
|
(uint32(ecmd.Speed) & 0xffff)
|
||||||
|
if speedval == math.MaxUint16 {
|
||||||
|
speedval = math.MaxUint32
|
||||||
|
}
|
||||||
|
|
||||||
return speedval, nil
|
return speedval, nil
|
||||||
}
|
}
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -84,7 +84,7 @@ github.com/onsi/gomega/matchers/support/goraph/bipartitegraph
|
|||||||
github.com/onsi/gomega/matchers/support/goraph/edge
|
github.com/onsi/gomega/matchers/support/goraph/edge
|
||||||
github.com/onsi/gomega/matchers/support/goraph/node
|
github.com/onsi/gomega/matchers/support/goraph/node
|
||||||
github.com/onsi/gomega/matchers/support/goraph/util
|
github.com/onsi/gomega/matchers/support/goraph/util
|
||||||
# github.com/safchain/ethtool v0.0.0-20170622225139-7ff1ba29eca2
|
# github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8
|
||||||
github.com/safchain/ethtool
|
github.com/safchain/ethtool
|
||||||
# github.com/sirupsen/logrus v1.0.6
|
# github.com/sirupsen/logrus v1.0.6
|
||||||
github.com/sirupsen/logrus
|
github.com/sirupsen/logrus
|
||||||
|
Loading…
x
Reference in New Issue
Block a user