summaryrefslogtreecommitdiff
path: root/src/conf_mode
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2022-02-14 19:07:29 +0100
committerChristian Poessinger <christian@poessinger.com>2022-02-14 19:07:29 +0100
commit6f1326d6b68f6dcb83843374c876407ef2922bd1 (patch)
tree278cb93f2e5a2a8990425f71fa8c1ee7e144ed4d /src/conf_mode
parent812d9770619b968b04961aebf3944fde13df491b (diff)
downloadvyos-1x-6f1326d6b68f6dcb83843374c876407ef2922bd1.tar.gz
vyos-1x-6f1326d6b68f6dcb83843374c876407ef2922bd1.zip
tunnel: T4154: verify() no more then one GRE tunnel is used w/o "ip key" per interface
It is impossible for the OS kernel to distinguish multiple GRE tunnels when no "gre key" is configured when sourcing tunnels from the same interface.
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-xsrc/conf_mode/interfaces-tunnel.py39
1 files changed, 26 insertions, 13 deletions
diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py
index 30f57ec0c..c9267e749 100755
--- a/src/conf_mode/interfaces-tunnel.py
+++ b/src/conf_mode/interfaces-tunnel.py
@@ -103,19 +103,22 @@ def verify(tunnel):
raise ConfigError('Tunnel parameters ip key must be set!')
if tunnel['encapsulation'] in ['gre', 'gretap']:
- if dict_search('parameters.ip.key', tunnel) != None:
- # Check pairs tunnel source-address/encapsulation/key with exists tunnels.
- # Prevent the same key for 2 tunnels with same source-address/encap. T2920
- for tunnel_if in Section.interfaces('tunnel'):
- # It makes no sense to run the test for re-used GRE keys on our
- # own interface we are currently working on
- if tunnel['ifname'] == tunnel_if:
- continue
- tunnel_cfg = get_interface_config(tunnel_if)
- # no match on encapsulation - bail out
- if dict_search('linkinfo.info_kind', tunnel_cfg) != tunnel['encapsulation']:
- continue
- new_source_address = dict_search('source_address', tunnel)
+ # Check pairs tunnel source-address/encapsulation/key with exists tunnels.
+ # Prevent the same key for 2 tunnels with same source-address/encap. T2920
+ for tunnel_if in Section.interfaces('tunnel'):
+ # It makes no sense to run the test against our own interface we
+ # are currently configuring
+ if tunnel['ifname'] == tunnel_if:
+ continue
+
+ tunnel_cfg = get_interface_config(tunnel_if)
+ # no match on encapsulation - bail out
+ if dict_search('linkinfo.info_kind', tunnel_cfg) != tunnel['encapsulation']:
+ continue
+
+ new_source_address = dict_search('source_address', tunnel)
+ new_source_interface = dict_search('source_interface', tunnel)
+ if dict_search('parameters.ip.key', tunnel) != None:
# 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)
@@ -125,6 +128,16 @@ def verify(tunnel):
dict_search('linkinfo.info_data.ikey', tunnel_cfg) == new_key:
raise ConfigError(f'Key "{orig_new_key}" for source-address "{new_source_address}" ' \
f'is already used for tunnel "{tunnel_if}"!')
+ else:
+ # If no IP GRE key is used we can not have more then one GRE tunnel
+ # bound to any one interface/IP address. This will result in a OS
+ # PermissionError: add tunnel "gre0" failed: File exists
+ if (dict_search('address', tunnel_cfg) == new_source_address or
+ (dict_search('address', tunnel_cfg) == '0.0.0.0' and
+ dict_search('link', tunnel_cfg) == new_source_interface)):
+ raise ConfigError(f'Missing required "ip key" parameter when \
+ running more then one GRE based tunnel on the \
+ same source-interface/source-address')
# Keys are not allowed with ipip and sit tunnels
if tunnel['encapsulation'] in ['ipip', 'sit']: