diff options
author | Christian Poessinger <christian@poessinger.com> | 2021-04-05 23:23:14 +0200 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2021-04-05 23:23:14 +0200 |
commit | 44f766a7880e9264487e62f4aacc9f4f635219ed (patch) | |
tree | a518937a0c5fbd4891282cf0ef6b131dc9a99ea6 /src | |
parent | ecf53662f75b2588977d449713f07d28bd0e24a6 (diff) | |
download | vyos-1x-44f766a7880e9264487e62f4aacc9f4f635219ed.tar.gz vyos-1x-44f766a7880e9264487e62f4aacc9f4f635219ed.zip |
tunnel: T3030: move erspan type into regular tunnel interface
Instead of having a dedicated ERSPAN interface type, rather move the specifics
into "interface tunnel". A migrator is not needed as there is yet no LTS release
with this feature and this is considered experimental.
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/interfaces-erspan.py | 108 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-tunnel.py | 30 |
2 files changed, 23 insertions, 115 deletions
diff --git a/src/conf_mode/interfaces-erspan.py b/src/conf_mode/interfaces-erspan.py deleted file mode 100755 index 97ae3cf55..000000000 --- a/src/conf_mode/interfaces-erspan.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2018-2020 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/>. - -import os - -from sys import exit -from copy import deepcopy -from netifaces import interfaces - -from vyos.config import Config -from vyos.configdict import dict_merge -from vyos.configdict import get_interface_dict -from vyos.configdict import node_changed -from vyos.configdict import leaf_node_changed -from vyos.configverify import verify_mtu_ipv6 -from vyos.configverify import verify_tunnel -from vyos.ifconfig import Interface -from vyos.ifconfig import ERSpanIf -from vyos.ifconfig import ER6SpanIf -from vyos.template import is_ipv4 -from vyos.template import is_ipv6 -from vyos.util import dict_search -from vyos import ConfigError -from vyos import airbag -airbag.enable() - -def get_config(config=None): - """ - Retrive CLI config as dictionary. Dictionary can never be empty, as at least - the interface name will be added or a deleted flag - """ - if config: - conf = config - else: - conf = Config() - base = ['interfaces', 'erspan'] - erspan = get_interface_dict(conf, base) - - tmp = leaf_node_changed(conf, ['encapsulation']) - if tmp: - erspan.update({'encapsulation_changed': {}}) - - return erspan - -def verify(erspan): - if 'deleted' in erspan: - return None - - if 'encapsulation' not in erspan: - raise ConfigError('Unable to detect the following ERSPAN tunnel encapsulation'\ - '{ifname}!'.format(**erspan)) - - verify_mtu_ipv6(erspan) - verify_tunnel(erspan) - - key = dict_search('parameters.ip.key',erspan) - if key == None: - raise ConfigError('parameters.ip.key is mandatory for ERSPAN tunnel') - - -def generate(erspan): - return None - -def apply(erspan): - if 'deleted' in erspan or 'encapsulation_changed' in erspan: - if erspan['ifname'] in interfaces(): - tmp = Interface(erspan['ifname']) - tmp.remove() - if 'deleted' in erspan: - return None - - dispatch = { - 'erspan': ERSpanIf, - 'ip6erspan': ER6SpanIf - } - - # We need to re-map the tunnel encapsulation proto to a valid interface class - encap = erspan['encapsulation'] - klass = dispatch[encap] - - erspan_tunnel = klass(**erspan) - erspan_tunnel.change_options() - erspan_tunnel.update(erspan) - - return None - -if __name__ == '__main__': - try: - c = get_config() - generate(c) - verify(c) - apply(c) - except ConfigError as e: - print(e) - exit(1) diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index cab94a5b0..4e6c8a9ab 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -61,6 +61,9 @@ def get_config(config=None): nhrp = conf.get_config_dict([], key_mangling=('-', '_'), get_first_key=True) if nhrp: tunnel.update({'nhrp' : list(nhrp.keys())}) + if 'encapsulation' in tunnel and tunnel['encapsulation'] not in ['erspan', 'ip6erspan']: + del tunnel['parameters']['erspan'] + return tunnel def verify(tunnel): @@ -72,14 +75,28 @@ def verify(tunnel): return None - if 'encapsulation' not in tunnel: - error = 'Must configure encapsulation for "{ifname}"!' - raise ConfigError(error.format(**tunnel)) + verify_tunnel(tunnel) + + if tunnel['encapsulation'] in ['erspan', 'ip6erspan']: + if dict_search('parameters.ip.key', tunnel) == None: + raise ConfigError('ERSPAN requires ip key parameter!') + + # this is a default field + ver = int(tunnel['parameters']['erspan']['version']) + if ver == 1: + if 'hw_id' in tunnel['parameters']['erspan']: + raise ConfigError('ERSPAN version 1 does not support hw-id!') + if 'direction' in tunnel['parameters']['erspan']: + raise ConfigError('ERSPAN version 1 does not support direction!') + elif ver == 2: + if 'idx' in tunnel['parameters']['erspan']: + raise ConfigError('ERSPAN version 2 does not index parameter!') + if 'direction' not in tunnel['parameters']['erspan']: + raise ConfigError('ERSPAN version 2 requires direction to be set!') verify_mtu_ipv6(tunnel) verify_address(tunnel) verify_vrf(tunnel) - verify_tunnel(tunnel) if 'source_interface' in tunnel: verify_interface_exists(tunnel['source_interface']) @@ -92,7 +109,6 @@ def verify(tunnel): if tunnel['encapsulation'] in ['ipip6', 'ip6ip6', 'ip6gre']: raise ConfigError('Can not disable PMTU discovery for given encapsulation') - def generate(tunnel): return None @@ -108,8 +124,8 @@ def apply(tunnel): encap = dict_search('linkinfo.info_kind', tmp) remote = dict_search('linkinfo.info_data.remote', tmp) - if ('deleted' in tunnel or 'encapsulation_changed' in tunnel or - encap in ['gretap', 'ip6gretap'] or remote in ['any']): + if ('deleted' in tunnel or 'encapsulation_changed' in tunnel or encap in + ['gretap', 'ip6gretap', 'erspan', 'ip6erspan'] or remote in ['any']): if interface in interfaces(): tmp = Interface(interface) tmp.remove() |