vendor: add safchain/ethtool
This commit is contained in:
parent
dd8ff8a5cf
commit
8da8088d43
4
Godeps/Godeps.json
generated
4
Godeps/Godeps.json
generated
@ -226,6 +226,10 @@
|
||||
"Comment": "v1.0-71-g2152b45",
|
||||
"Rev": "2152b45fa28a361beba9aab0885972323a444e28"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/safchain/ethtool",
|
||||
"Rev": "7ff1ba29eca231991280817541cb3903f6be15d1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vishvananda/netlink",
|
||||
"Rev": "6e453822d85ef5721799774b654d4d02fed62afb"
|
||||
|
240
vendor/github.com/safchain/ethtool/ethtool.go
generated
vendored
Normal file
240
vendor/github.com/safchain/ethtool/ethtool.go
generated
vendored
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
// Package ethtool aims to provide a library giving a simple access to the
|
||||
// Linux SIOCETHTOOL ioctl operations. It can be used to retrieve informations
|
||||
// from a network device like statistics, driver related informations or
|
||||
// even the peer of a VETH interface.
|
||||
package ethtool
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Maximum size of an interface name
|
||||
const (
|
||||
IFNAMSIZ = 16
|
||||
)
|
||||
|
||||
// ioctl ethtool request
|
||||
const (
|
||||
SIOCETHTOOL = 0x8946
|
||||
)
|
||||
|
||||
// ethtool stats related constants.
|
||||
const (
|
||||
ETH_GSTRING_LEN = 32
|
||||
ETH_SS_STATS = 1
|
||||
ETHTOOL_GDRVINFO = 0x00000003
|
||||
ETHTOOL_GSTRINGS = 0x0000001b
|
||||
ETHTOOL_GSTATS = 0x0000001d
|
||||
// other CMDs from ethtool-copy.h of ethtool-3.5 package
|
||||
ETHTOOL_GSET = 0x00000001 /* Get settings. */
|
||||
ETHTOOL_SSET = 0x00000002 /* Set settings. */
|
||||
ETHTOOL_GMSGLVL = 0x00000007 /* Get driver message level */
|
||||
ETHTOOL_SMSGLVL = 0x00000008 /* Set driver msg level. */
|
||||
)
|
||||
|
||||
// MAX_GSTRINGS maximum number of stats entries that ethtool can
|
||||
// retrieve currently.
|
||||
const (
|
||||
MAX_GSTRINGS = 1000
|
||||
)
|
||||
|
||||
type ifreq struct {
|
||||
ifr_name [IFNAMSIZ]byte
|
||||
ifr_data uintptr
|
||||
}
|
||||
|
||||
type ethtoolDrvInfo struct {
|
||||
cmd uint32
|
||||
driver [32]byte
|
||||
version [32]byte
|
||||
fw_version [32]byte
|
||||
bus_info [32]byte
|
||||
erom_version [32]byte
|
||||
reserved2 [12]byte
|
||||
n_priv_flags uint32
|
||||
n_stats uint32
|
||||
testinfo_len uint32
|
||||
eedump_len uint32
|
||||
regdump_len uint32
|
||||
}
|
||||
|
||||
type ethtoolGStrings struct {
|
||||
cmd uint32
|
||||
string_set uint32
|
||||
len uint32
|
||||
data [MAX_GSTRINGS * ETH_GSTRING_LEN]byte
|
||||
}
|
||||
|
||||
type ethtoolStats struct {
|
||||
cmd uint32
|
||||
n_stats uint32
|
||||
data [MAX_GSTRINGS]uint64
|
||||
}
|
||||
|
||||
type Ethtool struct {
|
||||
fd int
|
||||
}
|
||||
|
||||
// DriverName returns the driver name of the given interface.
|
||||
func (e *Ethtool) DriverName(intf string) (string, error) {
|
||||
info, err := e.getDriverInfo(intf)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes.Trim(info.driver[:], "\x00")), nil
|
||||
}
|
||||
|
||||
// BusInfo returns the bus info of the given interface.
|
||||
func (e *Ethtool) BusInfo(intf string) (string, error) {
|
||||
info, err := e.getDriverInfo(intf)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes.Trim(info.bus_info[:], "\x00")), nil
|
||||
}
|
||||
|
||||
func (e *Ethtool) getDriverInfo(intf string) (ethtoolDrvInfo, error) {
|
||||
drvinfo := ethtoolDrvInfo{
|
||||
cmd: ETHTOOL_GDRVINFO,
|
||||
}
|
||||
|
||||
var name [IFNAMSIZ]byte
|
||||
copy(name[:], []byte(intf))
|
||||
|
||||
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 ethtoolDrvInfo{}, syscall.Errno(ep)
|
||||
}
|
||||
|
||||
return drvinfo, nil
|
||||
}
|
||||
|
||||
// Stats retrieves stats of the given interface name.
|
||||
func (e *Ethtool) Stats(intf string) (map[string]uint64, error) {
|
||||
drvinfo := ethtoolDrvInfo{
|
||||
cmd: ETHTOOL_GDRVINFO,
|
||||
}
|
||||
|
||||
var name [IFNAMSIZ]byte
|
||||
copy(name[:], []byte(intf))
|
||||
|
||||
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 {
|
||||
return nil, fmt.Errorf("ethtool currently doesn't support more than %d entries, received %d", MAX_GSTRINGS, drvinfo.n_stats)
|
||||
}
|
||||
|
||||
gstrings := ethtoolGStrings{
|
||||
cmd: ETHTOOL_GSTRINGS,
|
||||
string_set: ETH_SS_STATS,
|
||||
len: drvinfo.n_stats,
|
||||
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 ep != 0 {
|
||||
return nil, syscall.Errno(ep)
|
||||
}
|
||||
|
||||
stats := ethtoolStats{
|
||||
cmd: ETHTOOL_GSTATS,
|
||||
n_stats: drvinfo.n_stats,
|
||||
data: [MAX_GSTRINGS]uint64{},
|
||||
}
|
||||
|
||||
ifr.ifr_data = uintptr(unsafe.Pointer(&stats))
|
||||
|
||||
_, _, 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)
|
||||
for i := 0; i != int(drvinfo.n_stats); i++ {
|
||||
b := gstrings.data[i*ETH_GSTRING_LEN : i*ETH_GSTRING_LEN+ETH_GSTRING_LEN]
|
||||
key := string(bytes.Trim(b, "\x00"))
|
||||
result[key] = stats.data[i]
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (e *Ethtool) Close() {
|
||||
syscall.Close(e.fd)
|
||||
}
|
||||
|
||||
func NewEthtool() (*Ethtool, error) {
|
||||
fd, _, err := syscall.RawSyscall(syscall.SYS_SOCKET, syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_IP)
|
||||
if err != 0 {
|
||||
return nil, syscall.Errno(err)
|
||||
}
|
||||
|
||||
return &Ethtool{
|
||||
fd: int(fd),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func BusInfo(intf string) (string, error) {
|
||||
e, err := NewEthtool()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer e.Close()
|
||||
return e.BusInfo(intf)
|
||||
}
|
||||
|
||||
func DriverName(intf string) (string, error) {
|
||||
e, err := NewEthtool()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer e.Close()
|
||||
return e.DriverName(intf)
|
||||
}
|
||||
|
||||
func Stats(intf string) (map[string]uint64, error) {
|
||||
e, err := NewEthtool()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer e.Close()
|
||||
return e.Stats(intf)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user