diff --git a/sysfs/net_class.go b/sysfs/net_class.go index 0c8cb2845..e1b1811de 100644 --- a/sysfs/net_class.go +++ b/sysfs/net_class.go @@ -117,6 +117,77 @@ func (fs FS) NetClass() (NetClass, error) { return netClass, nil } +// ParseNetClassAttribute parses a given file in /sys/class/net/ +// and sets the value in a given NetClassIface object if the value was readable. +// It returns an error if the file cannot be read. +func ParseNetClassAttribute(devicePath, attrName string, interfaceClass *NetClassIface) error { + attrPath := filepath.Join(devicePath, attrName) + value, err := util.SysReadFile(attrPath) + if err != nil { + return fmt.Errorf("failed to read file %q: %w", attrPath, err) + } + + vp := util.NewValueParser(value) + switch attrName { + case "addr_assign_type": + interfaceClass.AddrAssignType = vp.PInt64() + case "addr_len": + interfaceClass.AddrLen = vp.PInt64() + case "address": + interfaceClass.Address = value + case "broadcast": + interfaceClass.Broadcast = value + case "carrier": + interfaceClass.Carrier = vp.PInt64() + case "carrier_changes": + interfaceClass.CarrierChanges = vp.PInt64() + case "carrier_up_count": + interfaceClass.CarrierUpCount = vp.PInt64() + case "carrier_down_count": + interfaceClass.CarrierDownCount = vp.PInt64() + case "dev_id": + interfaceClass.DevID = vp.PInt64() + case "dormant": + interfaceClass.Dormant = vp.PInt64() + case "duplex": + interfaceClass.Duplex = value + case "flags": + interfaceClass.Flags = vp.PInt64() + case "ifalias": + interfaceClass.IfAlias = value + case "ifindex": + interfaceClass.IfIndex = vp.PInt64() + case "iflink": + interfaceClass.IfLink = vp.PInt64() + case "link_mode": + interfaceClass.LinkMode = vp.PInt64() + case "mtu": + interfaceClass.MTU = vp.PInt64() + case "name_assign_type": + interfaceClass.NameAssignType = vp.PInt64() + case "netdev_group": + interfaceClass.NetDevGroup = vp.PInt64() + case "operstate": + interfaceClass.OperState = value + case "phys_port_id": + interfaceClass.PhysPortID = value + case "phys_port_name": + interfaceClass.PhysPortName = value + case "phys_switch_id": + interfaceClass.PhysSwitchID = value + case "speed": + interfaceClass.Speed = vp.PInt64() + case "tx_queue_len": + interfaceClass.TxQueueLen = vp.PInt64() + case "type": + interfaceClass.Type = vp.PInt64() + default: + return nil + } + + return nil +} + // parseNetClassIface scans predefined files in /sys/class/net/ // directory and gets their contents. func parseNetClassIface(devicePath string) (*NetClassIface, error) { @@ -131,68 +202,12 @@ func parseNetClassIface(devicePath string) (*NetClassIface, error) { if !f.Type().IsRegular() { continue } - name := filepath.Join(devicePath, f.Name()) - value, err := util.SysReadFile(name) + err := ParseNetClassAttribute(devicePath, f.Name(), &interfaceClass) if err != nil { - if os.IsNotExist(err) || os.IsPermission(err) || err.Error() == "operation not supported" || errors.Is(err, os.ErrInvalid) { - continue + // Return fatal errors to caller + if !os.IsNotExist(err) && !os.IsPermission(err) && err.Error() != "operation not supported" && !errors.Is(err, os.ErrInvalid) { + return nil, err } - return nil, fmt.Errorf("failed to read file %q: %w", name, err) - } - vp := util.NewValueParser(value) - switch f.Name() { - case "addr_assign_type": - interfaceClass.AddrAssignType = vp.PInt64() - case "addr_len": - interfaceClass.AddrLen = vp.PInt64() - case "address": - interfaceClass.Address = value - case "broadcast": - interfaceClass.Broadcast = value - case "carrier": - interfaceClass.Carrier = vp.PInt64() - case "carrier_changes": - interfaceClass.CarrierChanges = vp.PInt64() - case "carrier_up_count": - interfaceClass.CarrierUpCount = vp.PInt64() - case "carrier_down_count": - interfaceClass.CarrierDownCount = vp.PInt64() - case "dev_id": - interfaceClass.DevID = vp.PInt64() - case "dormant": - interfaceClass.Dormant = vp.PInt64() - case "duplex": - interfaceClass.Duplex = value - case "flags": - interfaceClass.Flags = vp.PInt64() - case "ifalias": - interfaceClass.IfAlias = value - case "ifindex": - interfaceClass.IfIndex = vp.PInt64() - case "iflink": - interfaceClass.IfLink = vp.PInt64() - case "link_mode": - interfaceClass.LinkMode = vp.PInt64() - case "mtu": - interfaceClass.MTU = vp.PInt64() - case "name_assign_type": - interfaceClass.NameAssignType = vp.PInt64() - case "netdev_group": - interfaceClass.NetDevGroup = vp.PInt64() - case "operstate": - interfaceClass.OperState = value - case "phys_port_id": - interfaceClass.PhysPortID = value - case "phys_port_name": - interfaceClass.PhysPortName = value - case "phys_switch_id": - interfaceClass.PhysSwitchID = value - case "speed": - interfaceClass.Speed = vp.PInt64() - case "tx_queue_len": - interfaceClass.TxQueueLen = vp.PInt64() - case "type": - interfaceClass.Type = vp.PInt64() } }