diff options
author | Christian Poessinger <christian@poessinger.com> | 2022-02-14 19:07:29 +0100 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2022-02-14 19:07:29 +0100 |
commit | 6f1326d6b68f6dcb83843374c876407ef2922bd1 (patch) | |
tree | 278cb93f2e5a2a8990425f71fa8c1ee7e144ed4d /src/conf_mode | |
parent | 812d9770619b968b04961aebf3944fde13df491b (diff) | |
download | vyos-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-x | src/conf_mode/interfaces-tunnel.py | 39 |
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']: |