From d22f97af23abb5c12f8ea79c50fdda7ee0a3832d 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 --- 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 eac8915413cedce089234fdbef57ad25da208eec 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. --- 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 324aa9598c7d90efc917a00447380f985553b657 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 _ --- 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 147f655a69cd9526cd23f51ab18027cb5abc95b2 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 --- python/vyos/ethtool.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 25a116d09..8add1a327 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,19 @@ 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 50364a4b7a9de85fe59a6a4fb611bafb64c9f7f0 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() --- 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 8add1a327..98985e972 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 705022319916222d78082114245c7639c073bd32 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."). (cherry picked from commit f5e46ee6cc2b6c1c1869e26beca4ccd5bf52b62f) --- 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 ca076e3fa..ceeda12a0 100644 --- a/interface-definitions/interfaces-ethernet.xml.in +++ b/interface-definitions/interfaces-ethernet.xml.in @@ -104,12 +104,6 @@ - - - Enable UDP Fragmentation Offloading - - - diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 98985e972..5a5d84bed 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 696fec03b..7d29da8fc 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -71,11 +71,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, **{ @@ -338,26 +333,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: @@ -403,9 +378,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 a086dc2c429aea9614ac7a9c735c6475c2d6da59 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. --- 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 fc79f44bf..6d50d6e90 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 5a5d84bed..7dcb68346 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 7d29da8fc..76ed3fd92 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -42,34 +42,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 cc742d48579e4f76e5d3230d87e22f71f76f9301 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. --- 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 7dcb68346..968e2e2a3 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 27c4a7c38..889f4856f 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -85,7 +85,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 6f5fb5c503b5df96d0686002355da3633b1fc597 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! --- python/vyos/ethtool.py | 13 ++++++++++++- python/vyos/ifconfig/ethernet.py | 22 +++++----------------- 2 files changed, 17 insertions(+), 18 deletions(-) (limited to 'python/vyos/ethtool.py') diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py index 968e2e2a3..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}') @@ -162,3 +171,5 @@ class Ethtool: 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 76ed3fd92..d4fa3f655 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 @@ -181,32 +182,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 29082959e0efc02462fba8560d6726096e8743e9 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. --- 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 d4fa3f655..e5da3ac25 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -316,21 +316,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): @@ -369,8 +374,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 889f4856f..f604f787c 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -89,11 +89,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 0229645c8248decb5664056df8aa5cd5dff41802 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! --- 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 e5da3ac25..7bd269491 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -121,38 +121,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 f604f787c..81ed36bf2 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -88,6 +88,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 6c280b1ca52c8f2a80bbaea52aa3e09060af04b3 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. --- 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 cc313b32ef26141c2c027e8543f78da1231cada2 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 (cherry picked from commit 1572edd2cef355710d1129907d3e49451a6c31d4) --- 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 7bd269491..c4dfc7198 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -115,11 +115,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 2abf6711e880463b9d9276b2fa9ea7b4ebcdc179 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. (cherry picked from commit 07840977834816b69fa3b366817d90f44b5dc7a7) --- 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 c4dfc7198..78fec1fa2 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -80,25 +80,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. @@ -116,8 +97,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() @@ -151,10 +131,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 21a04f954..e7250fb49 100755 --- a/src/conf_mode/interfaces-ethernet.py +++ b/src/conf_mode/interfaces-ethernet.py @@ -126,7 +126,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 e626407f4c246941eb2ca1b167a4b594b7bf6461 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' (cherry picked from commit 3037661951d0e5d1f6264f886781b7ddc019329e) --- 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 0b414bcd2930a1469df0a747962f4650d0fb964b 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. --- 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