From 4abf852917b51b32f3778ccb1074ed9cf42124b0 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sat, 28 Aug 2021 17:41:34 +0200 Subject: vyos.ethtool: T3163: rename unused methods for offload validation (cherry picked from commit d22f97af23abb5c12f8ea79c50fdda7ee0a3832d) --- python/vyos/ethtool.py | 75 +++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 32 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index bc103959a..0ae526346 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -23,14 +23,14 @@ class Ethtool: # dictionary containing driver featurs, it will be populated on demand and # the content will look like: # { - # 'tls-hw-tx-offload': {'fixed': True, 'on': False}, - # 'tx-checksum-fcoe-crc': {'fixed': True, 'on': False}, - # 'tx-checksum-ip-generic': {'fixed': False, 'on': True}, - # 'tx-checksum-ipv4': {'fixed': True, 'on': False}, - # 'tx-checksum-ipv6': {'fixed': True, 'on': False}, - # 'tx-checksum-sctp': {'fixed': True, 'on': False}, - # 'tx-checksumming': {'fixed': False, 'on': True}, - # 'tx-esp-segmentation': {'fixed': True, 'on': False}, + # 'tls-hw-tx-offload': {'fixed': True, 'enabled': False}, + # 'tx-checksum-fcoe-crc': {'fixed': True, 'enabled': False}, + # 'tx-checksum-ip-generic': {'fixed': False, 'enabled': True}, + # 'tx-checksum-ipv4': {'fixed': True, 'enabled': False}, + # 'tx-checksum-ipv6': {'fixed': True, 'enabled': False}, + # 'tx-checksum-sctp': {'fixed': True, 'enabled': False}, + # 'tx-checksumming': {'fixed': False, 'enabled': True}, + # 'tx-esp-segmentation': {'fixed': True, 'enabled': False}, # } features = { } ring_buffers = { } @@ -42,12 +42,12 @@ class Ethtool: for line in out.splitlines()[1:]: if ":" in line: key, value = [s.strip() for s in line.strip().split(":", 1)] - fixed = "fixed" in value + fixed = bool('fixed' in value) if fixed: value = value.split()[0].strip() self.features[key.strip()] = { - "on": value == "on", - "fixed": fixed + 'enabled' : bool(value == 'on'), + 'fixed' : fixed } out, err = popen(f'ethtool -g {ifname}') @@ -63,36 +63,47 @@ class Ethtool: if value.isdigit(): self.ring_buffers[key] = int(value) - def is_fixed_lro(self): # in case of a missing configuration, rather return "fixed". In Ethtool # terminology "fixed" means the setting can not be changed by the user. return self.features.get('large-receive-offload', True).get('fixed', True) - def is_fixed_gro(self): - # in case of a missing configuration, rather return "fixed". In Ethtool - # terminology "fixed" means the setting can not be changed by the user. - return self.features.get('generic-receive-offload', True).get('fixed', True) + def _get_generic(self, feature): + """ + Generic method to read self.features and return a tuple for feature + enabled and feature is fixed. - def is_fixed_gso(self): - # in case of a missing configuration, rather return "fixed". In Ethtool - # terminology "fixed" means the setting can not be changed by the user. - return self.features.get('generic-segmentation-offload', True).get('fixed', True) + In case of a missing key, return "fixed = True and enabled = False" + """ + fixed = True + enabled = False + if feature in self.features: + if 'enabled' in self.features[feature]: + enabled = self.features[feature]['enabled'] + if 'fixed' in self.features[feature]: + fixed = self.features[feature]['fixed'] + return enabled, fixed - def is_fixed_sg(self): - # in case of a missing configuration, rather return "fixed". In Ethtool - # terminology "fixed" means the setting can not be changed by the user. - return self.features.get('scatter-gather', True).get('fixed', True) + def get_generic_receive_offload(self): + return self._get_generic('generic-receive-offload') - def is_fixed_tso(self): - # in case of a missing configuration, rather return "fixed". In Ethtool - # terminology "fixed" means the setting can not be changed by the user. - return self.features.get('tcp-segmentation-offload', True).get('fixed', True) + def get_generic_segmentation_offload(self): + return self._get_generic('generic-segmentation-offload') - def is_fixed_ufo(self): - # in case of a missing configuration, rather return "fixed". In Ethtool - # terminology "fixed" means the setting can not be changed by the user. - return self.features.get('udp-fragmentation-offload', True).get('fixed', True) + 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_udp_fragmentation_offload(self): + return self._get_generic('udp-fragmentation-offload') + + def get_rx_vlan_offload(self): + return self._get_generic('rx-vlan-offload') def get_rx_buffer(self): # Configuration of RX ring-buffers is not supported on every device, -- cgit v1.2.3 From 1c9db89970943bdb3f213741c5085537e3965fe1 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 29 Aug 2021 22:12:32 +0200 Subject: vyos.ethtool: T3163: drop obsoleted is_fixed_lro() method Commit d22f97af ("vyos.ethtool: T3163: rename unused methods for offload validation") reworked the entire class on how data should be presented to the user, but forgot to drop the is_fixed_lro() method. (cherry picked from commit eac8915413cedce089234fdbef57ad25da208eec) --- python/vyos/ethtool.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 0ae526346..e2cd37726 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -63,11 +63,6 @@ class Ethtool: if value.isdigit(): self.ring_buffers[key] = int(value) - def is_fixed_lro(self): - # in case of a missing configuration, rather return "fixed". In Ethtool - # terminology "fixed" means the setting can not be changed by the user. - return self.features.get('large-receive-offload', True).get('fixed', True) - def _get_generic(self, feature): """ Generic method to read self.features and return a tuple for feature -- cgit v1.2.3 From f4c6697582ddc4b6546107c9d4040bcdadf55b44 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 29 Aug 2021 23:10:31 +0200 Subject: vyos.ethtool: T3163: prefix class internal data structures with _ (cherry picked from commit 324aa9598c7d90efc917a00447380f985553b657) --- python/vyos/ethtool.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index e2cd37726..25a116d09 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -19,7 +19,6 @@ 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: # { @@ -32,8 +31,8 @@ class Ethtool: # 'tx-checksumming': {'fixed': False, 'enabled': True}, # 'tx-esp-segmentation': {'fixed': True, 'enabled': False}, # } - features = { } - ring_buffers = { } + _features = { } + _ring_buffers = { } def __init__(self, ifname): # Now populate features dictionaty @@ -45,7 +44,7 @@ class Ethtool: fixed = bool('fixed' in value) if fixed: value = value.split()[0].strip() - self.features[key.strip()] = { + self._features[key.strip()] = { 'enabled' : bool(value == 'on'), 'fixed' : fixed } @@ -61,22 +60,22 @@ class Ethtool: # output format from 0 -> n/a. As we are only interested in the # tx/rx keys we do not care about RX Mini/Jumbo. if value.isdigit(): - self.ring_buffers[key] = int(value) + self._ring_buffers[key] = int(value) def _get_generic(self, feature): """ - Generic method to read self.features and return a tuple for 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" """ fixed = True enabled = False - if feature in self.features: - if 'enabled' in self.features[feature]: - enabled = self.features[feature]['enabled'] - if 'fixed' in self.features[feature]: - fixed = self.features[feature]['fixed'] + if feature in self._features: + if 'enabled' in self._features[feature]: + enabled = self._features[feature]['enabled'] + if 'fixed' in self._features[feature]: + fixed = self._features[feature]['fixed'] return enabled, fixed def get_generic_receive_offload(self): @@ -103,9 +102,9 @@ class Ethtool: def get_rx_buffer(self): # Configuration of RX ring-buffers is not supported on every device, # thus when it's impossible return None - return self.ring_buffers.get('rx', None) + return self._ring_buffers.get('rx', None) def get_tx_buffer(self): # Configuration of TX ring-buffers is not supported on every device, # thus when it's impossible return None - return self.ring_buffers.get('tx', None) + return self._ring_buffers.get('tx', None) -- cgit v1.2.3 From ebf69a83bd1a2dba27e1c0bc6ecc4e1ea74683a1 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 29 Aug 2021 23:18:06 +0200 Subject: vyos.ethtool: T3163: add check_speed_duplex() method Add a new method which supports checking if the desired speed and duplex setting is actually supported by the underlaying network interface card. >>> from vyos.ethtool import Ethtool >>> tmp = Ethtool('eth0') >>> tmp.check_speed_duplex('100', 'full') False >>> tmp.check_speed_duplex('1000', 'full') True (cherry picked from commit 147f655a69cd9526cd23f51ab18027cb5abc95b2) --- python/vyos/ethtool.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 25a116d09..81284b686 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -13,6 +13,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with this library. If not, see . +import re from vyos.util import popen class Ethtool: @@ -32,9 +33,37 @@ class Ethtool: # 'tx-esp-segmentation': {'fixed': True, 'enabled': False}, # } _features = { } + # dictionary containing available interface speed and duplex settings + # { + # '10' : {'full': '', 'half': ''}, + # '100' : {'full': '', 'half': ''}, + # '1000': {'full': ''} + # } + _speed_duplex = { } _ring_buffers = { } def __init__(self, ifname): + # Build a dictinary of supported link-speed and dupley settings. + out, err = 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 + break + 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 : ''}) + # Now populate features dictionaty out, err = popen(f'ethtool -k {ifname}') # skip the first line, it only says: "Features for eth0": @@ -108,3 +137,18 @@ class Ethtool: # Configuration of TX ring-buffers is not supported on every device, # thus when it's impossible return None return self._ring_buffers.get('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 not speed.isdigit(): + raise ValueError(f'Value "{speed}" for speed is invalid!') + if duplex not in ['full', 'half']: + raise ValueError(f'Value "{duplex}" for duplex is invalid!') + + if speed in self._speed_duplex: + if duplex in self._speed_duplex[speed]: + return True + return False -- cgit v1.2.3 From 6f31b78d867f21405cc214697cf569b2df41288d Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Mon, 30 Aug 2021 21:25:20 +0200 Subject: vyos.ethtool: T3163: remove test and debug method get_rx_vlan_offload() (cherry picked from commit 50364a4b7a9de85fe59a6a4fb611bafb64c9f7f0) --- python/vyos/ethtool.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 81284b686..a81ddac31 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -125,9 +125,6 @@ class Ethtool: def get_udp_fragmentation_offload(self): return self._get_generic('udp-fragmentation-offload') - def get_rx_vlan_offload(self): - return self._get_generic('rx-vlan-offload') - def get_rx_buffer(self): # Configuration of RX ring-buffers is not supported on every device, # thus when it's impossible return None -- cgit v1.2.3 From f5e46ee6cc2b6c1c1869e26beca4ccd5bf52b62f Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Mon, 30 Aug 2021 21:36:52 +0200 Subject: ethernet: T3787: remove deprecated UDP fragmentation offloading option Deprecated in the Linux Kernel by commit 08a00fea6de277df12ccfadc21 ("net: Remove references to NETIF_F_UFO from ethtool."). --- interface-definitions/interfaces-ethernet.xml.in | 6 ----- python/vyos/ethtool.py | 3 --- python/vyos/ifconfig/ethernet.py | 28 ------------------------ src/migration-scripts/interfaces/20-to-21 | 12 ++++------ 4 files changed, 4 insertions(+), 45 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/interface-definitions/interfaces-ethernet.xml.in b/interface-definitions/interfaces-ethernet.xml.in index ec20bca8d..27d555552 100644 --- a/interface-definitions/interfaces-ethernet.xml.in +++ b/interface-definitions/interfaces-ethernet.xml.in @@ -101,12 +101,6 @@ - - - Enable UDP Fragmentation Offloading - - - diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index a81ddac31..397be6bb2 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -122,9 +122,6 @@ class Ethtool: def get_tcp_segmentation_offload(self): return self._get_generic('tcp-segmentation-offload') - def get_udp_fragmentation_offload(self): - return self._get_generic('udp-fragmentation-offload') - def get_rx_buffer(self): # Configuration of RX ring-buffers is not supported on every device, # thus when it's impossible return None diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py index cb03a006c..a6c7f5f25 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -72,11 +72,6 @@ class EthernetIf(Interface): 'possible': lambda i, v: EthernetIf.feature(i, 'tso', v), # 'shellcmd': 'ethtool -K {ifname} tso {value}', }, - 'ufo': { - 'validate': lambda v: assert_list(v, ['on', 'off']), - 'possible': lambda i, v: EthernetIf.feature(i, 'ufo', v), - # 'shellcmd': 'ethtool -K {ifname} ufo {value}', - }, }} _sysfs_set = {**Interface._sysfs_set, **{ @@ -339,26 +334,6 @@ class EthernetIf(Interface): print('Adapter does not support changing tcp-segmentation-offload settings!') return False - def set_ufo(self, state): - """ - Enable UDP fragmentation offloading. State can be either True or False. - - Example: - >>> from vyos.ifconfig import EthernetIf - >>> i = EthernetIf('eth0') - >>> i.set_udp_offload(True) - """ - if not isinstance(state, bool): - raise ValueError('Value out of range') - - enabled, fixed = self.ethtool.get_udp_fragmentation_offload() - if enabled != state: - if not fixed: - return self.set_interface('gro', 'on' if state else 'off') - else: - print('Adapter does not support changing udp-fragmentation-offload settings!') - return False - def set_ring_buffer(self, b_type, b_size): """ Example: @@ -404,9 +379,6 @@ class EthernetIf(Interface): # TSO (TCP segmentation offloading) self.set_tso(dict_search('offload.tso', config) != None) - # UDP fragmentation offloading - self.set_ufo(dict_search('offload.ufo', config) != None) - # Set physical interface speed and duplex if {'speed', 'duplex'} <= set(config): speed = config.get('speed') diff --git a/src/migration-scripts/interfaces/20-to-21 b/src/migration-scripts/interfaces/20-to-21 index 9210330d6..4b0e70d35 100755 --- a/src/migration-scripts/interfaces/20-to-21 +++ b/src/migration-scripts/interfaces/20-to-21 @@ -15,7 +15,8 @@ # along with this program. If not, see . # T3619: mirror Linux Kernel defaults for ethernet offloading options into VyOS -# CLI. See https://phabricator.vyos.net/T3619#102254 for all the details. +# CLI. See https://phabricator.vyos.net/T3619#102254 for all the details. +# T3787: Remove deprecated UDP fragmentation offloading option from sys import argv @@ -84,14 +85,9 @@ for ifname in config.list_nodes(base): elif enabled and not fixed: config.set(base + [ifname, 'offload', 'tso']) - # If UFO is enabled by the Kernel - we reflect this on the CLI. If UFO is - # enabled via CLI but not supported by the NIC - we remove it from the CLI - configured = config.exists(base + [ifname, 'offload', 'ufo']) - enabled, fixed = eth.get_udp_fragmentation_offload() - if configured and fixed: + # Remove deprecated UDP fragmentation offloading option + if config.exists(base + [ifname, 'offload', 'ufo']): config.delete(base + [ifname, 'offload', 'ufo']) - elif enabled and not fixed: - config.set(base + [ifname, 'offload', 'ufo']) try: with open(file_name, 'w') as f: -- cgit v1.2.3 From 862e6e96bfc557974dbbe374d0aefe654b76e664 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 31 Aug 2021 12:22:36 +0200 Subject: vyos.ethtool: T3163: use long option names when calling the ethtool binray This makes understanding the code easier what is "really" called without opening the man page. (cherry picked from commit a086dc2c429aea9614ac7a9c735c6475c2d6da59) --- op-mode-definitions/show-interfaces-ethernet.xml.in | 10 +++++----- python/vyos/ethtool.py | 2 +- python/vyos/ifconfig/ethernet.py | 7 +------ 3 files changed, 7 insertions(+), 12 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/op-mode-definitions/show-interfaces-ethernet.xml.in b/op-mode-definitions/show-interfaces-ethernet.xml.in index bdcfa55f1..897412295 100644 --- a/op-mode-definitions/show-interfaces-ethernet.xml.in +++ b/op-mode-definitions/show-interfaces-ethernet.xml.in @@ -23,19 +23,19 @@ Visually identify specified ethernet interface - echo "Blinking interface $4 for 30 seconds."; /sbin/ethtool --identify "$4" 30 + echo "Blinking interface $4 for 30 seconds."; ethtool --identify "$4" 30 Show physical device information for specified ethernet interface - /sbin/ethtool "$4"; /sbin/ethtool -i "$4" + ethtool "$4"; ethtool --driver "$4" Show physical device offloading capabilities - /sbin/ethtool -k "$4" | sed -e 1d -e '/fixed/d' -e 's/^\t*//g' -e 's/://' | column -t -s' ' + ethtool --show-features "$4" | sed -e 1d -e '/fixed/d' -e 's/^\t*//g' -e 's/://' | column -t -s' ' @@ -43,13 +43,13 @@ Show physical device statistics for specified ethernet interface - /sbin/ethtool -S "$4" + ethtool --statistics "$4" Show transceiver information from modules (e.g SFP+, QSFP) - /sbin/ethtool -m "$4" + ethtool --module-info "$4" diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 397be6bb2..55b7b776f 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -65,7 +65,7 @@ class Ethtool: self._speed_duplex[speed].update({ duplex : ''}) # Now populate features dictionaty - out, err = popen(f'ethtool -k {ifname}') + out, err = popen(f'ethtool --show-features {ifname}') # skip the first line, it only says: "Features for eth0": for line in out.splitlines()[1:]: if ":" in line: diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py index a6c7f5f25..2c9d99b91 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -43,34 +43,29 @@ class EthernetIf(Interface): @staticmethod def feature(ifname, option, value): - run(f'ethtool -K {ifname} {option} {value}') + run(f'ethtool --features {ifname} {option} {value}') return False _command_set = {**Interface._command_set, **{ 'gro': { 'validate': lambda v: assert_list(v, ['on', 'off']), 'possible': lambda i, v: EthernetIf.feature(i, 'gro', v), - # 'shellcmd': 'ethtool -K {ifname} gro {value}', }, 'gso': { 'validate': lambda v: assert_list(v, ['on', 'off']), 'possible': lambda i, v: EthernetIf.feature(i, 'gso', v), - # 'shellcmd': 'ethtool -K {ifname} gso {value}', }, 'lro': { 'validate': lambda v: assert_list(v, ['on', 'off']), 'possible': lambda i, v: EthernetIf.feature(i, 'lro', v), - # 'shellcmd': 'ethtool -K {ifname} lro {value}', }, 'sg': { 'validate': lambda v: assert_list(v, ['on', 'off']), 'possible': lambda i, v: EthernetIf.feature(i, 'sg', v), - # 'shellcmd': 'ethtool -K {ifname} sg {value}', }, 'tso': { 'validate': lambda v: assert_list(v, ['on', 'off']), 'possible': lambda i, v: EthernetIf.feature(i, 'tso', v), - # 'shellcmd': 'ethtool -K {ifname} tso {value}', }, }} -- cgit v1.2.3 From 2bfd809e9ae198d95b9fcb556440637fdcc4005c Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 31 Aug 2021 18:15:47 +0200 Subject: ethernet: T2241: check if interface supports changing speed/duplex settings Not all interface drivers have the ability to change the speed and duplex settings. Known drivers with this limitation are vmxnet3, virtio_net and xen_netfront. If this driver is detected, an error will be presented to the user. (cherry picked from commit cc742d48579e4f76e5d3230d87e22f71f76f9301) --- python/vyos/ethtool.py | 15 +++++++++++++++ src/conf_mode/interfaces-ethernet.py | 3 ++- src/migration-scripts/interfaces/20-to-21 | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 55b7b776f..fb2e49c1d 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -13,7 +13,9 @@ # You should have received a copy of the GNU Lesser General Public # License along with this library. If not, see . +import os import re + from vyos.util import popen class Ethtool: @@ -41,8 +43,18 @@ class Ethtool: # } _speed_duplex = { } _ring_buffers = { } + _driver_name = None def __init__(self, ifname): + # Get driver used for interface + sysfs_file = f'/sys/class/net/{ifname}/device/driver/module' + if os.path.exists(sysfs_file): + link = os.readlink(sysfs_file) + self._driver_name = os.path.basename(link) + + if not self._driver_name: + raise ValueError(f'Could not determine driver for interface {ifname}!') + # Build a dictinary of supported link-speed and dupley settings. out, err = popen(f'ethtool {ifname}') reading = False @@ -142,6 +154,9 @@ class Ethtool: if duplex not in ['full', 'half']: raise ValueError(f'Value "{duplex}" for duplex is invalid!') + if self._driver_name in ['vmxnet3', 'virtio_net', 'xen_netfront']: + return False + if speed in self._speed_duplex: if duplex in self._speed_duplex[speed]: return True diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index a7e01e279..57e05d4ea 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -75,7 +75,8 @@ def verify(ethernet): 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}"!') + raise ConfigError(f'Adapter does not support changing speed and duplex '\ + f'settings to: {speed}/{duplex}!') if 'ring_buffer' in ethernet: max_rx = ethtool.get_rx_buffer() diff --git a/src/migration-scripts/interfaces/20-to-21 b/src/migration-scripts/interfaces/20-to-21 index 4b0e70d35..bd89dcdb4 100755 --- a/src/migration-scripts/interfaces/20-to-21 +++ b/src/migration-scripts/interfaces/20-to-21 @@ -89,6 +89,21 @@ for ifname in config.list_nodes(base): if config.exists(base + [ifname, 'offload', 'ufo']): config.delete(base + [ifname, 'offload', 'ufo']) + # Also while processing the interface configuration, not all adapters support + # changing the speed and duplex settings. If the desired speed and duplex + # values do not work for the NIC driver, we change them back to the default + # value of "auto" - which will be applied if the CLI node is deleted. + speed_path = base + [ifname, 'speed'] + duplex_path = base + [ifname, 'duplex'] + # speed and duplex must always be set at the same time if not set to "auto" + if config.exists(speed_path) and config.exists(duplex_path): + speed = config.return_value(speed_path) + duplex = config.return_value(duplex_path) + if speed != 'auto' and duplex != 'auto': + if not eth.check_speed_duplex(speed, duplex): + config.delete(speed_path) + config.delete(duplex_path) + try: with open(file_name, 'w') as f: f.write(config.to_string()) -- cgit v1.2.3 From 5cbb1f3e4adba39d790f378afabb1e45416aff7c Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 31 Aug 2021 21:28:08 +0200 Subject: vyos.ethtool: T3163: purify code to read current speed and duplex settings It makes no sense to have a parser for the ethtool value sin ethtool.py and ethernet.py - one instance ios more then enough! (cherry picked from commit 6f5fb5c503b5df96d0686002355da3633b1fc597) --- python/vyos/ethtool.py | 14 +++++++++++++- python/vyos/ifconfig/ethernet.py | 22 +++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index fb2e49c1d..e803e28a1 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -44,6 +44,7 @@ class Ethtool: _speed_duplex = { } _ring_buffers = { } _driver_name = None + _auto_negotiation = None def __init__(self, ifname): # Get driver used for interface @@ -65,7 +66,6 @@ class Ethtool: reading = True if 'Supported pause frame use:' in line: reading = False - break if reading: for block in line.split(): if pattern.search(block): @@ -75,6 +75,15 @@ class Ethtool: self._speed_duplex.update({ speed : {}}) if duplex not in self._speed_duplex[speed]: self._speed_duplex[speed].update({ duplex : ''}) + if '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') + + if self._auto_negotiation == None: + raise ValueError(f'Could not determine auto-negotiation settings '\ + f'for interface {ifname}!') # Now populate features dictionaty out, err = popen(f'ethtool --show-features {ifname}') @@ -161,3 +170,6 @@ class Ethtool: if duplex in self._speed_duplex[speed]: return True return False + + def get_auto_negotiation(self): + return self._auto_negotiation diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py index 2c9d99b91..d6e42db99 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -20,6 +20,7 @@ from vyos.ethtool import Ethtool from vyos.ifconfig.interface import Interface from vyos.util import run from vyos.util import dict_search +from vyos.util import read_file from vyos.validate import assert_list @Interface.register @@ -182,32 +183,19 @@ class EthernetIf(Interface): # Get current speed and duplex settings: ifname = self.config['ifname'] - cmd = f'ethtool {ifname}' - tmp = self._cmd(cmd) - - if re.search("\tAuto-negotiation: on", tmp): + if self.ethtool.get_auto_negotiation(): if speed == 'auto' and duplex == 'auto': # bail out early as nothing is to change return else: # read in current speed and duplex settings - cur_speed = 0 - cur_duplex = '' - for line in tmp.splitlines(): - if line.lstrip().startswith("Speed:"): - non_decimal = re.compile(r'[^\d.]+') - cur_speed = non_decimal.sub('', line) - continue - - if line.lstrip().startswith("Duplex:"): - cur_duplex = line.split()[-1].lower() - break - + cur_speed = read_file(f'/sys/class/net/{ifname}/speed') + cur_duplex = read_file(f'/sys/class/net/{ifname}/duplex') if (cur_speed == speed) and (cur_duplex == duplex): # bail out early as nothing is to change return - cmd = f'ethtool -s {ifname}' + cmd = f'ethtool --change {ifname}' if speed == 'auto' or duplex == 'auto': cmd += ' autoneg on' else: -- cgit v1.2.3 From de3c476ccb60d66a844f9e12a9ca2963ae2206e6 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 31 Aug 2021 21:50:05 +0200 Subject: ethernet: T3163: only change ring-buffer settings if required Only update the RX/TX ring-buffer settings if they are different from the ones currently programmed to the hardware. There is no need to write the same value to the hardware again - this could cause traffic disruption on some NICs. (cherry picked from commit 29082959e0efc02462fba8560d6726096e8743e9) --- python/vyos/ethtool.py | 29 ++++++++++++++++++++++------- python/vyos/ifconfig/ethernet.py | 15 ++++++++++----- src/conf_mode/interfaces-ethernet.py | 4 ++-- 3 files changed, 34 insertions(+), 14 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index e803e28a1..f5796358d 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -43,6 +43,7 @@ class Ethtool: # } _speed_duplex = { } _ring_buffers = { } + _ring_buffers_max = { } _driver_name = None _auto_negotiation = None @@ -99,10 +100,20 @@ class Ethtool: 'fixed' : fixed } - out, err = popen(f'ethtool -g {ifname}') + out, err = popen(f'ethtool --show-ring {ifname}') # We are only interested in line 2-5 which contains the device maximum # ringbuffers for line in out.splitlines()[2:6]: + if ':' in line: + key, value = [s.strip() for s in line.strip().split(":", 1)] + key = key.lower().replace(' ', '_') + # T3645: ethtool version used on Debian Bullseye changed the + # output format from 0 -> n/a. As we are only interested in the + # tx/rx keys we do not care about RX Mini/Jumbo. + if value.isdigit(): + self._ring_buffers_max[key] = int(value) + # Now we wan't to get the current RX/TX ringbuffer values - used for + for line in out.splitlines()[7:11]: if ':' in line: key, value = [s.strip() for s in line.strip().split(":", 1)] key = key.lower().replace(' ', '_') @@ -143,15 +154,19 @@ class Ethtool: def get_tcp_segmentation_offload(self): return self._get_generic('tcp-segmentation-offload') - def get_rx_buffer(self): - # Configuration of RX ring-buffers is not supported on every device, + 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 - return self._ring_buffers.get('rx', None) + if rx_tx not in ['rx', 'tx']: + ValueError('Ring-buffer type must be either "rx" or "tx"') + return self._ring_buffers_max.get(rx_tx, None) - def get_tx_buffer(self): - # Configuration of TX ring-buffers is not supported on every device, + 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 - return self._ring_buffers.get('tx', None) + if rx_tx not in ['rx', 'tx']: + ValueError('Ring-buffer type must be either "rx" or "tx"') + return self._ring_buffers.get(rx_tx, None) def check_speed_duplex(self, speed, duplex): """ Check if the passed speed and duplex combination is supported by diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py index d6e42db99..5974a3d8f 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -317,21 +317,26 @@ class EthernetIf(Interface): print('Adapter does not support changing tcp-segmentation-offload settings!') return False - def set_ring_buffer(self, b_type, b_size): + def set_ring_buffer(self, rx_tx, size): """ Example: >>> from vyos.ifconfig import EthernetIf >>> i = EthernetIf('eth0') >>> i.set_ring_buffer('rx', '4096') """ + current_size = self.ethtool.get_ring_buffer(rx_tx) + if current_size == size: + # bail out early if nothing is about to change + return None + ifname = self.config['ifname'] - cmd = f'ethtool -G {ifname} {b_type} {b_size}' + cmd = f'ethtool --set-ring {ifname} {rx_tx} {size}' output, code = self._popen(cmd) # ethtool error codes: # 80 - value already setted # 81 - does not possible to set value if code and code != 80: - print(f'could not set "{b_type}" ring-buffer for {ifname}') + print(f'could not set "{rx_tx}" ring-buffer for {ifname}') return output def update(self, config): @@ -370,8 +375,8 @@ class EthernetIf(Interface): # Set interface ring buffer if 'ring_buffer' in config: - for b_type in config['ring_buffer']: - self.set_ring_buffer(b_type, config['ring_buffer'][b_type]) + for rx_tx, size in config['ring_buffer'].items(): + self.set_ring_buffer(rx_tx, size) # call base class first super().update(config) diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index 57e05d4ea..f3f3fede8 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -79,11 +79,11 @@ def verify(ethernet): f'settings to: {speed}/{duplex}!') if 'ring_buffer' in ethernet: - max_rx = ethtool.get_rx_buffer() + max_rx = ethtool.get_ring_buffer_max('rx') if not max_rx: raise ConfigError('Driver does not support RX ring-buffer configuration!') - max_tx = ethtool.get_tx_buffer() + max_tx = ethtool.get_ring_buffer_max('tx') if not max_tx: raise ConfigError('Driver does not support TX ring-buffer configuration!') -- cgit v1.2.3 From b0d4112bd6073e4a947869c3bd80f8e87783fbfa Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 31 Aug 2021 23:03:01 +0200 Subject: vyos.ethtool: T3163: purify code to read and change flow-control settings It makes no sense to have a parser for the ethtool values in ethtool.py and ethernet.py - one instance ios more then enough! (cherry picked from commit 0229645c8248decb5664056df8aa5cd5dff41802) --- python/vyos/ethtool.py | 23 +++++++++++++++++ python/vyos/ifconfig/ethernet.py | 42 ++++++++----------------------- src/conf_mode/interfaces-ethernet.py | 4 +++ src/migration-scripts/interfaces/20-to-21 | 8 ++++++ 4 files changed, 45 insertions(+), 32 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index f5796358d..87b9d7dd0 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -46,6 +46,8 @@ class Ethtool: _ring_buffers_max = { } _driver_name = None _auto_negotiation = None + _flow_control = None + _flow_control_enabled = None def __init__(self, ifname): # Get driver used for interface @@ -123,6 +125,15 @@ class Ethtool: if value.isdigit(): self._ring_buffers[key] = int(value) + # 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 --show-pause {ifname}') + if len(out.splitlines()) > 1: + self._flow_control = True + # read current flow control setting, this returns: + # ['Autonegotiate:', 'on'] + self._flow_control_enabled = out.splitlines()[1].split()[-1] + def _get_generic(self, feature): """ Generic method to read self._features and return a tuple for feature @@ -186,5 +197,17 @@ class Ethtool: return True return False + def check_flow_control(self): + """ Check if the NIC supports flow-control """ + if self._driver_name in ['vmxnet3', 'virtio_net', 'xen_netfront']: + return False + return self._flow_control + + def get_flow_control(self): + if self._flow_control_enabled == None: + raise ValueError('Interface does not support changing '\ + 'flow-control settings!') + return self._flow_control_enabled + def get_auto_negotiation(self): return self._auto_negotiation diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py index 5974a3d8f..cb07693c3 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -122,38 +122,16 @@ class EthernetIf(Interface): 'flow control settings!') return - # Get current flow control settings: - cmd = f'ethtool --show-pause {ifname}' - output, code = self._popen(cmd) - if code == 76: - # the interface does not support it - return '' - if code: - # never fail here as it prevent vyos to boot - print(f'unexpected return code {code} from {cmd}') - return '' - - # The above command returns - with tabs: - # - # Pause parameters for eth0: - # Autonegotiate: on - # RX: off - # TX: off - if re.search("Autonegotiate:\ton", output): - if enable == "on": - # flowcontrol is already enabled - no need to re-enable it again - # this will prevent the interface from flapping as applying the - # flow-control settings will take the interface down and bring - # it back up every time. - return '' - - # Assemble command executed on system. Unfortunately there is no way - # to change this setting via sysfs - cmd = f'ethtool --pause {ifname} autoneg {enable} tx {enable} rx {enable}' - output, code = self._popen(cmd) - if code: - print(f'could not set flowcontrol for {ifname}') - return output + current = self.ethtool.get_flow_control() + if current != enable: + # Assemble command executed on system. Unfortunately there is no way + # to change this setting via sysfs + cmd = f'ethtool --pause {ifname} autoneg {enable} tx {enable} rx {enable}' + output, code = self._popen(cmd) + if code: + print(f'Could not set flowcontrol for {ifname}') + return output + return None def set_speed_duplex(self, speed, duplex): """ diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index f3f3fede8..6e0d8c4e8 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -78,6 +78,10 @@ def verify(ethernet): raise ConfigError(f'Adapter does not support changing speed and duplex '\ f'settings to: {speed}/{duplex}!') + if 'disable_flow_control' in ethernet: + if not ethtool.check_flow_control(): + raise ConfigError('Adapter does not support changing flow-control settings!') + if 'ring_buffer' in ethernet: max_rx = ethtool.get_ring_buffer_max('rx') if not max_rx: diff --git a/src/migration-scripts/interfaces/20-to-21 b/src/migration-scripts/interfaces/20-to-21 index bd89dcdb4..0bd858760 100755 --- a/src/migration-scripts/interfaces/20-to-21 +++ b/src/migration-scripts/interfaces/20-to-21 @@ -104,6 +104,14 @@ for ifname in config.list_nodes(base): config.delete(speed_path) config.delete(duplex_path) + # Also while processing the interface configuration, not all adapters support + # changing disabling flow-control - or change this setting. If disabling + # flow-control is not supported by the NIC, we remove the setting from CLI + flow_control_path = base + [ifname, 'disable-flow-control'] + if config.exists(flow_control_path): + if not eth.check_flow_control(): + config.delete(flow_control_path) + try: with open(file_name, 'w') as f: f.write(config.to_string()) -- cgit v1.2.3 From f5f58669cccbb99ae2b8bc9737e9d6bb782a53a4 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 31 Aug 2021 23:31:29 +0200 Subject: vyos.ethtool: T3163: ring-buffer values should be stored as string Commit 29082959 ("ethernet: T3163: only change ring-buffer settings if required") added a delta-check code for the ring buffer values, unfortunately this was never properly evaluated as str() and int() got compared resulting always in an unequal result. (cherry picked from commit 6c280b1ca52c8f2a80bbaea52aa3e09060af04b3) --- python/vyos/ethtool.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 87b9d7dd0..609d83b5e 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -113,7 +113,7 @@ class Ethtool: # output format from 0 -> n/a. As we are only interested in the # tx/rx keys we do not care about RX Mini/Jumbo. if value.isdigit(): - self._ring_buffers_max[key] = int(value) + self._ring_buffers_max[key] = value # Now we wan't to get the current RX/TX ringbuffer values - used for for line in out.splitlines()[7:11]: if ':' in line: @@ -123,7 +123,7 @@ class Ethtool: # output format from 0 -> n/a. As we are only interested in the # tx/rx keys we do not care about RX Mini/Jumbo. if value.isdigit(): - self._ring_buffers[key] = int(value) + self._ring_buffers[key] = value # Get current flow control settings, but this is not supported by # all NICs (e.g. vmxnet3 does not support is) @@ -177,7 +177,7 @@ class Ethtool: # 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 self._ring_buffers.get(rx_tx, None) + return str(self._ring_buffers.get(rx_tx, None)) def check_speed_duplex(self, speed, duplex): """ Check if the passed speed and duplex combination is supported by -- cgit v1.2.3 From 1572edd2cef355710d1129907d3e49451a6c31d4 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 10 Sep 2021 16:45:30 +0200 Subject: ethernet: T3802: check if driver supports changing flow-control settings --- python/vyos/ethtool.py | 2 +- python/vyos/ifconfig/ethernet.py | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 609d83b5e..7e46969cf 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -46,7 +46,7 @@ class Ethtool: _ring_buffers_max = { } _driver_name = None _auto_negotiation = None - _flow_control = None + _flow_control = False _flow_control_enabled = None def __init__(self, ifname): diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py index cb07693c3..47d3b6b4d 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -116,11 +116,10 @@ class EthernetIf(Interface): if enable not in ['on', 'off']: raise ValueError("Value out of range") - driver_name = self.get_driver_name() - if driver_name in ['vmxnet3', 'virtio_net', 'xen_netfront']: + if not self.ethtool.check_flow_control(): self._debug_msg(f'{driver_name} driver does not support changing '\ 'flow control settings!') - return + return False current = self.ethtool.get_flow_control() if current != enable: -- cgit v1.2.3 From 07840977834816b69fa3b366817d90f44b5dc7a7 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 10 Sep 2021 16:46:55 +0200 Subject: ethernet: T3802: use only one implementation for get_driver_name() Move the two implementations to get the driver name of a NIC from ethernet.py and ethtool.py to only ethtool.py. --- python/vyos/ethtool.py | 13 ++++++++----- python/vyos/ifconfig/ethernet.py | 28 +++------------------------- src/conf_mode/interfaces-ethernet.py | 2 +- 3 files changed, 12 insertions(+), 31 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 7e46969cf..4efc3a234 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -134,6 +134,12 @@ class Ethtool: # ['Autonegotiate:', 'on'] self._flow_control_enabled = out.splitlines()[1].split()[-1] + def get_auto_negotiation(self): + return self._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 @@ -189,7 +195,7 @@ class Ethtool: if duplex not in ['full', 'half']: raise ValueError(f'Value "{duplex}" for duplex is invalid!') - if self._driver_name in ['vmxnet3', 'virtio_net', 'xen_netfront']: + if self.get_driver_name() in ['vmxnet3', 'virtio_net', 'xen_netfront']: return False if speed in self._speed_duplex: @@ -199,7 +205,7 @@ class Ethtool: def check_flow_control(self): """ Check if the NIC supports flow-control """ - if self._driver_name in ['vmxnet3', 'virtio_net', 'xen_netfront']: + if self.get_driver_name() in ['vmxnet3', 'virtio_net', 'xen_netfront']: return False return self._flow_control @@ -208,6 +214,3 @@ class Ethtool: raise ValueError('Interface does not support changing '\ 'flow-control settings!') return self._flow_control_enabled - - def get_auto_negotiation(self): - return self._auto_negotiation diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py index 47d3b6b4d..50e865203 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -81,25 +81,6 @@ class EthernetIf(Interface): super().__init__(ifname, **kargs) self.ethtool = Ethtool(ifname) - def get_driver_name(self): - """ - Return the driver name used by NIC. Some NICs don't support all - features e.g. changing link-speed, duplex - - Example: - >>> from vyos.ifconfig import EthernetIf - >>> i = EthernetIf('eth0') - >>> i.get_driver_name() - 'vmxnet3' - """ - ifname = self.config['ifname'] - sysfs_file = f'/sys/class/net/{ifname}/device/driver/module' - if os.path.exists(sysfs_file): - link = os.readlink(sysfs_file) - return os.path.basename(link) - else: - return None - def set_flow_control(self, enable): """ Changes the pause parameters of the specified Ethernet device. @@ -117,8 +98,7 @@ class EthernetIf(Interface): raise ValueError("Value out of range") if not self.ethtool.check_flow_control(): - self._debug_msg(f'{driver_name} driver does not support changing '\ - 'flow control settings!') + self._debug_msg(f'NIC driver does not support changing flow control settings!') return False current = self.ethtool.get_flow_control() @@ -152,10 +132,8 @@ class EthernetIf(Interface): if duplex not in ['auto', 'full', 'half']: raise ValueError("Value out of range (duplex)") - driver_name = self.get_driver_name() - if driver_name in ['vmxnet3', 'virtio_net', 'xen_netfront']: - self._debug_msg(f'{driver_name} driver does not support changing '\ - 'speed/duplex settings!') + if not self.ethtool.check_speed_duplex(speed, duplex): + self._debug_msg(f'NIC driver does not support changing speed/duplex settings!') return # Get current speed and duplex settings: diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py index 17f58b285..de851262b 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -113,7 +113,7 @@ def verify(ethernet): 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() + driver = ethtool.get_driver_name() # T3342 - Xen driver requires special treatment if driver == 'vif': if int(ethernet['mtu']) > 1500 and dict_search('offload.sg', ethernet) == None: -- cgit v1.2.3 From 3037661951d0e5d1f6264f886781b7ddc019329e Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 10 Sep 2021 16:56:32 +0200 Subject: ethtool: T3802: extend check_speed_duplex() implementation to support 'auto' --- python/vyos/ethtool.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 4efc3a234..bc95767b1 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -190,9 +190,9 @@ class Ethtool: the underlaying network adapter. """ if isinstance(speed, int): speed = str(speed) - if not speed.isdigit(): + if speed != 'auto' and not speed.isdigit(): raise ValueError(f'Value "{speed}" for speed is invalid!') - if duplex not in ['full', 'half']: + if duplex not in ['auto', 'full', 'half']: raise ValueError(f'Value "{duplex}" for duplex is invalid!') if self.get_driver_name() in ['vmxnet3', 'virtio_net', 'xen_netfront']: -- cgit v1.2.3 From 21499b23a1b711aafe9640b898d06b95c70988b9 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Thu, 30 Sep 2021 20:24:17 +0200 Subject: vyos.ethtool: T3874: do not throw exception if adapter has issues with autoneg Instead of throwing an exception when an adapters autoneg capabilities can not be detected, just pretend it does not support autoneg. (cherry picked from commit 0b414bcd2930a1469df0a747962f4650d0fb964b) --- python/vyos/ethtool.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index bc95767b1..eb5b0a456 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -45,7 +45,7 @@ class Ethtool: _ring_buffers = { } _ring_buffers_max = { } _driver_name = None - _auto_negotiation = None + _auto_negotiation = False _flow_control = False _flow_control_enabled = None @@ -84,10 +84,6 @@ class Ethtool: tmp = line.split()[-1] self._auto_negotiation = bool(tmp == 'on') - if self._auto_negotiation == None: - raise ValueError(f'Could not determine auto-negotiation settings '\ - f'for interface {ifname}!') - # Now populate features dictionaty out, err = popen(f'ethtool --show-features {ifname}') # skip the first line, it only says: "Features for eth0": -- cgit v1.2.3 From 8c8fe9b6f91d0a0b6c56b9e7a31b8f71dca75272 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 24 Oct 2021 21:27:28 +0200 Subject: vyos.ethtool: T3935: relax __init__() when driver name is not detected In addition to commit 0b414bcd ("vyos.ethtool: T3874: do not throw exception if adapter has issues with autoneg") we should also not care too strict when locating the driver name. This might cause false positives. (cherry picked from commit 8cf5a4f023c5459cad4c84e93f73a9ddd69be81a) --- python/vyos/ethtool.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index eb5b0a456..e45b0f041 100644 --- a/python/vyos/ethtool.py +++ b/python/vyos/ethtool.py @@ -56,9 +56,6 @@ class Ethtool: link = os.readlink(sysfs_file) self._driver_name = os.path.basename(link) - if not self._driver_name: - raise ValueError(f'Could not determine driver for interface {ifname}!') - # Build a dictinary of supported link-speed and dupley settings. out, err = popen(f'ethtool {ifname}') reading = False -- cgit v1.2.3