summaryrefslogtreecommitdiff
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
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.
-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']: