summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-definitions/interfaces-tunnel.xml.in15
-rw-r--r--python/vyos/configverify.py7
-rw-r--r--smoketest/configs/tunnel-broker2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_tunnel.py20
-rwxr-xr-xsrc/conf_mode/dhcp_server.py12
-rwxr-xr-xsrc/conf_mode/dhcpv6_server.py2
-rwxr-xr-xsrc/conf_mode/interfaces-tunnel.py4
-rwxr-xr-xsrc/migration-scripts/interfaces/21-to-2246
8 files changed, 63 insertions, 45 deletions
diff --git a/interface-definitions/interfaces-tunnel.xml.in b/interface-definitions/interfaces-tunnel.xml.in
index df9b58992..2c15abec7 100644
--- a/interface-definitions/interfaces-tunnel.xml.in
+++ b/interface-definitions/interfaces-tunnel.xml.in
@@ -54,21 +54,6 @@
</constraint>
</properties>
</leafNode>
- <leafNode name="dhcp-interface">
- <properties>
- <help>dhcp interface</help>
- <valueHelp>
- <format>interface</format>
- <description>DHCP interface that supplies the local IP address for this tunnel</description>
- </valueHelp>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces.py</script>
- </completionHelp>
- <constraint>
- <validator name="interface-name"/>
- </constraint>
- </properties>
- </leafNode>
<leafNode name="encapsulation">
<properties>
<help>Encapsulation of this tunnel interface</help>
diff --git a/python/vyos/configverify.py b/python/vyos/configverify.py
index ce7e76eb4..3aece499e 100644
--- a/python/vyos/configverify.py
+++ b/python/vyos/configverify.py
@@ -95,15 +95,12 @@ def verify_tunnel(config):
raise ConfigError('Must configure the tunnel encapsulation for '\
'{ifname}!'.format(**config))
- if 'source_address' not in config and 'dhcp_interface' not in config:
- raise ConfigError('source-address is mandatory for tunnel')
+ if 'source_address' not in config and 'source_interface' not in config:
+ raise ConfigError('source-address or source-interface required for tunnel!')
if 'remote' not in config and config['encapsulation'] != 'gre':
raise ConfigError('remote-ip address is mandatory for tunnel')
- if {'source_address', 'dhcp_interface'} <= set(config):
- raise ConfigError('Can not use both source-address and dhcp-interface')
-
if config['encapsulation'] in ['ipip6', 'ip6ip6', 'ip6gre']:
error_ipv6 = 'Encapsulation mode requires IPv6'
if 'source_address' in config and not is_ipv6(config['source_address']):
diff --git a/smoketest/configs/tunnel-broker b/smoketest/configs/tunnel-broker
index d4a5c2dfc..03ac0db41 100644
--- a/smoketest/configs/tunnel-broker
+++ b/smoketest/configs/tunnel-broker
@@ -56,7 +56,7 @@ interfaces {
tunnel tun100 {
address 172.16.0.1/30
encapsulation gre-bridge
- local-ip 192.0.2.0
+ dhcp-interface eth0
remote-ip 192.0.2.100
}
tunnel tun200 {
diff --git a/smoketest/scripts/cli/test_interfaces_tunnel.py b/smoketest/scripts/cli/test_interfaces_tunnel.py
index 3aed498b4..ff8778828 100755
--- a/smoketest/scripts/cli/test_interfaces_tunnel.py
+++ b/smoketest/scripts/cli/test_interfaces_tunnel.py
@@ -156,26 +156,6 @@ class TunnelInterfaceTest(BasicInterfaceTest.TestCase):
self.cli_delete(self._base_path + [interface])
self.cli_commit()
- def test_tunnel_verify_local_dhcp(self):
- # We can not use source-address and dhcp-interface at the same time
-
- interface = f'tun1020'
- local_if_addr = f'10.0.0.1/24'
-
- self.cli_set(self._base_path + [interface, 'address', local_if_addr])
- self.cli_set(self._base_path + [interface, 'encapsulation', 'gre'])
- self.cli_set(self._base_path + [interface, 'source-address', self.local_v4])
- self.cli_set(self._base_path + [interface, 'remote', remote_ip4])
- self.cli_set(self._base_path + [interface, 'dhcp-interface', 'eth0'])
-
- # source-address and dhcp-interface can not be used at the same time
- with self.assertRaises(ConfigSessionError):
- self.cli_commit()
- self.cli_delete(self._base_path + [interface, 'dhcp-interface'])
-
- # Check if commit is ok
- self.cli_commit()
-
def test_tunnel_parameters_gre(self):
interface = f'tun1030'
gre_key = '10'
diff --git a/src/conf_mode/dhcp_server.py b/src/conf_mode/dhcp_server.py
index 28f2a4ca5..a8cef5ebf 100755
--- a/src/conf_mode/dhcp_server.py
+++ b/src/conf_mode/dhcp_server.py
@@ -151,9 +151,15 @@ def verify(dhcp):
listen_ok = False
subnets = []
failover_ok = False
+ shared_networks = len(dhcp['shared_network_name'])
+ disabled_shared_networks = 0
+
# A shared-network requires a subnet definition
for network, network_config in dhcp['shared_network_name'].items():
+ if 'disable' in network_config:
+ disabled_shared_networks += 1
+
if 'subnet' not in network_config:
raise ConfigError(f'No subnets defined for {network}. At least one\n' \
'lease subnet must be configured.')
@@ -226,7 +232,7 @@ def verify(dhcp):
# There must be one subnet connected to a listen interface.
# This only counts if the network itself is not disabled!
if 'disable' not in network_config:
- if is_subnet_connected(subnet, primary=True):
+ if is_subnet_connected(subnet, primary=False):
listen_ok = True
# Subnets must be non overlapping
@@ -243,6 +249,10 @@ def verify(dhcp):
if net.overlaps(net2):
raise ConfigError('Conflicting subnet ranges: "{net}" overlaps "{net2}"!')
+ # Prevent 'disable' for shared-network if only one network is configured
+ if (shared_networks - disabled_shared_networks) < 1:
+ raise ConfigError(f'At least one shared network must be active!')
+
if 'failover' in dhcp:
if not failover_ok:
raise ConfigError('DHCP failover must be enabled for at least one subnet!')
diff --git a/src/conf_mode/dhcpv6_server.py b/src/conf_mode/dhcpv6_server.py
index 175300bb0..e6a2e4486 100755
--- a/src/conf_mode/dhcpv6_server.py
+++ b/src/conf_mode/dhcpv6_server.py
@@ -128,7 +128,7 @@ def verify(dhcpv6):
# Subnets must be unique
if subnet in subnets:
- raise ConfigError('DHCPv6 subnets must be unique! Subnet {0} defined multiple times!'.format(subnet['network']))
+ raise ConfigError(f'DHCPv6 subnets must be unique! Subnet {subnet} defined multiple times!')
subnets.append(subnet)
# DHCPv6 requires at least one configured address range or one static mapping
diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py
index 5fa165190..4db564e6d 100755
--- a/src/conf_mode/interfaces-tunnel.py
+++ b/src/conf_mode/interfaces-tunnel.py
@@ -78,7 +78,7 @@ def verify(tunnel):
# If tunnel source address any and key not set
if tunnel['encapsulation'] in ['gre'] and \
- tunnel['source_address'] == '0.0.0.0' and \
+ dict_search('source_address', tunnel) == '0.0.0.0' and \
dict_search('parameters.ip.key', tunnel) == None:
raise ConfigError('Tunnel parameters ip key must be set!')
@@ -91,7 +91,7 @@ def verify(tunnel):
# no match on encapsulation - bail out
if dict_search('linkinfo.info_kind', tunnel_cfg) != tunnel['encapsulation']:
continue
- new_source_address = tunnel['source_address']
+ new_source_address = dict_search('source_address', tunnel)
# Convert tunnel key to ip key, format "ip -j link show"
# 1 => 0.0.0.1, 999 => 0.0.3.231
orig_new_key = dict_search('parameters.ip.key', tunnel)
diff --git a/src/migration-scripts/interfaces/21-to-22 b/src/migration-scripts/interfaces/21-to-22
new file mode 100755
index 000000000..098102102
--- /dev/null
+++ b/src/migration-scripts/interfaces/21-to-22
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 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/>.
+
+from sys import argv
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 1):
+ print("Must specify file name!")
+ exit(1)
+
+file_name = argv[1]
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+config = ConfigTree(config_file)
+base = ['interfaces', 'tunnel']
+
+if not config.exists(base):
+ exit(0)
+
+for interface in config.list_nodes(base):
+ path = base + [interface, 'dhcp-interface']
+ if config.exists(path):
+ tmp = config.return_value(path)
+ config.delete(path)
+ config.set(base + [interface, 'source-interface'], value=tmp)
+
+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))
+ exit(1)