From 44f766a7880e9264487e62f4aacc9f4f635219ed Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Mon, 5 Apr 2021 23:23:14 +0200 Subject: 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. --- src/conf_mode/interfaces-erspan.py | 108 ------------------------------------- src/conf_mode/interfaces-tunnel.py | 30 ++++++++--- 2 files changed, 23 insertions(+), 115 deletions(-) delete mode 100755 src/conf_mode/interfaces-erspan.py (limited to 'src/conf_mode') 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 . - -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() -- cgit v1.2.3