summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/lldp/lldpd.j22
-rw-r--r--interface-definitions/include/version/lldp-version.xml.i2
-rw-r--r--interface-definitions/lldp.xml.in15
-rw-r--r--python/vyos/ethtool.py34
-rw-r--r--python/vyos/ifconfig/ethernet.py31
-rw-r--r--smoketest/configs/ospf-small3
-rwxr-xr-xsmoketest/scripts/cli/test_service_lldp.py16
-rwxr-xr-xsrc/conf_mode/lldp.py5
-rwxr-xr-xsrc/conf_mode/snmp.py2
-rwxr-xr-xsrc/migration-scripts/lldp/0-to-114
-rwxr-xr-xsrc/migration-scripts/lldp/1-to-248
11 files changed, 149 insertions, 23 deletions
diff --git a/data/templates/lldp/lldpd.j2 b/data/templates/lldp/lldpd.j2
index 3c499197d..6ae063c4b 100644
--- a/data/templates/lldp/lldpd.j2
+++ b/data/templates/lldp/lldpd.j2
@@ -1,2 +1,2 @@
### Autogenerated by lldp.py ###
-DAEMON_ARGS="-M 4 {{ '-x' if snmp.enable is vyos_defined }} {{ '-c' if legacy_protocols.cdp is vyos_defined }} {{ '-e' if legacy_protocols.edp is vyos_defined }} {{ '-f' if legacy_protocols.fdp is vyos_defined }} {{ '-s' if legacy_protocols.sonmp is vyos_defined }}"
+DAEMON_ARGS="-M 4 {{ '-x' if snmp is vyos_defined }} {{ '-c' if legacy_protocols.cdp is vyos_defined }} {{ '-e' if legacy_protocols.edp is vyos_defined }} {{ '-f' if legacy_protocols.fdp is vyos_defined }} {{ '-s' if legacy_protocols.sonmp is vyos_defined }}"
diff --git a/interface-definitions/include/version/lldp-version.xml.i b/interface-definitions/include/version/lldp-version.xml.i
index 0deb73279..b41d80451 100644
--- a/interface-definitions/include/version/lldp-version.xml.i
+++ b/interface-definitions/include/version/lldp-version.xml.i
@@ -1,3 +1,3 @@
<!-- include start from include/version/lldp-version.xml.i -->
-<syntaxVersion component='lldp' version='1'></syntaxVersion>
+<syntaxVersion component='lldp' version='2'></syntaxVersion>
<!-- include end -->
diff --git a/interface-definitions/lldp.xml.in b/interface-definitions/lldp.xml.in
index 738bb11c1..25fb575b6 100644
--- a/interface-definitions/lldp.xml.in
+++ b/interface-definitions/lldp.xml.in
@@ -175,19 +175,12 @@
<multi/>
</properties>
</leafNode>
- <node name="snmp">
+ <leafNode name="snmp">
<properties>
- <help>SNMP parameters for LLDP</help>
+ <help>Enable SNMP queries of the LLDP database</help>
+ <valueless/>
</properties>
- <children>
- <leafNode name="enable">
- <properties>
- <help>Enable SNMP queries of the LLDP database</help>
- <valueless/>
- </properties>
- </leafNode>
- </children>
- </node>
+ </leafNode>
</children>
</node>
</children>
diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py
index f19632719..ba638b280 100644
--- a/python/vyos/ethtool.py
+++ b/python/vyos/ethtool.py
@@ -23,6 +23,7 @@ from vyos.utils.process import popen
_drivers_without_speed_duplex_flow = ['vmxnet3', 'virtio_net', 'xen_netfront',
'iavf', 'ice', 'i40e', 'hv_netvsc', 'veth', 'ixgbevf',
'tun']
+_drivers_without_eee = ['vmxnet3', 'virtio_net', 'xen_netfront', 'hv_netvsc']
class Ethtool:
"""
@@ -55,16 +56,18 @@ class Ethtool:
_auto_negotiation_supported = None
_flow_control = False
_flow_control_enabled = None
+ _eee = False
+ _eee_enabled = None
def __init__(self, ifname):
# Get driver used for interface
- out, err = popen(f'ethtool --driver {ifname}')
+ out, _ = popen(f'ethtool --driver {ifname}')
driver = re.search(r'driver:\s(\w+)', out)
if driver:
self._driver_name = driver.group(1)
# Build a dictinary of supported link-speed and dupley settings.
- out, err = popen(f'ethtool {ifname}')
+ out, _ = popen(f'ethtool {ifname}')
reading = False
pattern = re.compile(r'\d+base.*')
for line in out.splitlines()[1:]:
@@ -95,7 +98,7 @@ class Ethtool:
self._auto_negotiation = bool(tmp == 'on')
# Now populate features dictionaty
- out, err = popen(f'ethtool --show-features {ifname}')
+ out, _ = 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:
@@ -108,7 +111,7 @@ class Ethtool:
'fixed' : fixed
}
- out, err = popen(f'ethtool --show-ring {ifname}')
+ out, _ = 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]:
@@ -133,13 +136,22 @@ class Ethtool:
# 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}')
+ out, _ = 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]
+ # Get current Energy Efficient Ethernet (EEE) settings, but this is
+ # not supported by all NICs (e.g. vmxnet3 does not support is)
+ out, _ = popen(f'ethtool --show-eee {ifname}')
+ if len(out.splitlines()) > 1:
+ self._eee = True
+ # read current EEE setting, this returns:
+ # EEE status: disabled || EEE status: enabled - inactive || EEE status: enabled - active
+ self._eee_enabled = bool('enabled' in out.splitlines()[2])
+
def check_auto_negotiation_supported(self):
""" Check if the NIC supports changing auto-negotiation """
return self._auto_negotiation_supported
@@ -227,3 +239,15 @@ class Ethtool:
raise ValueError('Interface does not support changing '\
'flow-control settings!')
return self._flow_control_enabled
+
+ def check_eee(self):
+ """ Check if the NIC supports eee """
+ if self.get_driver_name() in _drivers_without_eee:
+ return False
+ return self._eee
+
+ def get_eee(self):
+ if self._eee_enabled == None:
+ raise ValueError('Interface does not support changing '\
+ 'EEE settings!')
+ return self._eee_enabled
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index aa1e87744..aaf903acd 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -399,6 +399,34 @@ class EthernetIf(Interface):
print(f'could not set "{rx_tx}" ring-buffer for {ifname}')
return output
+ def set_eee(self, enable):
+ """
+ Enable/Disable Energy Efficient Ethernet (EEE) settings
+
+ Example:
+ >>> from vyos.ifconfig import EthernetIf
+ >>> i = EthernetIf('eth0')
+ >>> i.set_eee(enable=False)
+ """
+ if not isinstance(enable, bool):
+ raise ValueError('Value out of range')
+
+ if not self.ethtool.check_eee():
+ self._debug_msg(f'NIC driver does not support changing EEE settings!')
+ return False
+
+ current = self.ethtool.get_eee()
+ if current != enable:
+ # Assemble command executed on system. Unfortunately there is no way
+ # to change this setting via sysfs
+ cmd = f'ethtool --set-eee {self.ifname} eee '
+ cmd += 'on' if enable else 'off'
+ output, code = self._popen(cmd)
+ if code:
+ Warning(f'could not change "{self.ifname}" EEE setting!')
+ return output
+ return None
+
def update(self, config):
""" General helper function which works on a dictionary retrived by
get_config_dict(). It's main intention is to consolidate the scattered
@@ -409,6 +437,9 @@ class EthernetIf(Interface):
value = 'off' if 'disable_flow_control' in config else 'on'
self.set_flow_control(value)
+ # Always disable Energy Efficient Ethernet
+ self.set_eee(False)
+
# GRO (generic receive offload)
self.set_gro(dict_search('offload.gro', config) != None)
diff --git a/smoketest/configs/ospf-small b/smoketest/configs/ospf-small
index 767f4e21f..b3002b1af 100644
--- a/smoketest/configs/ospf-small
+++ b/smoketest/configs/ospf-small
@@ -81,6 +81,9 @@ service {
lldp {
interface all {
}
+ snmp {
+ enable
+ }
}
snmp {
community public {
diff --git a/smoketest/scripts/cli/test_service_lldp.py b/smoketest/scripts/cli/test_service_lldp.py
index ee26844ab..7e30b43f5 100755
--- a/smoketest/scripts/cli/test_service_lldp.py
+++ b/smoketest/scripts/cli/test_service_lldp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2022-2023 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -122,6 +122,20 @@ class TestServiceLLDP(VyOSUnitTestSHIM.TestCase):
self.assertIn(f'configure ports {interface} med location elin "{elin}"', config)
self.assertIn(f'configure system interface pattern "{interface}"', config)
+ def test_06_lldp_snmp(self):
+ self.cli_set(base_path + ['snmp'])
+
+ # verify - can not start lldp snmp without snmp beeing configured
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(['service', 'snmp'])
+ self.cli_commit()
+
+ # SNMP required process to be started with -x option
+ tmp = read_file('/etc/default/lldpd')
+ self.assertIn('-x', tmp)
+
+ self.cli_delete(['service', 'snmp'])
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/conf_mode/lldp.py b/src/conf_mode/lldp.py
index c2e87d171..3c647a0e8 100755
--- a/src/conf_mode/lldp.py
+++ b/src/conf_mode/lldp.py
@@ -86,9 +86,9 @@ def verify(lldp):
raise ConfigError(f'Must define both longitude and latitude for "{interface}" location!')
# check options
- if 'snmp' in lldp and 'enable' in lldp['snmp']:
+ if 'snmp' in lldp:
if 'system_snmp_enabled' not in lldp:
- raise ConfigError('SNMP must be configured to enable LLDP SNMP')
+ raise ConfigError('SNMP must be configured to enable LLDP SNMP!')
def generate(lldp):
@@ -121,4 +121,3 @@ if __name__ == '__main__':
except ConfigError as e:
print(e)
exit(1)
-
diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py
index f1d41f23d..6565ffd60 100755
--- a/src/conf_mode/snmp.py
+++ b/src/conf_mode/snmp.py
@@ -54,7 +54,7 @@ def get_config(config=None):
if not conf.exists(base):
snmp.update({'deleted' : ''})
- if conf.exists(['service', 'lldp', 'snmp', 'enable']):
+ if conf.exists(['service', 'lldp', 'snmp']):
snmp.update({'lldp_snmp' : ''})
if 'deleted' in snmp:
diff --git a/src/migration-scripts/lldp/0-to-1 b/src/migration-scripts/lldp/0-to-1
index a936cbdfc..a99356062 100755
--- a/src/migration-scripts/lldp/0-to-1
+++ b/src/migration-scripts/lldp/0-to-1
@@ -1,4 +1,18 @@
#!/usr/bin/env python3
+#
+# Copyright (C) 2020 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Delete "set service lldp interface <interface> location civic-based" option
# as it was broken most of the time anyways
diff --git a/src/migration-scripts/lldp/1-to-2 b/src/migration-scripts/lldp/1-to-2
new file mode 100755
index 000000000..35efb25db
--- /dev/null
+++ b/src/migration-scripts/lldp/1-to-2
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# T5855: migrate "set service lldp snmp enable" -> `set service lldp snmp"
+
+import sys
+
+from vyos.configtree import ConfigTree
+
+if len(sys.argv) < 2:
+ print("Must specify file name!")
+ sys.exit(1)
+
+file_name = sys.argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+config = ConfigTree(config_file)
+base = ['service', 'lldp']
+if not config.exists(base):
+ # Nothing to do
+ sys.exit(0)
+
+if config.exists(base + ['snmp']):
+ enabled = config.exists(base + ['snmp', 'enable'])
+ config.delete(base + ['snmp'])
+ if enabled: config.set(base + ['snmp'])
+
+try:
+ with open(file_name, 'w') as f:
+ f.write(config.to_string())
+except OSError as e:
+ print("Failed to save the modified config: {}".format(e))
+ sys.exit(1)