summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-definitions/include/tunnel-local-remote-ip.xml.i37
-rw-r--r--interface-definitions/include/tunnel-parameters-ip.xml.i49
-rw-r--r--interface-definitions/interfaces-erspan.xml.in96
-rw-r--r--interface-definitions/interfaces-tunnel.xml.in103
-rw-r--r--python/vyos/configverify.py43
-rwxr-xr-xpython/vyos/ifconfig/erspan.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_erspan.py28
-rwxr-xr-xsrc/conf_mode/interfaces-erspan.py52
-rwxr-xr-xsrc/conf_mode/interfaces-tunnel.py34
9 files changed, 151 insertions, 293 deletions
diff --git a/interface-definitions/include/tunnel-local-remote-ip.xml.i b/interface-definitions/include/tunnel-local-remote-ip.xml.i
new file mode 100644
index 000000000..85c20f482
--- /dev/null
+++ b/interface-definitions/include/tunnel-local-remote-ip.xml.i
@@ -0,0 +1,37 @@
+<!-- included start from tunnel-local-remote-ip.xml.i -->
+<leafNode name="local-ip">
+ <properties>
+ <help>Local IP address for this tunnel</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>Local IPv4 address for this tunnel</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>Local IPv6 address for this tunnel</description>
+ </valueHelp>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_local_ips.sh --both</script>
+ </completionHelp>
+ <constraint>
+ <validator name="ip-address"/>
+ </constraint>
+ </properties>
+</leafNode>
+<leafNode name="remote-ip">
+ <properties>
+ <help>Remote IP address for this tunnel</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>Remote IPv4 address for this tunnel</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>Remote IPv6 address for this tunnel</description>
+ </valueHelp>
+ <constraint>
+ <!-- does it need fixing/changing to be more restrictive ? -->
+ <validator name="ip-address"/>
+ </constraint>
+ </properties>
+</leafNode>
diff --git a/interface-definitions/include/tunnel-parameters-ip.xml.i b/interface-definitions/include/tunnel-parameters-ip.xml.i
new file mode 100644
index 000000000..c304bd3ff
--- /dev/null
+++ b/interface-definitions/include/tunnel-parameters-ip.xml.i
@@ -0,0 +1,49 @@
+<!-- included start from tunnel-parameters-ip.xml.i -->
+<node name="ip">
+ <properties>
+ <help>IPv4 specific tunnel parameters</help>
+ </properties>
+ <children>
+ <leafNode name="ttl">
+ <properties>
+ <help>Time to live field</help>
+ <valueHelp>
+ <format>0-255</format>
+ <description>Time to live (default 255)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-255"/>
+ </constraint>
+ <constraintErrorMessage>TTL must be between 0 and 255</constraintErrorMessage>
+ </properties>
+ <defaultValue>255</defaultValue>
+ </leafNode>
+ <leafNode name="tos">
+ <properties>
+ <help>Type of Service (TOS)</help>
+ <valueHelp>
+ <format>0-99</format>
+ <description>Type of Service (TOS)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-99"/>
+ </constraint>
+ <constraintErrorMessage>TOS must be between 0 and 99</constraintErrorMessage>
+ </properties>
+ <defaultValue>inherit</defaultValue>
+ </leafNode>
+ <leafNode name="key">
+ <properties>
+ <help>Tunnel key</help>
+ <valueHelp>
+ <format>u32</format>
+ <description>Tunnel key</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-4294967295"/>
+ </constraint>
+ <constraintErrorMessage>key must be between 0-4294967295</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ </children>
+</node>
diff --git a/interface-definitions/interfaces-erspan.xml.in b/interface-definitions/interfaces-erspan.xml.in
index 6b98b0730..afc29a658 100644
--- a/interface-definitions/interfaces-erspan.xml.in
+++ b/interface-definitions/interfaces-erspan.xml.in
@@ -17,62 +17,23 @@
</properties>
<children>
#include <include/interface-description.xml.i>
- #include <include/address-ipv4-ipv6.xml.i>
#include <include/interface-disable.xml.i>
#include <include/interface-disable-link-detect.xml.i>
- #include <include/interface-vrf.xml.i>
#include <include/interface-mtu-64-8024.xml.i>
- #include <include/interface-ipv4-options.xml.i>
- #include <include/interface-ipv6-options.xml.i>
- <leafNode name="local-ip">
- <properties>
- <help>Local IP address for this tunnel</help>
- <valueHelp>
- <format>ipv4</format>
- <description>Local IPv4 address for this ERSPAN tunnel</description>
- </valueHelp>
- <valueHelp>
- <format>ipv6</format>
- <description>Local IPv6 address for this tunnel [NOTICE: unavailable for mGRE tunnels]</description>
- </valueHelp>
- <completionHelp>
- <script>${vyos_completion_dir}/list_local.py</script>
- </completionHelp>
- <constraint>
- <validator name="ip-address"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="remote-ip">
- <properties>
- <help>Remote IP address for this ERSPAN tunnel</help>
- <valueHelp>
- <format>ipv4</format>
- <description>Remote IPv4 address for this tunnel</description>
- </valueHelp>
- <valueHelp>
- <format>ipv6</format>
- <description>Remote IPv6 address for this tunnel</description>
- </valueHelp>
- <constraint>
- <!-- does it need fixing/changing to be more restrictive ? -->
- <validator name="ip-address"/>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/tunnel-local-remote-ip.xml.i>
<leafNode name="encapsulation">
<properties>
- <help>Encapsulation of this ERSPAN tunnel interface</help>
+ <help>Encapsulation of this tunnel interface</help>
<completionHelp>
<list>erspan ip6erspan</list>
</completionHelp>
<valueHelp>
<format>erspan</format>
- <description>Encapsulated Remote SPAN over GRE and IPv4</description>
+ <description>Generic Routing Encapsulation</description>
</valueHelp>
<valueHelp>
<format>ip6erspan</format>
- <description>Encapsulated Remote SPAN over GRE and IPv6</description>
+ <description>Generic Routing Encapsulation bridge interface</description>
</valueHelp>
<constraint>
<regex>^(erspan|ip6erspan)$</regex>
@@ -85,54 +46,7 @@
<help>ERSPAN Tunnel parameters</help>
</properties>
<children>
- <node name="ip">
- <properties>
- <help>IP specific ERSPAN tunnel parameters</help>
- </properties>
- <children>
- <leafNode name="ttl">
- <properties>
- <help>Time to live field</help>
- <valueHelp>
- <format>0-255</format>
- <description>Time to live (default 255)</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-255"/>
- </constraint>
- <constraintErrorMessage>TTL must be between 0 and 255</constraintErrorMessage>
- </properties>
- <defaultValue>255</defaultValue>
- </leafNode>
- <leafNode name="tos">
- <properties>
- <help>Type of Service (TOS)</help>
- <valueHelp>
- <format>0-99</format>
- <description>Type of Service (TOS)</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-99"/>
- </constraint>
- <constraintErrorMessage>TOS must be between 0 and 99</constraintErrorMessage>
- </properties>
- <defaultValue>inherit</defaultValue>
- </leafNode>
- <leafNode name="key">
- <properties>
- <help>ERSPAN Tunnel key</help>
- <valueHelp>
- <format>0-4294967295</format>
- <description>Tunnel key</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-4294967295"/>
- </constraint>
- <constraintErrorMessage>key must be between 0-4294967295</constraintErrorMessage>
- </properties>
- </leafNode>
- </children>
- </node>
+ #include <include/tunnel-parameters-ip.xml.i>
<leafNode name="version">
<properties>
<help>ERSPAN version number setting(default:1)</help>
diff --git a/interface-definitions/interfaces-tunnel.xml.in b/interface-definitions/interfaces-tunnel.xml.in
index 7fa847ab0..279c05cca 100644
--- a/interface-definitions/interfaces-tunnel.xml.in
+++ b/interface-definitions/interfaces-tunnel.xml.in
@@ -27,42 +27,7 @@
</leafNode>
#include <include/interface-ipv4-options.xml.i>
#include <include/interface-ipv6-options.xml.i>
- <leafNode name="local-ip">
- <properties>
- <help>Local IP address for this tunnel</help>
- <valueHelp>
- <format>ipv4</format>
- <description>Local IPv4 address for this tunnel</description>
- </valueHelp>
- <valueHelp>
- <format>ipv6</format>
- <description>Local IPv6 address for this tunnel [NOTICE: unavailable for mGRE tunnels]</description>
- </valueHelp>
- <completionHelp>
- <script>${vyos_completion_dir}/list_local_ips.sh --both</script>
- </completionHelp>
- <constraint>
- <validator name="ip-address"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="remote-ip">
- <properties>
- <help>Remote IP address for this tunnel</help>
- <valueHelp>
- <format>ipv4</format>
- <description>Remote IPv4 address for this tunnel</description>
- </valueHelp>
- <valueHelp>
- <format>ipv6</format>
- <description>Remote IPv6 address for this tunnel</description>
- </valueHelp>
- <constraint>
- <!-- does it need fixing/changing to be more restrictive ? -->
- <validator name="ip-address"/>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/tunnel-local-remote-ip.xml.i>
<leafNode name="source-interface">
<properties>
<help>Physical Interface used for underlaying traffic</help>
@@ -175,71 +140,7 @@
<help>Tunnel parameters</help>
</properties>
<children>
- <node name="ip">
- <properties>
- <help>IPv4 specific tunnel parameters</help>
- </properties>
- <children>
- <leafNode name="no-pmtu-discovery">
- <properties>
- <help>Disable path MTU discovery</help>
- <valueless/>
- </properties>
- </leafNode>
- <leafNode name="ttl">
- <properties>
- <help>Time to live (default: 0)</help>
- <valueHelp>
- <format>0</format>
- <description>Copy value from original IP header</description>
- </valueHelp>
- <valueHelp>
- <format>1-255</format>
- <description>Time to Live</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-255"/>
- </constraint>
- <constraintErrorMessage>TTL must be between 0 and 255</constraintErrorMessage>
- </properties>
- <defaultValue>0</defaultValue>
- </leafNode>
- <leafNode name="tos">
- <properties>
- <help>Type of Service (default: 0)</help>
- <completionHelp>
- <list>inherit</list>
- </completionHelp>
- <valueHelp>
- <format>0</format>
- <description>Copy value from original IP header</description>
- </valueHelp>
- <valueHelp>
- <format>1-99</format>
- <description>Type of Service (TOS)</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-99"/>
- </constraint>
- <constraintErrorMessage>TOS must be between 0 and 99</constraintErrorMessage>
- </properties>
- <defaultValue>0</defaultValue>
- </leafNode>
- <leafNode name="key">
- <properties>
- <help>Tunnel key</help>
- <valueHelp>
- <format>u32</format>
- <description>Tunnel key</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-4294967295"/>
- </constraint>
- <constraintErrorMessage>Key must be in range 0-4294967295</constraintErrorMessage>
- </properties>
- </leafNode>
- </children>
- </node>
+ #include <include/tunnel-parameters-ip.xml.i>
<node name="ipv6">
<properties>
<help>IPv6 specific tunnel parameters</help>
diff --git a/python/vyos/configverify.py b/python/vyos/configverify.py
index a888791ba..e71e4e1c5 100644
--- a/python/vyos/configverify.py
+++ b/python/vyos/configverify.py
@@ -89,6 +89,49 @@ def verify_vrf(config):
'Interface "{ifname}" cannot be both a member of VRF "{vrf}" '
'and bridge "{is_bridge_member}"!'.format(**config))
+def verify_tunnel(config):
+ """
+ This helper is used to verify the common part of the tunnel
+ """
+ from vyos.template import is_ipv4
+ from vyos.template import is_ipv6
+
+ if 'encapsulation' not in config:
+ raise ConfigError('Must configure the tunnel encapsulation for '\
+ '{ifname}!'.format(**config))
+
+ if 'local_ip' not in config and 'dhcp_interface' not in config:
+ raise ConfigError('local-ip is mandatory for tunnel')
+
+ if 'remote_ip' not in config and config['encapsulation'] != 'gre':
+ raise ConfigError('remote-ip is mandatory for tunnel')
+
+ if {'local_ip', 'dhcp_interface'} <= set(config):
+ raise ConfigError('Can not use both local-ip and dhcp-interface')
+
+ if config['encapsulation'] in ['ipip6', 'ip6ip6', 'ip6gre', 'ip6erspan']:
+ error_ipv6 = 'Encapsulation mode requires IPv6'
+ if 'local_ip' in config and not is_ipv6(config['local_ip']):
+ raise ConfigError(f'{error_ipv6} local-ip')
+
+ if 'remote_ip' in config and not is_ipv6(config['remote_ip']):
+ raise ConfigError(f'{error_ipv6} remote-ip')
+ else:
+ error_ipv4 = 'Encapsulation mode requires IPv4'
+ if 'local_ip' in config and not is_ipv4(config['local_ip']):
+ raise ConfigError(f'{error_ipv4} local-ip')
+
+ if 'remote_ip' in config and not is_ipv4(config['remote_ip']):
+ raise ConfigError(f'{error_ipv4} remote-ip')
+
+ if config['encapsulation'] in ['sit', 'gre-bridge']:
+ if 'source_interface' in config:
+ raise ConfigError('Option source-interface can not be used with ' \
+ 'encapsulation "sit" or "gre-bridge"')
+ elif config['encapsulation'] == 'gre':
+ if 'local_ip' in config and is_ipv6(config['local_ip']):
+ raise ConfigError('Can not use local IPv6 address is for mGRE tunnels')
+
def verify_eapol(config):
"""
Common helper function used by interface implementations to perform
diff --git a/python/vyos/ifconfig/erspan.py b/python/vyos/ifconfig/erspan.py
index 848840144..50230e14a 100755
--- a/python/vyos/ifconfig/erspan.py
+++ b/python/vyos/ifconfig/erspan.py
@@ -167,7 +167,7 @@ class ER6SpanIf(_ERSpan):
self._cmd(command)
- def change_options(self, config):
+ def change_options(self):
ifname = self.config['ifname']
local_ip = self.config['local_ip']
remote_ip = self.config['remote_ip']
diff --git a/smoketest/scripts/cli/test_interfaces_erspan.py b/smoketest/scripts/cli/test_interfaces_erspan.py
index d21b3ab9b..c180f0a34 100755
--- a/smoketest/scripts/cli/test_interfaces_erspan.py
+++ b/smoketest/scripts/cli/test_interfaces_erspan.py
@@ -93,24 +93,11 @@ class ERSPanTunnelInterfaceTest(BasicInterfaceTest.BaseTest):
def test_erspan_ipv4(self):
interface = 'ersp100'
encapsulation = 'erspan'
- address_v4 = '10.1.1.1/24'
key = 123
- self.session.set(self._base_path + [interface, 'address', address_v4])
-
- # Must configure the ERSPAN tunnel encapsulation for ersp100
- with self.assertRaises(ConfigSessionError):
- self.session.commit()
self.session.set(self._base_path + [interface, 'encapsulation', encapsulation])
-
- # local-ip is mandatory for ERSPAN tunnel
- with self.assertRaises(ConfigSessionError):
- self.session.commit()
self.session.set(self._base_path + [interface, 'local-ip', self.local_v4])
-
-
self.session.set(self._base_path + [interface, 'remote-ip', self.remote_v4])
-
self.session.set(self._base_path + [interface, 'parameters', 'ip' , 'key', str(key)])
self.session.commit()
@@ -127,24 +114,11 @@ class ERSPanTunnelInterfaceTest(BasicInterfaceTest.BaseTest):
def test_erspan_ipv6(self):
interface = 'ersp1000'
encapsulation = 'ip6erspan'
- address_v6 = '2001:db8::1/24'
key = 123
- self.session.set(self._base_path + [interface, 'address', address_v6])
-
- # Must configure the ERSPAN tunnel encapsulation for ersp100
- with self.assertRaises(ConfigSessionError):
- self.session.commit()
self.session.set(self._base_path + [interface, 'encapsulation', encapsulation])
-
- # local-ip is mandatory for ERSPAN tunnel
- with self.assertRaises(ConfigSessionError):
- self.session.commit()
self.session.set(self._base_path + [interface, 'local-ip', self.local_v6])
-
-
self.session.set(self._base_path + [interface, 'remote-ip', self.remote_v6])
-
self.session.set(self._base_path + [interface, 'parameters', 'ip' , 'key', str(key)])
self.session.commit()
@@ -158,4 +132,4 @@ class ERSPanTunnelInterfaceTest(BasicInterfaceTest.BaseTest):
self.assertEqual(self.remote_v6, conf['linkinfo']['info_data']['remote'])
if __name__ == '__main__':
- unittest.main()
+ unittest.main(verbosity=2)
diff --git a/src/conf_mode/interfaces-erspan.py b/src/conf_mode/interfaces-erspan.py
index 1bb5a4a9d..2d65b834c 100755
--- a/src/conf_mode/interfaces-erspan.py
+++ b/src/conf_mode/interfaces-erspan.py
@@ -25,9 +25,8 @@ from vyos.configdict import dict_merge
from vyos.configdict import get_interface_dict
from vyos.configdict import node_changed
from vyos.configdict import leaf_node_changed
-from vyos.configverify import verify_vrf
-from vyos.configverify import verify_address
from vyos.configverify import verify_mtu_ipv6
+from vyos.configverify import verify_tunnel
from vyos.ifconfig import Interface
from vyos.ifconfig import ERSpanIf
from vyos.ifconfig import ER6SpanIf
@@ -51,7 +50,7 @@ def get_config(config=None):
erspan = get_interface_dict(conf, base)
tmp = leaf_node_changed(conf, ['encapsulation'])
- if tmp:
+ if tmp:
erspan.update({'encapsulation_changed': {}})
return erspan
@@ -61,57 +60,28 @@ def verify(erspan):
return None
if 'encapsulation' not in erspan:
- raise ConfigError('Must configure the ERSPAN tunnel encapsulation for '\
+ raise ConfigError('Unable to detect the following ERSPAN tunnel encapsulation'\
'{ifname}!'.format(**erspan))
verify_mtu_ipv6(erspan)
- verify_address(erspan)
- verify_vrf(erspan)
-
- if 'local_ip' not in erspan:
- raise ConfigError('local-ip is mandatory for ERSPAN tunnel')
-
- if 'remote_ip' not in erspan:
- raise ConfigError('remote-ip is mandatory for ERSPAN tunnel')
-
- if erspan['encapsulation'] in ['ip6erspan']:
- error_ipv6 = 'Encapsulation mode requires IPv6'
- if 'local_ip' in erspan and not is_ipv6(erspan['local_ip']):
- raise ConfigError(f'{error_ipv6} local-ip')
-
- if 'remote_ip' in erspan and not is_ipv6(erspan['remote_ip']):
- raise ConfigError(f'{error_ipv6} remote-ip')
- else:
- error_ipv4 = 'Encapsulation mode requires IPv4'
- if 'local_ip' in erspan and not is_ipv4(erspan['local_ip']):
- raise ConfigError(f'{error_ipv4} local-ip')
-
- if 'remote_ip' in erspan and not is_ipv4(erspan['remote_ip']):
- raise ConfigError(f'{error_ipv4} remote-ip')
-
- if 'parameters' not in erspan:
- raise ConfigError('parameters is mandatory for ERSPAN tunnel')
+ verify_tunnel(erspan)
key = dict_search('parameters.ip.key',erspan)
if key == None:
raise ConfigError('parameters.ip.key is mandatory for ERSPAN tunnel')
-
- if erspan['encapsulation'] == 'erspan':
- if 'local_ip' in erspan and is_ipv6(erspan['local_ip']):
- raise ConfigError('Can not use local IPv6 address is for ERSPAN tunnels')
def generate(erspan):
return None
def apply(erspan):
- if 'deleted' in erspan or 'encapsulation_changed' in erspan:
- if erspan['ifname'] in interfaces():
- tmp = Interface(erspan['ifname'])
- tmp.remove()
- if 'deleted' in erspan:
- return None
-
+ if 'deleted' in erspan or 'encapsulation_changed' in erspan:
+ if erspan['ifname'] in interfaces():
+ tmp = Interface(erspan['ifname'])
+ tmp.remove()
+ if 'deleted' in erspan:
+ return None
+
dispatch = {
'erspan': ERSpanIf,
'ip6erspan': ER6SpanIf
diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py
index f03bc9d5d..034bd6dd1 100755
--- a/src/conf_mode/interfaces-tunnel.py
+++ b/src/conf_mode/interfaces-tunnel.py
@@ -29,6 +29,7 @@ from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_interface_exists
from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_vrf
+from vyos.configverify import verify_tunnel
from vyos.ifconfig import Interface
from vyos.ifconfig import GREIf
from vyos.ifconfig import GRETapIf
@@ -84,38 +85,7 @@ def verify(tunnel):
verify_mtu_ipv6(tunnel)
verify_address(tunnel)
verify_vrf(tunnel)
-
- if 'local_ip' not in tunnel and 'dhcp_interface' not in tunnel:
- raise ConfigError('local-ip is mandatory for tunnel')
-
- if 'remote_ip' not in tunnel and tunnel['encapsulation'] != 'gre':
- raise ConfigError('remote-ip is mandatory for tunnel')
-
- if {'local_ip', 'dhcp_interface'} <= set(tunnel):
- raise ConfigError('Can not use both local-ip and dhcp-interface')
-
- if tunnel['encapsulation'] in ['ipip6', 'ip6ip6', 'ip6gre']:
- error_ipv6 = 'Encapsulation mode requires IPv6'
- if 'local_ip' in tunnel and not is_ipv6(tunnel['local_ip']):
- raise ConfigError(f'{error_ipv6} local-ip')
-
- if 'remote_ip' in tunnel and not is_ipv6(tunnel['remote_ip']):
- raise ConfigError(f'{error_ipv6} remote-ip')
- else:
- error_ipv4 = 'Encapsulation mode requires IPv4'
- if 'local_ip' in tunnel and not is_ipv4(tunnel['local_ip']):
- raise ConfigError(f'{error_ipv4} local-ip')
-
- if 'remote_ip' in tunnel and not is_ipv4(tunnel['remote_ip']):
- raise ConfigError(f'{error_ipv4} remote-ip')
-
- if tunnel['encapsulation'] in ['sit', 'gre-bridge']:
- if 'source_interface' in tunnel:
- raise ConfigError('Option source-interface can not be used with ' \
- 'encapsulation "sit" or "gre-bridge"')
- elif tunnel['encapsulation'] == 'gre':
- if 'local_ip' in tunnel and is_ipv6(tunnel['local_ip']):
- raise ConfigError('Can not use local IPv6 address is for mGRE tunnels')
+ verify_tunnel(tunnel)
if 'source_interface' in tunnel:
verify_interface_exists(tunnel['source_interface'])