summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-definitions/include/ospfv3/protocol-common-config.xml.i10
-rw-r--r--python/vyos/ethtool.py78
-rw-r--r--python/vyos/nat.py11
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_ethernet.py27
-rwxr-xr-xsmoketest/scripts/cli/test_nat.py17
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospf.py4
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospfv3.py2
-rwxr-xr-xsrc/conf_mode/protocols_ospfv3.py2
8 files changed, 95 insertions, 56 deletions
diff --git a/interface-definitions/include/ospfv3/protocol-common-config.xml.i b/interface-definitions/include/ospfv3/protocol-common-config.xml.i
index 1462b9c15..72fb86d3d 100644
--- a/interface-definitions/include/ospfv3/protocol-common-config.xml.i
+++ b/interface-definitions/include/ospfv3/protocol-common-config.xml.i
@@ -251,6 +251,16 @@
#include <include/route-map.xml.i>
</children>
</node>
+ <node name="isis">
+ <properties>
+ <help>Redistribute IS-IS routes</help>
+ </properties>
+ <children>
+ #include <include/ospf/metric.xml.i>
+ #include <include/ospf/metric-type.xml.i>
+ #include <include/route-map.xml.i>
+ </children>
+ </node>
<node name="kernel">
<properties>
<help>Redistribute kernel routes</help>
diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py
index 18d66b84b..473c98d0c 100644
--- a/python/vyos/ethtool.py
+++ b/python/vyos/ethtool.py
@@ -32,16 +32,24 @@ class Ethtool:
"""
# dictionary containing driver featurs, it will be populated on demand and
# the content will look like:
- # {
- # '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},
- # }
+ # [{'esp-hw-offload': {'active': False, 'fixed': True, 'requested': False},
+ # 'esp-tx-csum-hw-offload': {'active': False,
+ # 'fixed': True,
+ # 'requested': False},
+ # 'fcoe-mtu': {'active': False, 'fixed': True, 'requested': False},
+ # 'generic-receive-offload': {'active': True,
+ # 'fixed': False,
+ # 'requested': True},
+ # 'generic-segmentation-offload': {'active': True,
+ # 'fixed': False,
+ # 'requested': True},
+ # 'highdma': {'active': True, 'fixed': False, 'requested': True},
+ # 'ifname': 'eth0',
+ # 'l2-fwd-offload': {'active': False, 'fixed': True, 'requested': False},
+ # 'large-receive-offload': {'active': False,
+ # 'fixed': False,
+ # 'requested': False},
+ # ...
_features = { }
# dictionary containing available interface speed and duplex settings
# {
@@ -54,8 +62,7 @@ class Ethtool:
_driver_name = None
_auto_negotiation = False
_auto_negotiation_supported = None
- _flow_control = False
- _flow_control_enabled = None
+ _flow_control = None
_eee = False
_eee_enabled = None
@@ -97,31 +104,19 @@ class Ethtool:
tmp = line.split()[-1]
self._auto_negotiation = bool(tmp == 'on')
- # Now populate features dictionaty
- 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:
- key, value = [s.strip() for s in line.strip().split(":", 1)]
- fixed = bool('fixed' in value)
- if fixed:
- value = value.split()[0].strip()
- self._features[key.strip()] = {
- 'enabled' : bool(value == 'on'),
- 'fixed' : fixed
- }
+ # Now populate driver features
+ out, _ = popen(f'ethtool --json --show-features {ifname}')
+ self._features = loads(out)
+ # Get information about NIC ring buffers
out, _ = popen(f'ethtool --json --show-ring {ifname}')
self._ring_buffer = loads(out)
# Get current flow control settings, but this is not supported by
# all NICs (e.g. vmxnet3 does not support is)
- 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]
+ out, err = popen(f'ethtool --json --show-pause {ifname}')
+ if not bool(err):
+ self._flow_control = loads(out)
# Get current Energy Efficient Ethernet (EEE) settings, but this is
# not supported by all NICs (e.g. vmxnet3 does not support is)
@@ -149,14 +144,12 @@ class Ethtool:
In case of a missing key, return "fixed = True and enabled = False"
"""
+ active = 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
+ if feature in self._features[0]:
+ active = bool(self._features[0][feature]['active'])
+ fixed = bool(self._features[0][feature]['fixed'])
+ return active, fixed
def get_generic_receive_offload(self):
return self._get_generic('generic-receive-offload')
@@ -210,15 +203,14 @@ class Ethtool:
def check_flow_control(self):
""" Check if the NIC supports flow-control """
- if self.get_driver_name() in _drivers_without_speed_duplex_flow:
- return False
- return self._flow_control
+ return bool(self._flow_control)
def get_flow_control(self):
- if self._flow_control_enabled == None:
+ if self._flow_control == None:
raise ValueError('Interface does not support changing '\
'flow-control settings!')
- return self._flow_control_enabled
+
+ return 'on' if bool(self._flow_control[0]['autonegotiate']) else 'off'
def check_eee(self):
""" Check if the NIC supports eee """
diff --git a/python/vyos/nat.py b/python/vyos/nat.py
index 7215aac88..da2613b16 100644
--- a/python/vyos/nat.py
+++ b/python/vyos/nat.py
@@ -89,11 +89,14 @@ def parse_nat_rule(rule_conf, rule_id, nat_type, ipv6=False):
if addr and is_ip_network(addr):
if not ipv6:
map_addr = dict_search_args(rule_conf, nat_type, 'address')
- if port:
- translation_output.append(f'{ip_prefix} prefix to {ip_prefix} {translation_prefix}addr map {{ {map_addr} : {addr} . {port} }}')
+ if map_addr:
+ if port:
+ translation_output.append(f'{ip_prefix} prefix to {ip_prefix} {translation_prefix}addr map {{ {map_addr} : {addr} . {port} }}')
+ else:
+ translation_output.append(f'{ip_prefix} prefix to {ip_prefix} {translation_prefix}addr map {{ {map_addr} : {addr} }}')
+ ignore_type_addr = True
else:
- translation_output.append(f'{ip_prefix} prefix to {ip_prefix} {translation_prefix}addr map {{ {map_addr} : {addr} }}')
- ignore_type_addr = True
+ translation_output.append(f'prefix to {addr}')
else:
translation_output.append(f'prefix to {addr}')
elif addr == 'masquerade':
diff --git a/smoketest/scripts/cli/test_interfaces_ethernet.py b/smoketest/scripts/cli/test_interfaces_ethernet.py
index 9bf6a1a61..8f387b23d 100755
--- a/smoketest/scripts/cli/test_interfaces_ethernet.py
+++ b/smoketest/scripts/cli/test_interfaces_ethernet.py
@@ -31,6 +31,7 @@ from vyos.ifconfig import Section
from vyos.pki import CERT_BEGIN
from vyos.utils.process import cmd
from vyos.utils.process import process_named_running
+from vyos.utils.process import popen
from vyos.utils.file import read_file
from vyos.utils.network import is_ipv6_link_local
@@ -304,6 +305,8 @@ class EthernetInterfaceTest(BasicInterfaceTest.TestCase):
def test_ethtool_ring_buffer(self):
for interface in self._interfaces:
+ # We do not use vyos.ethtool here to not have any chance
+ # for invalid testcases. Re-gain data by hand
tmp = cmd(f'sudo ethtool --json --show-ring {interface}')
tmp = loads(tmp)
max_rx = str(tmp[0]['rx-max'])
@@ -327,5 +330,29 @@ class EthernetInterfaceTest(BasicInterfaceTest.TestCase):
self.assertEqual(max_rx, rx)
self.assertEqual(max_tx, tx)
+ def test_ethtool_flow_control(self):
+ for interface in self._interfaces:
+ # Disable flow-control
+ self.cli_set(self._base_path + [interface, 'disable-flow-control'])
+ # Check current flow-control state on ethernet interface
+ out, err = popen(f'sudo ethtool --json --show-pause {interface}')
+ # Flow-control not supported - test if it bails out with a proper
+ # this is a dynamic path where err = 1 on VMware, but err = 0 on
+ # a physical box.
+ if bool(err):
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ else:
+ out = loads(out)
+ # Flow control is on
+ self.assertTrue(out[0]['autonegotiate'])
+
+ # commit change on CLI to disable-flow-control and re-test
+ self.cli_commit()
+
+ out, err = popen(f'sudo ethtool --json --show-pause {interface}')
+ out = loads(out)
+ self.assertFalse(out[0]['autonegotiate'])
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_nat.py b/smoketest/scripts/cli/test_nat.py
index 4f1c3cb4f..43e374398 100755
--- a/smoketest/scripts/cli/test_nat.py
+++ b/smoketest/scripts/cli/test_nat.py
@@ -87,21 +87,28 @@ class TestNAT(VyOSUnitTestSHIM.TestCase):
address_group_member = '192.0.2.1'
interface_group = 'smoketest_ifaces'
interface_group_member = 'bond.99'
- rule = '100'
self.cli_set(['firewall', 'group', 'address-group', address_group, 'address', address_group_member])
self.cli_set(['firewall', 'group', 'interface-group', interface_group, 'interface', interface_group_member])
- self.cli_set(src_path + ['rule', rule, 'source', 'group', 'address-group', address_group])
- self.cli_set(src_path + ['rule', rule, 'outbound-interface', 'group', interface_group])
- self.cli_set(src_path + ['rule', rule, 'translation', 'address', 'masquerade'])
+ self.cli_set(src_path + ['rule', '100', 'source', 'group', 'address-group', address_group])
+ self.cli_set(src_path + ['rule', '100', 'outbound-interface', 'group', interface_group])
+ self.cli_set(src_path + ['rule', '100', 'translation', 'address', 'masquerade'])
+
+ self.cli_set(src_path + ['rule', '110', 'source', 'group', 'address-group', address_group])
+ self.cli_set(src_path + ['rule', '110', 'translation', 'address', '203.0.113.1'])
+
+ self.cli_set(src_path + ['rule', '120', 'source', 'group', 'address-group', address_group])
+ self.cli_set(src_path + ['rule', '120', 'translation', 'address', '203.0.113.111/32'])
self.cli_commit()
nftables_search = [
[f'set A_{address_group}'],
[f'elements = {{ {address_group_member} }}'],
- [f'ip saddr @A_{address_group}', f'oifname @I_{interface_group}', 'masquerade']
+ [f'ip saddr @A_{address_group}', f'oifname @I_{interface_group}', 'masquerade'],
+ [f'ip saddr @A_{address_group}', 'snat to 203.0.113.1'],
+ [f'ip saddr @A_{address_group}', 'snat prefix to 203.0.113.111/32']
]
self.verify_nftables(nftables_search, 'ip vyos_nat')
diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py
index 6bffc7c45..82fb96754 100755
--- a/smoketest/scripts/cli/test_protocols_ospf.py
+++ b/smoketest/scripts/cli/test_protocols_ospf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2023 VyOS maintainers and contributors
+# Copyright (C) 2021-2024 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
@@ -240,7 +240,7 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
def test_ospf_07_redistribute(self):
metric = '15'
metric_type = '1'
- redistribute = ['bgp', 'connected', 'isis', 'kernel', 'rip', 'static']
+ redistribute = ['babel', 'bgp', 'connected', 'isis', 'kernel', 'rip', 'static']
for protocol in redistribute:
self.cli_set(base_path + ['redistribute', protocol, 'metric', metric])
diff --git a/smoketest/scripts/cli/test_protocols_ospfv3.py b/smoketest/scripts/cli/test_protocols_ospfv3.py
index a9894009d..989e1552d 100755
--- a/smoketest/scripts/cli/test_protocols_ospfv3.py
+++ b/smoketest/scripts/cli/test_protocols_ospfv3.py
@@ -118,7 +118,7 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
metric_type = '1'
route_map = 'foo-bar'
route_map_seq = '10'
- redistribute = ['bgp', 'connected', 'kernel', 'ripng', 'static']
+ redistribute = ['babel', 'bgp', 'connected', 'isis', 'kernel', 'ripng', 'static']
self.cli_set(['policy', 'route-map', route_map, 'rule', route_map_seq, 'action', 'permit'])
diff --git a/src/conf_mode/protocols_ospfv3.py b/src/conf_mode/protocols_ospfv3.py
index 2c1cbfecd..afd767dbf 100755
--- a/src/conf_mode/protocols_ospfv3.py
+++ b/src/conf_mode/protocols_ospfv3.py
@@ -85,7 +85,7 @@ def get_config(config=None):
if 'graceful_restart' not in ospfv3:
del default_values['graceful_restart']
- for protocol in ['babel', 'bgp', 'connected', 'kernel', 'ripng', 'static']:
+ for protocol in ['babel', 'bgp', 'connected', 'isis', 'kernel', 'ripng', 'static']:
if dict_search(f'redistribute.{protocol}', ospfv3) is None:
del default_values['redistribute'][protocol]
if not bool(default_values['redistribute']):