From d5b066152b3502c2fb6663e3f9860b867b876acb Mon Sep 17 00:00:00 2001 From: Archana Shinde Date: Mon, 19 Mar 2018 14:30:29 -0700 Subject: [PATCH] vendor: Vendor github.com/safchain/ethtool We were using code copied from github.com/safchain/ethtool. Vendor in upstream package instead to use additional functionality added in. Fixes #71 Signed-off-by: Archana Shinde --- Gopkg.lock | 7 +- Gopkg.toml | 4 + vendor/github.com/safchain/ethtool/LICENSE | 202 +++++++++ vendor/github.com/safchain/ethtool/ethtool.go | 385 ++++++++++++++++++ .../safchain/ethtool/ethtool_cmd.go | 200 +++++++++ .../safchain/ethtool/ethtool_msglvl.go | 113 +++++ virtcontainers/network.go | 2 +- virtcontainers/pkg/ethtool/ethtool.go | 164 -------- virtcontainers/pkg/ethtool/ethtool_test.go | 67 --- 9 files changed, 911 insertions(+), 233 deletions(-) create mode 100644 vendor/github.com/safchain/ethtool/LICENSE create mode 100644 vendor/github.com/safchain/ethtool/ethtool.go create mode 100644 vendor/github.com/safchain/ethtool/ethtool_cmd.go create mode 100644 vendor/github.com/safchain/ethtool/ethtool_msglvl.go delete mode 100644 virtcontainers/pkg/ethtool/ethtool.go delete mode 100644 virtcontainers/pkg/ethtool/ethtool_test.go diff --git a/Gopkg.lock b/Gopkg.lock index b0c8b02d33..308ddac5c7 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -130,6 +130,11 @@ revision = "792786c7400a136282c1664665ae0a8db921c6c2" version = "v1.0.0" +[[projects]] + name = "github.com/safchain/ethtool" + packages = ["."] + revision = "79559b488d8848b53a8e34c330140c3fc37ee246" + [[projects]] name = "github.com/sirupsen/logrus" packages = [ @@ -245,6 +250,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "8dba9fde76331ee3c2baa2a34230f174e3ab122a6b17975c533cdfbf42b49617" + inputs-digest = "a50c12d36c3881a8fdc1c46a9a2ef78edc27ae1a1ec0c448799f37c589209108" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 89c4730fdf..9d2ab2ec7d 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -66,6 +66,10 @@ name = "github.com/containerd/cri-containerd" revision = "3d382e2f5dabe3bae62ceb9ded56bdee847008ee" +[[constraint]] + name = "github.com/safchain/ethtool" + revision = "79559b488d8848b53a8e34c330140c3fc37ee246" + [prune] non-go = true go-tests = true diff --git a/vendor/github.com/safchain/ethtool/LICENSE b/vendor/github.com/safchain/ethtool/LICENSE new file mode 100644 index 0000000000..8f71f43fee --- /dev/null +++ b/vendor/github.com/safchain/ethtool/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed 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. + diff --git a/vendor/github.com/safchain/ethtool/ethtool.go b/vendor/github.com/safchain/ethtool/ethtool.go new file mode 100644 index 0000000000..582d0221df --- /dev/null +++ b/vendor/github.com/safchain/ethtool/ethtool.go @@ -0,0 +1,385 @@ +/* + * + * 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" + "encoding/hex" + "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. */ + ETHTOOL_GMODULEINFO = 0x00000042 /* Get plug-in module information */ + ETHTOOL_GMODULEEEPROM = 0x00000043 /* Get plug-in module eeprom */ + ETHTOOL_GPERMADDR = 0x00000020 +) + +// MAX_GSTRINGS maximum number of stats entries that ethtool can +// retrieve currently. +const ( + MAX_GSTRINGS = 1000 + EEPROM_LEN = 640 + PERMADDR_LEN = 32 +) + +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 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 ethtoolPermAddr struct { + cmd uint32 + size uint32 + data [PERMADDR_LEN]byte +} + +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) ModuleEeprom(intf string) ([]byte, error) { + eeprom, _, err := e.getModuleEeprom(intf) + if err != nil { + return nil, err + } + + return eeprom.data[:eeprom.len], nil +} + +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 +} + +func (e *Ethtool) DriverInfo(intf string) (ethtoolDrvInfo, error) { + drvInfo, err := e.getDriverInfo(intf) + if err != nil { + return ethtoolDrvInfo{}, err + } + + return drvInfo, nil +} + +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) 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 +} + +func (e *Ethtool) getPermAddr(intf string) (ethtoolPermAddr, error) { + permAddr := ethtoolPermAddr{ + cmd: ETHTOOL_GPERMADDR, + size: PERMADDR_LEN, + } + + var name [IFNAMSIZ]byte + copy(name[:], []byte(intf)) + + ifr := ifreq{ + ifr_name: name, + ifr_data: uintptr(unsafe.Pointer(&permAddr)), + } + + _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr))) + if ep != 0 { + return ethtoolPermAddr{}, syscall.Errno(ep) + } + + return permAddr, nil +} + +func (e *Ethtool) getModuleEeprom(intf string) (ethtoolEeprom, ethtoolModInfo, error) { + modInfo := ethtoolModInfo{ + cmd: ETHTOOL_GMODULEINFO, + } + + var name [IFNAMSIZ]byte + copy(name[:], []byte(intf)) + + ifr := ifreq{ + ifr_name: name, + ifr_data: uintptr(unsafe.Pointer(&modInfo)), + } + + _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr))) + if ep != 0 { + return ethtoolEeprom{}, ethtoolModInfo{}, syscall.Errno(ep) + } + + 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) + } + + ifr.ifr_data = uintptr(unsafe.Pointer(&eeprom)) + + _, _, ep = syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr))) + if ep != 0 { + return ethtoolEeprom{}, ethtoolModInfo{}, syscall.Errno(ep) + } + + return eeprom, modInfo, 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.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_IP) + if err != nil { + return nil, 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) +} + +func PermAddr(intf string) (string, error) { + e, err := NewEthtool() + if err != nil { + return "", err + } + defer e.Close() + return e.PermAddr(intf) +} diff --git a/vendor/github.com/safchain/ethtool/ethtool_cmd.go b/vendor/github.com/safchain/ethtool/ethtool_cmd.go new file mode 100644 index 0000000000..f5b34eeb07 --- /dev/null +++ b/vendor/github.com/safchain/ethtool/ethtool_cmd.go @@ -0,0 +1,200 @@ +/* + * + * 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 ( + "reflect" + "syscall" + "unsafe" +) + +type EthtoolCmd struct { /* ethtool.c: struct ethtool_cmd */ + Cmd uint32 + Supported uint32 + Advertising uint32 + Speed uint16 + Duplex uint8 + Port uint8 + Phy_address uint8 + Transceiver uint8 + Autoneg uint8 + Mdio_support uint8 + Maxtxpkt uint32 + Maxrxpkt uint32 + Speed_hi uint16 + Eth_tp_mdix uint8 + Reserved2 uint8 + Lp_advertising uint32 + Reserved [2]uint32 +} + +// CmdGet returns the interface settings in the receiver struct +// and returns speed +func (ecmd *EthtoolCmd) CmdGet(intf string) (uint32, error) { + e, err := NewEthtool() + if err != nil { + return 0, err + } + defer e.Close() + return e.CmdGet(ecmd, intf) +} + +// CmdSet sets and returns the settings in the receiver struct +// and returns speed +func (ecmd *EthtoolCmd) CmdSet(intf string) (uint32, error) { + e, err := NewEthtool() + if err != nil { + return 0, err + } + defer e.Close() + return e.CmdSet(ecmd, intf) +} + +func (f *EthtoolCmd) reflect(retv *map[string]uint64) { + val := reflect.ValueOf(f).Elem() + + for i := 0; i < val.NumField(); i++ { + valueField := val.Field(i) + typeField := val.Type().Field(i) + + t := valueField.Interface() + //tt := reflect.TypeOf(t) + //fmt.Printf(" t %T %v tt %T %v\n", t, t, tt, tt) + switch t.(type) { + case uint32: + //fmt.Printf(" t is uint32\n") + (*retv)[typeField.Name] = uint64(t.(uint32)) + case uint16: + (*retv)[typeField.Name] = uint64(t.(uint16)) + case uint8: + (*retv)[typeField.Name] = uint64(t.(uint8)) + case int32: + (*retv)[typeField.Name] = uint64(t.(int32)) + case int16: + (*retv)[typeField.Name] = uint64(t.(int16)) + case int8: + (*retv)[typeField.Name] = uint64(t.(int8)) + default: + (*retv)[typeField.Name+"_unknown_type"] = 0 + } + + //tag := typeField.Tag + //fmt.Printf("Field Name: %s,\t Field Value: %v,\t Tag Value: %s\n", + // typeField.Name, valueField.Interface(), tag.Get("tag_name")) + } +} + +// CmdGet returns the interface settings in the receiver struct +// and returns speed +func (e *Ethtool) CmdGet(ecmd *EthtoolCmd, intf string) (uint32, error) { + ecmd.Cmd = ETHTOOL_GSET + + var name [IFNAMSIZ]byte + copy(name[:], []byte(intf)) + + ifr := ifreq{ + ifr_name: name, + ifr_data: uintptr(unsafe.Pointer(ecmd)), + } + + _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), + SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr))) + if ep != 0 { + return 0, syscall.Errno(ep) + } + + var speedval uint32 = (uint32(ecmd.Speed_hi) << 16) | + (uint32(ecmd.Speed) & 0xffff) + + return speedval, nil +} + +// CmdSet sets and returns the settings in the receiver struct +// and returns speed +func (e *Ethtool) CmdSet(ecmd *EthtoolCmd, intf string) (uint32, error) { + ecmd.Cmd = ETHTOOL_SSET + + var name [IFNAMSIZ]byte + copy(name[:], []byte(intf)) + + ifr := ifreq{ + ifr_name: name, + ifr_data: uintptr(unsafe.Pointer(ecmd)), + } + + _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), + SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr))) + if ep != 0 { + return 0, syscall.Errno(ep) + } + + var speedval uint32 = (uint32(ecmd.Speed_hi) << 16) | + (uint32(ecmd.Speed) & 0xffff) + + return speedval, nil +} + +// CmdGetMapped returns the interface settings in a map +func (e *Ethtool) CmdGetMapped(intf string) (map[string]uint64, error) { + ecmd := EthtoolCmd{ + Cmd: ETHTOOL_GSET, + } + + var name [IFNAMSIZ]byte + copy(name[:], []byte(intf)) + + ifr := ifreq{ + ifr_name: name, + ifr_data: uintptr(unsafe.Pointer(&ecmd)), + } + + _, _, 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) + + // ref https://gist.github.com/drewolson/4771479 + // Golang Reflection Example + ecmd.reflect(&result) + + var speedval uint32 = (uint32(ecmd.Speed_hi) << 16) | + (uint32(ecmd.Speed) & 0xffff) + result["speed"] = uint64(speedval) + + return result, nil +} + +func CmdGetMapped(intf string) (map[string]uint64, error) { + e, err := NewEthtool() + if err != nil { + return nil, err + } + defer e.Close() + return e.CmdGetMapped(intf) +} diff --git a/vendor/github.com/safchain/ethtool/ethtool_msglvl.go b/vendor/github.com/safchain/ethtool/ethtool_msglvl.go new file mode 100644 index 0000000000..91836f0190 --- /dev/null +++ b/vendor/github.com/safchain/ethtool/ethtool_msglvl.go @@ -0,0 +1,113 @@ +/* + * + * 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 ( + "syscall" + "unsafe" +) + +type ethtoolValue struct { /* ethtool.c: struct ethtool_value */ + cmd uint32 + data uint32 +} + +// MsglvlGet returns the msglvl of the given interface. +func (e *Ethtool) MsglvlGet(intf string) (uint32, error) { + edata := ethtoolValue{ + cmd: ETHTOOL_GMSGLVL, + } + + var name [IFNAMSIZ]byte + copy(name[:], []byte(intf)) + + ifr := ifreq{ + ifr_name: name, + ifr_data: uintptr(unsafe.Pointer(&edata)), + } + + _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), + SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr))) + if ep != 0 { + return 0, syscall.Errno(ep) + } + + return edata.data, nil +} + +// MsglvlSet returns the read-msglvl, post-set-msglvl of the given interface. +func (e *Ethtool) MsglvlSet(intf string, valset uint32) (uint32, uint32, error) { + edata := ethtoolValue{ + cmd: ETHTOOL_GMSGLVL, + } + + var name [IFNAMSIZ]byte + copy(name[:], []byte(intf)) + + ifr := ifreq{ + ifr_name: name, + ifr_data: uintptr(unsafe.Pointer(&edata)), + } + + _, _, ep := syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), + SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr))) + if ep != 0 { + return 0, 0, syscall.Errno(ep) + } + + readval := edata.data + + edata.cmd = ETHTOOL_SMSGLVL + edata.data = valset + + _, _, ep = syscall.Syscall(syscall.SYS_IOCTL, uintptr(e.fd), + SIOCETHTOOL, uintptr(unsafe.Pointer(&ifr))) + if ep != 0 { + return 0, 0, syscall.Errno(ep) + } + + return readval, edata.data, nil +} + +// MsglvlGet returns the msglvl of the given interface. +func MsglvlGet(intf string) (uint32, error) { + e, err := NewEthtool() + if err != nil { + return 0, err + } + defer e.Close() + return e.MsglvlGet(intf) +} + +// MsglvlSet returns the read-msglvl, post-set-msglvl of the given interface. +func MsglvlSet(intf string, valset uint32) (uint32, uint32, error) { + e, err := NewEthtool() + if err != nil { + return 0, 0, err + } + defer e.Close() + return e.MsglvlSet(intf, valset) +} diff --git a/virtcontainers/network.go b/virtcontainers/network.go index 42a8a6ffb9..491dea60bd 100644 --- a/virtcontainers/network.go +++ b/virtcontainers/network.go @@ -30,8 +30,8 @@ import ( "time" "github.com/containernetworking/plugins/pkg/ns" - "github.com/kata-containers/runtime/virtcontainers/pkg/ethtool" "github.com/kata-containers/runtime/virtcontainers/pkg/uuid" + "github.com/safchain/ethtool" "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" "github.com/vishvananda/netns" diff --git a/virtcontainers/pkg/ethtool/ethtool.go b/virtcontainers/pkg/ethtool/ethtool.go deleted file mode 100644 index 7cb39401e6..0000000000 --- a/virtcontainers/pkg/ethtool/ethtool.go +++ /dev/null @@ -1,164 +0,0 @@ -/* - * - * 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 - -import ( - "bytes" - "syscall" - "unsafe" -) - -// Maximum size of an interface name -const ( - IFNAMSIZ = 16 -) - -// ioctl ethtool request -const ( - SIOCETHTOOL = 0x8946 -) - -// ethtool stats related constants. -const ( - ethGstringLen = 32 - ethtoolGDrvInfo = 0x00000003 -) - -// maxGtrings maximum number of stats entries that ethtool can -// retrieve currently. -const ( - maxGstrings = 1000 -) - -type ifreq struct { - ifrName [IFNAMSIZ]byte - ifrData uintptr -} - -type ethtoolDrvInfo struct { - cmd uint32 - driver [32]byte - version [32]byte - fwVersion [32]byte - busInfo [32]byte - eromVersion [32]byte - reserved2 [12]byte - nPrivFlags uint32 - nStats uint32 - testinfoLen uint32 - eedumpLen uint32 - regdumpLen uint32 -} - -type ethtoolGStrings struct { - cmd uint32 - stringSet uint32 - len uint32 - data [maxGstrings * ethGstringLen]byte -} - -type ethtoolStats struct { - cmd uint32 - nStats uint32 - data [maxGstrings]uint64 -} - -// Ethtool file descriptor. -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.busInfo[:], "\x00")), nil -} - -func (e *Ethtool) getDriverInfo(intf string) (ethtoolDrvInfo, error) { - drvinfo := ethtoolDrvInfo{ - cmd: ethtoolGDrvInfo, - } - - var name [IFNAMSIZ]byte - copy(name[:], []byte(intf)) - - ifr := ifreq{ - ifrName: name, - ifrData: 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 -} - -// Close closes the ethtool file descriptor. -func (e *Ethtool) Close() { - syscall.Close(e.fd) -} - -// NewEthtool opens a ethtool socket. -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 -} - -// BusInfo returns the bus information of the network device. -func BusInfo(intf string) (string, error) { - e, err := NewEthtool() - if err != nil { - return "", err - } - defer e.Close() - return e.BusInfo(intf) -} - -// DriverName returns the driver name of the network interface. -func DriverName(intf string) (string, error) { - e, err := NewEthtool() - if err != nil { - return "", err - } - defer e.Close() - return e.DriverName(intf) -} diff --git a/virtcontainers/pkg/ethtool/ethtool_test.go b/virtcontainers/pkg/ethtool/ethtool_test.go deleted file mode 100644 index 0fc37ed8af..0000000000 --- a/virtcontainers/pkg/ethtool/ethtool_test.go +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * 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 - -import ( - "net" - "testing" -) - -func TestDriverName(t *testing.T) { - intfs, err := net.Interfaces() - if err != nil { - t.Fatal(err) - } - - // we expected to have at least one success - success := false - for _, intf := range intfs { - _, err := DriverName(intf.Name) - if err == nil { - success = true - } - } - - if !success { - t.Fatal("Unable to retrieve driver from any interface of this system.") - } -} - -func TestBusInfo(t *testing.T) { - intfs, err := net.Interfaces() - if err != nil { - t.Fatal(err) - } - - // we expected to have at least one success - success := false - for _, intf := range intfs { - _, err := BusInfo(intf.Name) - if err == nil { - success = true - } - } - - if !success { - t.Fatal("Unable to retrieve bus info from any interface of this system.") - } -}