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:09:30 +0100
commit1ad47b7a0aa2a073149fa047878d52e7ca8889c1 (patch)
tree44a44989a9aa812872433cb45ea96f3cd459aac9
parent8bd635bd747ca35db5dd38d1fddeb0d0a9ffca37 (diff)
downloadvyos-1x-1ad47b7a0aa2a073149fa047878d52e7ca8889c1.tar.gz
vyos-1x-1ad47b7a0aa2a073149fa047878d52e7ca8889c1.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. (cherry picked from commit 6f1326d6b68f6dcb83843374c876407ef2922bd1)
-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 2798d321f..6cdaa463f 100755
--- a/src/conf_mode/interfaces-tunnel.py
+++ b/src/conf_mode/interfaces-tunnel.py
@@ -83,19 +83,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)
@@ -105,6 +108,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']: