diff --git a/debian/control b/debian/control index d1d1602ae..f8cfb876c 100644 --- a/debian/control +++ b/debian/control @@ -1,384 +1,384 @@ Source: vyos-1x Section: contrib/net Priority: extra Maintainer: VyOS Package Maintainers <maintainers@vyos.net> Build-Depends: debhelper (>= 9), dh-python, fakeroot, gcc, iproute2, libvyosconfig0 (>= 0.0.7), libzmq3-dev, python3 (>= 3.10), # For QA pylint, # For generating command definitions python3-lxml, python3-xmltodict, # For running tests python3-coverage, python3-hurry.filesize, python3-netaddr, python3-netifaces, python3-nose, python3-jinja2, python3-paramiko, python3-passlib, python3-psutil, python3-requests, python3-setuptools, python3-tabulate, python3-zmq, quilt, whois Standards-Version: 3.9.6 Package: vyos-1x Architecture: amd64 arm64 Pre-Depends: libpam-runtime [amd64], libnss-tacplus [amd64], libpam-tacplus [amd64], libpam-radius-auth [amd64] Depends: ## Fundamentals ${python3:Depends} (>= 3.10), dialog, libvyosconfig0, libpam-cap, bash-completion, ipvsadm, udev, less, at, rsync, vyatta-bash, vyatta-biosdevname, vyatta-cfg, vyos-http-api-tools, vyos-utils, ## End of Fundamentals ## Python libraries used in multiple modules and scripts python3, python3-cryptography, python3-hurry.filesize, python3-inotify, python3-jinja2, python3-jmespath, python3-netaddr, python3-netifaces, python3-paramiko, python3-passlib, python3-pyroute2, python3-psutil, python3-pyhumps, python3-pystache, python3-pyudev, python3-six, python3-tabulate, python3-voluptuous, python3-xmltodict, python3-zmq, ## End of Python libraries ## Basic System services and utilities coreutils, sudo, systemd, bsdmainutils, openssl, curl, dbus, file, iproute2 (>= 6.0.0), linux-cpupower, # ipaddrcheck is widely used in IP value validators ipaddrcheck, - ethtool, + ethtool (>= 6.10), lm-sensors, procps, netplug, sed, ssl-cert, tuned, beep, wide-dhcpv6-client, # Generic colorizer grc, ## End of System services and utilities ## For the installer fdisk, gdisk, mdadm, efibootmgr, libefivar1, dosfstools, grub-efi-amd64-signed [amd64], grub-efi-arm64-bin [arm64], mokutil [amd64], shim-signed [amd64], sbsigntool [amd64], # Image signature verification tool minisign, # Live filesystem tools squashfs-tools, fuse-overlayfs, ## End installer auditd, iputils-arping, iputils-ping, isc-dhcp-client, # For "vpn pptp", "vpn l2tp", "vpn sstp", "service ipoe-server" accel-ppp, # End "vpn pptp", "vpn l2tp", "vpn sstp", "service ipoe-server" avahi-daemon, conntrack, conntrackd, ## Conf mode features # For "interfaces wireless" hostapd, hsflowd, iw, wireless-regdb, wpasupplicant (>= 0.6.7), # End "interfaces wireless" # For "interfaces wwan" modemmanager, usb-modeswitch, libqmi-utils, # End "interfaces wwan" # For "interfaces openvpn" openvpn, openvpn-auth-ldap, openvpn-auth-radius, openvpn-otp, openvpn-dco, libpam-google-authenticator, # End "interfaces openvpn" # For "interfaces wireguard" wireguard-tools, qrencode, # End "interfaces wireguard" # For "interfaces pppoe" pppoe, # End "interfaces pppoe" # For "interfaces sstpc" sstp-client, # End "interfaces sstpc" # For "protocols *" frr (>= 9.1), frr-pythontools, frr-rpki-rtrlib, frr-snmp, # End "protocols *" # For "protocols nhrp" (part of DMVPN) opennhrp, # End "protocols nhrp" # For "protocols igmp-proxy" igmpproxy, # End "protocols igmp-proxy" # For "pki" certbot, # End "pki" # For "service console-server" conserver-client, conserver-server, console-data, dropbear, # End "service console-server" # For "service aws glb" aws-gwlbtun, # For "service dns dynamic" ddclient (>= 3.11.1), # End "service dns dynamic" # # For "service ids" fastnetmon [amd64], suricata, suricata-update, # End "service ids" # # For "service ndp-proxy" ndppd, # End "service ndp-proxy" # For "service router-advert" radvd, # End "service route-advert" # For "load-balancing reverse-proxy" haproxy, # End "load-balancing reverse-proxy" # For "load-balancing wan" vyatta-wanloadbalance, # End "load-balancing wan" # For "service dhcp-relay" isc-dhcp-relay, # For "service dhcp-server" kea, # End "service dhcp-server" # For "service lldp" lldpd, # End "service lldp" # For "service https" nginx-light, # End "service https" # For "service ssh" openssh-server, sshguard, # End "service ssh" # For "service salt-minion" salt-minion, # End "service salt-minion" # For "service snmp" snmp, snmpd, # End "service snmp" # For "service webproxy" squid, squidclient, squidguard, # End "service webproxy" # For "service monitoring telegraf" telegraf (>= 1.20), # End "service monitoring telegraf" # For "service monitoring zabbix-agent" zabbix-agent2, # End "service monitoring zabbix-agent" # For "service tftp-server" tftpd-hpa, # End "service tftp-server" # For "service dns forwarding" pdns-recursor, # End "service dns forwarding" # For "service sla owamp" owamp-client, owamp-server, # End "service sla owamp" # For "service sla twamp" twamp-client, twamp-server, # End "service sla twamp" # For "service broadcast-relay" udp-broadcast-relay, # End "service broadcast-relay" # For "high-availability vrrp" keepalived (>=2.0.5), # End "high-availability-vrrp" # For "system console" util-linux, # End "system console" # For "system task-scheduler" cron, # End "system task-scheduler" # For "system lcd" lcdproc, lcdproc-extra-drivers, # End "system lcd" # For "system config-management commit-archive" git, # End "system config-management commit-archive" # For firewall libndp-tools, libnetfilter-conntrack3, libnfnetlink0, nfct, nftables (>= 0.9.3), # For "vpn ipsec" strongswan (>= 5.9), strongswan-swanctl (>= 5.9), charon-systemd, libcharon-extra-plugins (>=5.9), libcharon-extauth-plugins (>=5.9), libstrongswan-extra-plugins (>=5.9), libstrongswan-standard-plugins (>=5.9), python3-vici (>= 5.7.2), # End "vpn ipsec" # For "nat64" jool, # End "nat64" # For "system conntrack modules rtsp" nat-rtsp, # End "system conntrack modules rtsp" # For "service ntp" chrony, # End "system ntp" # For "vpn openconnect" ocserv, # End "vpn openconnect" # For "system flow-accounting" pmacct (>= 1.6.0), # End "system flow-accounting" # For "system syslog" rsyslog, # End "system syslog" # For "system option keyboard-layout" kbd, # End "system option keyboard-layout" # For "container" podman (>=4.9.5), netavark, aardvark-dns, # iptables is only used for containers now, not the the firewall CLI iptables, # End container ## End Configuration mode ## Operational mode # Used for hypervisor model in "run show version" hvinfo, # For "run traceroute" traceroute, # For "run monitor traffic" tcpdump, # End "run monitor traffic" # For "show hardware dmi" dmidecode, # For "run show hardware storage smart" smartmontools, # For "run show hardware scsi" lsscsi, # For "run show hardware pci" pciutils, # For "show hardware usb" usbutils, # For "run show hardware storage nvme" nvme-cli, # For "run monitor bandwidth-test" iperf, iperf3, # End "run monitor bandwidth-test" # For "run wake-on-lan" etherwake, # For "run force ipv6-nd" ndisc6, # For "run monitor bandwidth" bmon, # For "run format disk" parted, # End Operational mode ## TPM tools cryptsetup, tpm2-tools, ## End TPM tools ## Optional utilities easy-rsa, tcptraceroute, mtr-tiny, telnet, stunnel4, uidmap ## End optional utilities Description: VyOS configuration scripts and data VyOS configuration scripts, interface definitions, and everything Package: vyos-1x-vmware Architecture: amd64 Depends: vyos-1x, open-vm-tools Description: VyOS configuration scripts and data for VMware Adds configuration files required for VyOS running on VMware hosts. Package: vyos-1x-smoketest Architecture: all Depends: skopeo, snmp, vyos-1x Description: VyOS build sanity checking toolkit diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 80bb56fa2..21272cc5b 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -1,204 +1,200 @@ # Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library. If not, see <http://www.gnu.org/licenses/>. import re from json import loads from vyos.utils.network import interface_exists from vyos.utils.process import popen # These drivers do not support using ethtool to change the speed, duplex, or # flow control settings _drivers_without_speed_duplex_flow = ['vmxnet3', 'virtio_net', 'xen_netfront', 'iavf', 'ice', 'i40e', 'hv_netvsc', 'veth', 'ixgbevf', 'tun'] class Ethtool: """ Class is used to retrive and cache information about an ethernet adapter """ # dictionary containing driver featurs, it will be populated on demand and # the content will look like: # [{'esp-hw-offload': {'active': False, 'fixed': True, 'requested': False}, # 'esp-tx-csum-hw-offload': {'active': False, # 'fixed': True, # 'requested': False}, # 'fcoe-mtu': {'active': False, 'fixed': True, 'requested': False}, # 'generic-receive-offload': {'active': True, # 'fixed': False, # 'requested': True}, # 'generic-segmentation-offload': {'active': True, # 'fixed': False, # 'requested': True}, # 'highdma': {'active': True, 'fixed': False, 'requested': True}, # 'ifname': 'eth0', # 'l2-fwd-offload': {'active': False, 'fixed': True, 'requested': False}, # 'large-receive-offload': {'active': False, # 'fixed': False, # 'requested': False}, # ... _features = { } # dictionary containing available interface speed and duplex settings # { # '10' : {'full': '', 'half': ''}, # '100' : {'full': '', 'half': ''}, # '1000': {'full': ''} # } - _speed_duplex = {'auto': {'auto': ''}} _ring_buffer = None _driver_name = None - _auto_negotiation = False - _auto_negotiation_supported = None _flow_control = None def __init__(self, ifname): # Get driver used for interface if not interface_exists(ifname): raise ValueError(f'Interface "{ifname}" does not exist!') out, _ = popen(f'ethtool --driver {ifname}') driver = re.search(r'driver:\s(\w+)', out) if driver: self._driver_name = driver.group(1) # Build a dictinary of supported link-speed and dupley settings. - out, _ = popen(f'ethtool {ifname}') - reading = False - pattern = re.compile(r'\d+base.*') - for line in out.splitlines()[1:]: - line = line.lstrip() - if 'Supported link modes:' in line: - reading = True - if 'Supported pause frame use:' in line: - reading = False - if reading: - for block in line.split(): - if pattern.search(block): - speed = block.split('base')[0] - duplex = block.split('/')[-1].lower() - if speed not in self._speed_duplex: - self._speed_duplex.update({ speed : {}}) - if duplex not in self._speed_duplex[speed]: - self._speed_duplex[speed].update({ duplex : ''}) - if 'Supports auto-negotiation:' in line: - # Split the following string: Auto-negotiation: off - # we are only interested in off or on - tmp = line.split()[-1] - self._auto_negotiation_supported = bool(tmp == 'Yes') - # Only read in if Auto-negotiation is supported - if self._auto_negotiation_supported and 'Auto-negotiation:' in line: - # Split the following string: Auto-negotiation: off - # we are only interested in off or on - tmp = line.split()[-1] - self._auto_negotiation = bool(tmp == 'on') + # [ { + # "ifname": "eth0", + # "supported-ports": [ "TP" ], + # "supported-link-modes": [ "10baseT/Half","10baseT/Full","100baseT/Half","100baseT/Full","1000baseT/Full" ], + # "supported-pause-frame-use": "Symmetric", + # "supports-auto-negotiation": true, + # "supported-fec-modes": [ ], + # "advertised-link-modes": [ "10baseT/Half","10baseT/Full","100baseT/Half","100baseT/Full","1000baseT/Full" ], + # "advertised-pause-frame-use": "Symmetric", + # "advertised-auto-negotiation": true, + # "advertised-fec-modes": [ ], + # "speed": 1000, + # "duplex": "Full", + # "auto-negotiation": false, + # "port": "Twisted Pair", + # "phyad": 1, + # "transceiver": "internal", + # "supports-wake-on": "pumbg", + # "wake-on": "g", + # "current-message-level": 7, + # "link-detected": true + # } ] + out, _ = popen(f'ethtool --json {ifname}') + self._base_settings = loads(out)[0] # Now populate driver features out, _ = popen(f'ethtool --json --show-features {ifname}') - self._features = loads(out) + self._features = loads(out)[0] # Get information about NIC ring buffers out, _ = popen(f'ethtool --json --show-ring {ifname}') - self._ring_buffer = loads(out) + self._ring_buffer = loads(out)[0] # Get current flow control settings, but this is not supported by # all NICs (e.g. vmxnet3 does not support is) out, err = popen(f'ethtool --json --show-pause {ifname}') if not bool(err): - self._flow_control = loads(out) + self._flow_control = loads(out)[0] def check_auto_negotiation_supported(self): """ Check if the NIC supports changing auto-negotiation """ - return self._auto_negotiation_supported + return self._base_settings['supports-auto-negotiation'] def get_auto_negotiation(self): - return self._auto_negotiation_supported and self._auto_negotiation + return self._base_settings['supports-auto-negotiation'] and self._base_settings['auto-negotiation'] def get_driver_name(self): return self._driver_name def _get_generic(self, feature): """ Generic method to read self._features and return a tuple for feature enabled and feature is fixed. In case of a missing key, return "fixed = True and enabled = False" """ active = False fixed = True - if feature in self._features[0]: - active = bool(self._features[0][feature]['active']) - fixed = bool(self._features[0][feature]['fixed']) + if feature in self._features: + active = bool(self._features[feature]['active']) + fixed = bool(self._features[feature]['fixed']) return active, fixed def get_generic_receive_offload(self): return self._get_generic('generic-receive-offload') def get_generic_segmentation_offload(self): return self._get_generic('generic-segmentation-offload') def get_hw_tc_offload(self): return self._get_generic('hw-tc-offload') def get_large_receive_offload(self): return self._get_generic('large-receive-offload') def get_scatter_gather(self): return self._get_generic('scatter-gather') def get_tcp_segmentation_offload(self): return self._get_generic('tcp-segmentation-offload') def get_ring_buffer_max(self, rx_tx): # Configuration of RX/TX ring-buffers is not supported on every device, # thus when it's impossible return None if rx_tx not in ['rx', 'tx']: ValueError('Ring-buffer type must be either "rx" or "tx"') - return str(self._ring_buffer[0].get(f'{rx_tx}-max', None)) + return str(self._ring_buffer.get(f'{rx_tx}-max', None)) def get_ring_buffer(self, rx_tx): # Configuration of RX/TX ring-buffers is not supported on every device, # thus when it's impossible return None if rx_tx not in ['rx', 'tx']: ValueError('Ring-buffer type must be either "rx" or "tx"') - return str(self._ring_buffer[0].get(rx_tx, None)) + return str(self._ring_buffer.get(rx_tx, None)) def check_speed_duplex(self, speed, duplex): """ Check if the passed speed and duplex combination is supported by the underlaying network adapter. """ if isinstance(speed, int): speed = str(speed) if speed != 'auto' and not speed.isdigit(): raise ValueError(f'Value "{speed}" for speed is invalid!') if duplex not in ['auto', 'full', 'half']: raise ValueError(f'Value "{duplex}" for duplex is invalid!') + if speed == 'auto' and duplex == 'auto': + return True + if self.get_driver_name() in _drivers_without_speed_duplex_flow: return False - if speed in self._speed_duplex: - if duplex in self._speed_duplex[speed]: - return True + # ['10baset/half', '10baset/full', '100baset/half', '100baset/full', '1000baset/full'] + tmp = [x.lower() for x in self._base_settings['supported-link-modes']] + if f'{speed}baset/{duplex}' in tmp: + return True return False def check_flow_control(self): """ Check if the NIC supports flow-control """ return bool(self._flow_control) def get_flow_control(self): if self._flow_control == None: raise ValueError('Interface does not support changing '\ 'flow-control settings!') - return 'on' if bool(self._flow_control[0]['autonegotiate']) else 'off' + return 'on' if bool(self._flow_control['autonegotiate']) else 'off'