Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkg: net: report backing device address #221

Merged
merged 1 commit into from
Feb 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pkg/net/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ type NIC struct {
MacAddress string `json:"mac_address"`
IsVirtual bool `json:"is_virtual"`
Capabilities []*NICCapability `json:"capabilities"`
// TODO(jaypipes): Add PCI field for accessing PCI device information
// PCI *PCIDevice `json:"pci"`
PCIAddress *string `json:"pci_address,omitempty"`
// TODO(fromani): add other hw addresses (USB) when we support them
}

func (n *NIC) String() string {
Expand Down
54 changes: 54 additions & 0 deletions pkg/net/net_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ func nics(ctx *context.Context) []*NIC {
} else {
nic.Capabilities = []*NICCapability{}
}

nic.PCIAddress = netDevicePCIAddress(paths.SysClassNet, filename)

nics = append(nics, nic)
}
return nics
Expand Down Expand Up @@ -162,3 +165,54 @@ func netParseEthtoolFeature(line string) *NICCapability {
CanEnable: !fixed,
}
}

func netDevicePCIAddress(netDevDir, netDevName string) *string {
// what we do here is not that hard in the end: we need to navigate the sysfs
// up to the directory belonging to the device backing the network interface.
// we can make few relatively safe assumptions, but the safest way is follow
// the right links. And so we go.
// First of all, knowing the network device name we need to resolve the backing
// device path to its full sysfs path.
// say we start with netDevDir="/sys/class/net" and netDevName="enp0s31f6"
netPath := filepath.Join(netDevDir, netDevName)
dest, err := os.Readlink(netPath)
if err != nil {
// bail out with empty value
return nil
}
// now we have something like dest="../../devices/pci0000:00/0000:00:1f.6/net/enp0s31f6"
// remember the path is relative to netDevDir="/sys/class/net"
ffromani marked this conversation as resolved.
Show resolved Hide resolved

netDev := filepath.Clean(filepath.Join(netDevDir, dest))
// so we clean "/sys/class/net/../../devices/pci0000:00/0000:00:1f.6/net/enp0s31f6"
// leading to "/sys/devices/pci0000:00/0000:00:1f.6/net/enp0s31f6"
// still not there. We need to access the data of the pci device. So we jump into the path
// linked to the "device" pseudofile
dest, err = os.Readlink(filepath.Join(netDev, "device"))
if err != nil {
// bail out with empty value
return nil
}
// we expect something like="../../../0000:00:1f.6"

devPath := filepath.Clean(filepath.Join(netDev, dest))
// so we clean "/sys/devices/pci0000:00/0000:00:1f.6/net/enp0s31f6/../../../0000:00:1f.6"
// leading to "/sys/devices/pci0000:00/0000:00:1f.6/"
// finally here!

// to which bus is this device connected to?
dest, err = os.Readlink(filepath.Join(devPath, "subsystem"))
if err != nil {
// bail out with empty value
return nil
}
// ok, this is hacky, but since we need the last *two* path components and we know we
// are running on linux...
if !strings.HasSuffix(dest, "/bus/pci") {
// unsupported and unexpected bus!
return nil
}

pciAddr := filepath.Base(devPath)
return &pciAddr
}