summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-definitions/interfaces-geneve.xml.in25
-rw-r--r--python/vyos/ifconfig/geneve.py26
-rw-r--r--python/vyos/ifconfig/vxlan.py3
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_geneve.py46
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_vxlan.py31
-rwxr-xr-xsrc/op_mode/show_interfaces.py5
6 files changed, 124 insertions, 12 deletions
diff --git a/interface-definitions/interfaces-geneve.xml.in b/interface-definitions/interfaces-geneve.xml.in
index 5894f580c..25308c8ef 100644
--- a/interface-definitions/interfaces-geneve.xml.in
+++ b/interface-definitions/interfaces-geneve.xml.in
@@ -23,6 +23,31 @@
#include <include/interface-ipv6-options.xml.i>
#include <include/interface-mac.xml.i>
#include <include/interface-mtu-1450-16000.xml.i>
+ <node name="parameters">
+ <properties>
+ <help>GENEVE tunnel parameters</help>
+ </properties>
+ <children>
+ <node name="ip">
+ <properties>
+ <help>IPv4 specific tunnel parameters</help>
+ </properties>
+ <children>
+ #include <include/interface-parameters-dont-fragment.xml.i>
+ #include <include/interface-parameters-tos.xml.i>
+ #include <include/interface-parameters-ttl.xml.i>
+ </children>
+ </node>
+ <node name="ipv6">
+ <properties>
+ <help>IPv6 specific tunnel parameters</help>
+ </properties>
+ <children>
+ #include <include/interface-parameters-flowlabel.xml.i>
+ </children>
+ </node>
+ </children>
+ </node>
#include <include/tunnel-remote.xml.i>
#include <include/vni.xml.i>
</children>
diff --git a/python/vyos/ifconfig/geneve.py b/python/vyos/ifconfig/geneve.py
index 6747d2bd6..7cb3968df 100644
--- a/python/vyos/ifconfig/geneve.py
+++ b/python/vyos/ifconfig/geneve.py
@@ -13,7 +13,8 @@
# 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/>.
-from vyos.ifconfig.interface import Interface
+from vyos.ifconfig import Interface
+from vyos.util import dict_search
@Interface.register
class GeneveIf(Interface):
@@ -37,8 +38,27 @@ class GeneveIf(Interface):
}
def _create(self):
- cmd = 'ip link add name {ifname} type geneve id {vni} remote {remote}'.format(**self.config)
- self._cmd(cmd)
+ # This table represents a mapping from VyOS internal config dict to
+ # arguments used by iproute2. For more information please refer to:
+ # - https://man7.org/linux/man-pages/man8/ip-link.8.html
+ mapping = {
+ 'parameters.ip.dont_fragment': 'df set',
+ 'parameters.ip.tos' : 'tos',
+ 'parameters.ip.ttl' : 'ttl',
+ 'parameters.ipv6.flowlabel' : 'flowlabel',
+ }
+
+ cmd = 'ip link add name {ifname} type {type} id {vni} remote {remote}'
+ for vyos_key, iproute2_key in mapping.items():
+ # dict_search will return an empty dict "{}" for valueless nodes like
+ # "parameters.nolearning" - thus we need to test the nodes existence
+ # by using isinstance()
+ tmp = dict_search(vyos_key, self.config)
+ if isinstance(tmp, dict):
+ cmd += f' {iproute2_key}'
+ elif tmp != None:
+ cmd += f' {iproute2_key} {tmp}'
+ self._cmd(cmd.format(**self.config))
# interface is always A/D down. It needs to be enabled explicitly
self.set_admin_state('down')
diff --git a/python/vyos/ifconfig/vxlan.py b/python/vyos/ifconfig/vxlan.py
index 6556aff5a..d73fb47b8 100644
--- a/python/vyos/ifconfig/vxlan.py
+++ b/python/vyos/ifconfig/vxlan.py
@@ -14,7 +14,7 @@
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
from vyos import ConfigError
-from vyos.ifconfig.interface import Interface
+from vyos.ifconfig import Interface
from vyos.util import dict_search
@Interface.register
@@ -77,4 +77,5 @@ class VXLANIf(Interface):
cmd += f' {iproute2_key} {tmp}'
self._cmd(cmd.format(**self.config))
+ # interface is always A/D down. It needs to be enabled explicitly
self.set_admin_state('down')
diff --git a/smoketest/scripts/cli/test_interfaces_geneve.py b/smoketest/scripts/cli/test_interfaces_geneve.py
index b708b5437..e31867900 100755
--- a/smoketest/scripts/cli/test_interfaces_geneve.py
+++ b/smoketest/scripts/cli/test_interfaces_geneve.py
@@ -17,6 +17,9 @@
import unittest
from vyos.configsession import ConfigSession
+from vyos.ifconfig import Interface
+from vyos.util import get_json_iface_options
+
from base_interfaces_test import BasicInterfaceTest
class GeneveInterfaceTest(BasicInterfaceTest.BaseTest):
@@ -28,8 +31,51 @@ class GeneveInterfaceTest(BasicInterfaceTest.BaseTest):
cls._options = {
'gnv0': ['vni 10', 'remote 127.0.1.1'],
'gnv1': ['vni 20', 'remote 127.0.1.2'],
+ 'gnv1': ['vni 30', 'remote 2001:db8::1', 'parameters ipv6 flowlabel 0x1000'],
}
cls._interfaces = list(cls._options)
+ def test_geneve_parameters(self):
+ tos = '40'
+ ttl = 20
+ for intf in self._interfaces:
+ for option in self._options.get(intf, []):
+ self.session.set(self._base_path + [intf] + option.split())
+
+ self.session.set(self._base_path + [intf, 'parameters', 'ip', 'dont-fragment'])
+ self.session.set(self._base_path + [intf, 'parameters', 'ip', 'tos', tos])
+ self.session.set(self._base_path + [intf, 'parameters', 'ip', 'ttl', str(ttl)])
+ ttl += 10
+
+ self.session.commit()
+
+ ttl = 20
+ for interface in self._interfaces:
+ options = get_json_iface_options(interface)
+ import pprint
+ pprint.pprint(options)
+
+ vni = options['linkinfo']['info_data']['id']
+ self.assertIn(f'vni {vni}', self._options[interface])
+
+ if any('remote' in s for s in self._options[interface]):
+ key = 'remote'
+ if 'remote6' in options['linkinfo']['info_data']:
+ key = 'remote6'
+
+ remote = options['linkinfo']['info_data'][key]
+ self.assertIn(f'remote {remote}', self._options[interface])
+
+ if any('flowlabel' in s for s in self._options[interface]):
+ label = options['linkinfo']['info_data']['label']
+ self.assertIn(f'parameters ipv6 flowlabel {label}', self._options[interface])
+
+ self.assertEqual('geneve', options['linkinfo']['info_kind'])
+ self.assertEqual('set', options['linkinfo']['info_data']['df'])
+ self.assertEqual(f'0x{tos}', options['linkinfo']['info_data']['tos'])
+ self.assertEqual(ttl, options['linkinfo']['info_data']['ttl'])
+ self.assertEqual(Interface(interface).get_admin_state(), 'up')
+ ttl += 10
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_vxlan.py b/smoketest/scripts/cli/test_interfaces_vxlan.py
index c52dc410b..b66315c5e 100755
--- a/smoketest/scripts/cli/test_interfaces_vxlan.py
+++ b/smoketest/scripts/cli/test_interfaces_vxlan.py
@@ -32,16 +32,14 @@ class VXLANInterfaceTest(BasicInterfaceTest.BaseTest):
cls._options = {
'vxlan10': ['vni 10', 'remote 127.0.0.2'],
'vxlan20': ['vni 20', 'group 239.1.1.1', 'source-interface eth0'],
- 'vxlan30': ['vni 30', 'remote 2001:db8:2000::1', 'source-address 2001:db8:1000::1'],
+ 'vxlan30': ['vni 30', 'remote 2001:db8:2000::1', 'source-address 2001:db8:1000::1', 'parameters ipv6 flowlabel 0x1000'],
}
cls._interfaces = list(cls._options)
def test_vxlan_parameters(self):
- addr = '192.0.2.0/31'
tos = '40'
ttl = 20
for intf in self._interfaces:
- self.session.set(self._base_path + [intf, 'address', addr])
for option in self._options.get(intf, []):
self.session.set(self._base_path + [intf] + option.split())
@@ -55,6 +53,31 @@ class VXLANInterfaceTest(BasicInterfaceTest.BaseTest):
ttl = 20
for interface in self._interfaces:
options = get_json_iface_options(interface)
+
+ vni = options['linkinfo']['info_data']['id']
+ self.assertIn(f'vni {vni}', self._options[interface])
+
+ if any('link' in s for s in self._options[interface]):
+ link = options['linkinfo']['info_data']['link']
+ self.assertIn(f'source-interface {link}', self._options[interface])
+
+ if any('local6' in s for s in self._options[interface]):
+ remote = options['linkinfo']['info_data']['local6']
+ self.assertIn(f'source-address {local6}', self._options[interface])
+
+ if any('remote6' in s for s in self._options[interface]):
+ remote = options['linkinfo']['info_data']['remote6']
+ self.assertIn(f'remote {remote}', self._options[interface])
+
+ if any('group' in s for s in self._options[interface]):
+ group = options['linkinfo']['info_data']['group']
+ self.assertIn(f'group {group}', self._options[interface])
+
+ if any('flowlabel' in s for s in self._options[interface]):
+ label = options['linkinfo']['info_data']['label']
+ self.assertIn(f'parameters ipv6 flowlabel {label}', self._options[interface])
+
+ self.assertEqual('vxlan', options['linkinfo']['info_kind'])
self.assertEqual('set', options['linkinfo']['info_data']['df'])
self.assertEqual(f'0x{tos}', options['linkinfo']['info_data']['tos'])
self.assertEqual(ttl, options['linkinfo']['info_data']['ttl'])
@@ -62,4 +85,4 @@ class VXLANInterfaceTest(BasicInterfaceTest.BaseTest):
ttl += 10
if __name__ == '__main__':
- unittest.main(verbosity=2, failfast=True)
+ unittest.main(verbosity=2)
diff --git a/src/op_mode/show_interfaces.py b/src/op_mode/show_interfaces.py
index 256c86d2a..5375a8406 100755
--- a/src/op_mode/show_interfaces.py
+++ b/src/op_mode/show_interfaces.py
@@ -71,10 +71,7 @@ def filtered_interfaces(ifnames, iftypes, vif, vrrp):
if ifnames and ifname not in ifnames:
continue
- # return the class which can handle this interface name
- klass = Section.klass(ifname)
- # connect to the interface
- interface = klass(ifname, create=False, debug=False)
+ interface = Interface(ifname)
if iftypes and interface.definition['section'] not in iftypes:
continue