diff options
author | Christian Poessinger <christian@poessinger.com> | 2021-07-25 11:49:05 +0200 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2021-07-25 21:10:25 +0200 |
commit | 7a85dbfb8b97dade658e8213099fc4995ae62ea1 (patch) | |
tree | 0223edb96033a250674ce83b4de9cda419f7ef99 /src/conf_mode | |
parent | e4d697b1d3aad0cb8e81f4c36bcaa4c089195f43 (diff) | |
download | vyos-1x-7a85dbfb8b97dade658e8213099fc4995ae62ea1.tar.gz vyos-1x-7a85dbfb8b97dade658e8213099fc4995ae62ea1.zip |
ifconfig: backport ifconfig framework from 1.4 to support new tunnel options
It is easier to backport the entire vyos.ifconfig library from 1.4 instead of
backporting single pieces which are required to add new feature to the tunnel
interface section.
In addition that both libraries are now back in sync it will become much easier
to backport any other new feature introduced in VyOS 1.4!
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-x | src/conf_mode/interfaces-l2tpv3.py | 33 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-tunnel.py | 109 |
2 files changed, 27 insertions, 115 deletions
diff --git a/src/conf_mode/interfaces-l2tpv3.py b/src/conf_mode/interfaces-l2tpv3.py index 7b3afa058..9b6ddd5aa 100755 --- a/src/conf_mode/interfaces-l2tpv3.py +++ b/src/conf_mode/interfaces-l2tpv3.py @@ -34,7 +34,6 @@ airbag.enable() k_mod = ['l2tp_eth', 'l2tp_netlink', 'l2tp_ip', 'l2tp_ip6'] - def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the @@ -65,15 +64,15 @@ def verify(l2tpv3): interface = l2tpv3['ifname'] - for key in ['local_ip', 'remote_ip', 'tunnel_id', 'peer_tunnel_id', + for key in ['source_address', 'remote', 'tunnel_id', 'peer_tunnel_id', 'session_id', 'peer_session_id']: if key not in l2tpv3: tmp = key.replace('_', '-') - raise ConfigError(f'L2TPv3 {tmp} must be configured!') + raise ConfigError(f'Missing mandatory L2TPv3 option: "{tmp}"!') - if not is_addr_assigned(l2tpv3['local_ip']): - raise ConfigError('L2TPv3 local-ip address ' - '"{local_ip}" is not configured!'.format(**l2tpv3)) + if not is_addr_assigned(l2tpv3['source_address']): + raise ConfigError('L2TPv3 source-address address "{source_address}" ' + 'not configured on any interface!'.format(**l2tpv3)) verify_mtu_ipv6(l2tpv3) verify_address(l2tpv3) @@ -83,34 +82,16 @@ def generate(l2tpv3): return None def apply(l2tpv3): - # This is a special type of interface which needs additional parameters - # when created using iproute2. Instead of passing a ton of arguments, - # use a dictionary provided by the interface class which holds all the - # options necessary. - conf = L2TPv3If.get_config() - # Check if L2TPv3 interface already exists if l2tpv3['ifname'] in interfaces(): # L2TPv3 is picky when changing tunnels/sessions, thus we can simply # always delete it first. - conf['session_id'] = l2tpv3['session_id'] - conf['tunnel_id'] = l2tpv3['tunnel_id'] - l = L2TPv3If(l2tpv3['ifname'], **conf) + l = L2TPv3If(**l2tpv3) l.remove() if 'deleted' not in l2tpv3: - conf['peer_tunnel_id'] = l2tpv3['peer_tunnel_id'] - conf['local_port'] = l2tpv3['source_port'] - conf['remote_port'] = l2tpv3['destination_port'] - conf['encapsulation'] = l2tpv3['encapsulation'] - conf['local_address'] = l2tpv3['local_ip'] - conf['remote_address'] = l2tpv3['remote_ip'] - conf['session_id'] = l2tpv3['session_id'] - conf['tunnel_id'] = l2tpv3['tunnel_id'] - conf['peer_session_id'] = l2tpv3['peer_session_id'] - # Finally create the new interface - l = L2TPv3If(l2tpv3['ifname'], **conf) + l = L2TPv3If(**l2tpv3) l.update(l2tpv3) return None diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index 3a497bade..e5958e9ae 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -29,15 +29,9 @@ from vyos.configverify import verify_bridge_delete from vyos.configverify import verify_interface_exists from vyos.configverify import verify_mtu_ipv6 from vyos.configverify import verify_vrf +from vyos.configverify import verify_tunnel from vyos.ifconfig import Interface -from vyos.ifconfig import GREIf -from vyos.ifconfig import GRETapIf -from vyos.ifconfig import IPIPIf -from vyos.ifconfig import IP6GREIf -from vyos.ifconfig import IPIP6If -from vyos.ifconfig import IP6IP6If -from vyos.ifconfig import SitIf -from vyos.ifconfig import Sit6RDIf +from vyos.ifconfig import TunnelIf from vyos.template import is_ipv4 from vyos.template import is_ipv6 from vyos.util import get_interface_config @@ -78,48 +72,30 @@ def verify(tunnel): return None - if 'encapsulation' not in tunnel: - raise ConfigError('Must configure the tunnel encapsulation for '\ - '{ifname}!'.format(**tunnel)) + verify_tunnel(tunnel) verify_mtu_ipv6(tunnel) verify_address(tunnel) verify_vrf(tunnel) - if 'local_ip' not in tunnel and 'dhcp_interface' not in tunnel: - raise ConfigError('local-ip is mandatory for tunnel') - - if 'remote_ip' not in tunnel and tunnel['encapsulation'] != 'gre': - raise ConfigError('remote-ip is mandatory for tunnel') - - if {'local_ip', 'dhcp_interface'} <= set(tunnel): - raise ConfigError('Can not use both local-ip and dhcp-interface') - - if tunnel['encapsulation'] in ['ipip6', 'ip6ip6', 'ip6gre']: - error_ipv6 = 'Encapsulation mode requires IPv6' - if 'local_ip' in tunnel and not is_ipv6(tunnel['local_ip']): - raise ConfigError(f'{error_ipv6} local-ip') + if 'source_interface' in tunnel: + verify_interface_exists(tunnel['source_interface']) - if 'remote_ip' in tunnel and not is_ipv6(tunnel['remote_ip']): - raise ConfigError(f'{error_ipv6} remote-ip') - else: - error_ipv4 = 'Encapsulation mode requires IPv4' - if 'local_ip' in tunnel and not is_ipv4(tunnel['local_ip']): - raise ConfigError(f'{error_ipv4} local-ip') + # TTL != 0 and nopmtudisc are incompatible, parameters and ip use default + # values, thus the keys are always present. + if dict_search('parameters.ip.no_pmtu_discovery', tunnel) != None: + if dict_search('parameters.ip.ttl', tunnel) != '0': + raise ConfigError('Disabled PMTU requires TTL set to "0"!') + if tunnel['encapsulation'] in ['ipip6', 'ip6ip6', 'ip6gre']: + raise ConfigError('Can not disable PMTU discovery for given encapsulation') - if 'remote_ip' in tunnel and not is_ipv4(tunnel['remote_ip']): - raise ConfigError(f'{error_ipv4} remote-ip') + if dict_search('parameters.ip.ignore_df', tunnel) != None: + if tunnel['encapsulation'] not in ['gretap']: + raise ConfigError('Option ignore-df can only be used on GRETAP tunnels!') - if tunnel['encapsulation'] in ['sit', 'gre-bridge']: - if 'source_interface' in tunnel: - raise ConfigError('Option source-interface can not be used with ' \ - 'encapsulation "sit" or "gre-bridge"') - elif tunnel['encapsulation'] == 'gre': - if 'local_ip' in tunnel and is_ipv6(tunnel['local_ip']): - raise ConfigError('Can not use local IPv6 address is for mGRE tunnels') + if dict_search('parameters.ip.no_pmtu_discovery', tunnel) == None: + raise ConfigError('Option ignore-df requires path MTU discovery to be disabled!') - if 'source_interface' in tunnel: - verify_interface_exists(tunnel['source_interface']) def generate(tunnel): return None @@ -136,60 +112,15 @@ 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'] or remote in ['any']): if interface in interfaces(): tmp = Interface(interface) tmp.remove() if 'deleted' in tunnel: return None - dispatch = { - 'gre': GREIf, - 'gre-bridge': GRETapIf, - 'ipip': IPIPIf, - 'ipip6': IPIP6If, - 'ip6ip6': IP6IP6If, - 'ip6gre': IP6GREIf, - 'sit': SitIf, - } - - # We need to re-map the tunnel encapsulation proto to a valid interface class - encap = tunnel['encapsulation'] - klass = dispatch[encap] - - # This is a special type of interface which needs additional parameters - # when created using iproute2. Instead of passing a ton of arguments, - # use a dictionary provided by the interface class which holds all the - # options necessary. - conf = klass.get_config() - - # Copy/re-assign our dictionary values to values understood by the - # derived _Tunnel classes - mapping = { - # this : get_config() - 'local_ip' : 'local', - 'remote_ip' : 'remote', - 'source_interface' : 'dev', - 'parameters.ip.ttl' : 'ttl', - 'parameters.ip.tos' : 'tos', - 'parameters.ip.key' : 'key', - } - - # Add additional IPv6 options if tunnel is IPv6 aware - if tunnel['encapsulation'] in ['ipip6', 'ip6ip6', 'ip6gre']: - mappingv6 = { - # this : get_config() - 'parameters.ipv6.encaplimit' : 'encaplimit' - } - mapping.update(mappingv6) - - for our_key, their_key in mapping.items(): - if dict_search(our_key, tunnel) and their_key in conf: - conf[their_key] = dict_search(our_key, tunnel) - - tun = klass(interface, **conf) - tun.change_options() + tun = TunnelIf(**tunnel) tun.update(tunnel) return None |