From 91892e431349ca0edb5e3e3023e4f340ab9b777f Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 31 Aug 2021 11:58:46 +0200 Subject: ethernet: T3514: bail out early on invalid adapter speed/duplex setting Ethernet adapters have a discrete set of available speed and duplex settings. Instead of passing every value down to ethtool and let it decide, we can do this early in the VyOS verify() function for ethernet interfaces. --- src/conf_mode/interfaces-ethernet.py | 50 +++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index 78c24952b..27c4a7c38 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -73,32 +73,20 @@ def verify(ethernet): ifname = ethernet['ifname'] verify_interface_exists(ifname) + ethtool = Ethtool(ifname) # No need to check speed and duplex keys as both have default values. if ((ethernet['speed'] == 'auto' and ethernet['duplex'] != 'auto') or (ethernet['speed'] != 'auto' and ethernet['duplex'] == 'auto')): raise ConfigError('Speed/Duplex missmatch. Must be both auto or manually configured') - verify_mtu(ethernet) - verify_mtu_ipv6(ethernet) - verify_dhcpv6(ethernet) - verify_address(ethernet) - verify_vrf(ethernet) - verify_eapol(ethernet) - verify_mirror(ethernet) + if ethernet['speed'] != 'auto' and ethernet['duplex'] != 'auto': + # We need to verify if the requested speed and duplex setting is + # supported by the underlaying NIC. + speed = ethernet['speed'] + duplex = ethernet['duplex'] + if not ethtool.check_speed_duplex(speed, duplex): + raise ConfigError(f'Adapter does not support speed "{speed}" and duplex "{duplex}"!') - # verify offloading capabilities - if dict_search('offload.rps', ethernet) != None: - if not os.path.exists(f'/sys/class/net/{ifname}/queues/rx-0/rps_cpus'): - raise ConfigError('Interface does not suport RPS!') - - driver = EthernetIf(ifname).get_driver_name() - # T3342 - Xen driver requires special treatment - if driver == 'vif': - if int(ethernet['mtu']) > 1500 and dict_search('offload.sg', ethernet) == None: - raise ConfigError('Xen netback drivers requires scatter-gatter offloading '\ - 'for MTU size larger then 1500 bytes') - - ethtool = Ethtool(ifname) if 'ring_buffer' in ethernet: max_rx = ethtool.get_rx_buffer() if not max_rx: @@ -118,6 +106,26 @@ def verify(ethernet): raise ConfigError(f'Driver only supports a maximum TX ring-buffer '\ f'size of "{max_tx}" bytes!') + verify_mtu(ethernet) + verify_mtu_ipv6(ethernet) + verify_dhcpv6(ethernet) + verify_address(ethernet) + verify_vrf(ethernet) + verify_eapol(ethernet) + verify_mirror(ethernet) + + # verify offloading capabilities + if dict_search('offload.rps', ethernet) != None: + if not os.path.exists(f'/sys/class/net/{ifname}/queues/rx-0/rps_cpus'): + raise ConfigError('Interface does not suport RPS!') + + driver = EthernetIf(ifname).get_driver_name() + # T3342 - Xen driver requires special treatment + if driver == 'vif': + if int(ethernet['mtu']) > 1500 and dict_search('offload.sg', ethernet) == None: + raise ConfigError('Xen netback drivers requires scatter-gatter offloading '\ + 'for MTU size larger then 1500 bytes') + # XDP requires multiple TX queues if 'xdp' in ethernet: queues = glob(f'/sys/class/net/{ifname}/queues/tx-*') @@ -136,7 +144,7 @@ def generate(ethernet): if 'eapol' in ethernet: render(wpa_suppl_conf.format(**ethernet), 'ethernet/wpa_supplicant.conf.tmpl', ethernet) - + ifname = ethernet['ifname'] cert_file_path = os.path.join(cfg_dir, f'{ifname}_cert.pem') cert_key_path = os.path.join(cfg_dir, f'{ifname}_cert.key') -- cgit v1.2.3