summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/vyos/ethtool.py75
1 files changed, 57 insertions, 18 deletions
diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py
index 0ae526346..8add1a327 100644
--- a/python/vyos/ethtool.py
+++ b/python/vyos/ethtool.py
@@ -13,13 +13,13 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+import re
from vyos.util import popen
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,10 +32,38 @@ class Ethtool:
# 'tx-checksumming': {'fixed': False, 'enabled': True},
# 'tx-esp-segmentation': {'fixed': True, 'enabled': False},
# }
- features = { }
- ring_buffers = { }
+ _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":
@@ -45,7 +73,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,27 +89,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)
-
- 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)
+ 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):
@@ -108,9 +131,25 @@ 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)
+
+ 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
+