diff options
-rw-r--r-- | interface-definitions/interfaces-tunnel.xml.in | 8 | ||||
-rw-r--r-- | python/vyos/ifconfig/tunnel.py | 20 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-tunnel.py | 17 |
3 files changed, 33 insertions, 12 deletions
diff --git a/interface-definitions/interfaces-tunnel.xml.in b/interface-definitions/interfaces-tunnel.xml.in index e1ac60319..a38a73e15 100644 --- a/interface-definitions/interfaces-tunnel.xml.in +++ b/interface-definitions/interfaces-tunnel.xml.in @@ -66,6 +66,14 @@ </constraint> </properties> </leafNode> + <leafNode name="source-interface"> + <properties> + <help>Physical Interface used for underlaying traffic</help> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces.py</script> + </completionHelp> + </properties> + </leafNode> <leafNode name="6rd-prefix"> <properties> <help>6rd network prefix</help> diff --git a/python/vyos/ifconfig/tunnel.py b/python/vyos/ifconfig/tunnel.py index 009a53a82..690b61366 100644 --- a/python/vyos/ifconfig/tunnel.py +++ b/python/vyos/ifconfig/tunnel.py @@ -141,8 +141,8 @@ class GREIf(_Tunnel): default = {'type': 'gre'} required = ['local', ] # mGRE is a GRE without remote endpoint - options = ['local', 'remote', 'ttl', 'tos', 'key'] - updates = ['local', 'remote', 'ttl', 'tos', + options = ['local', 'remote', 'dev', 'ttl', 'tos', 'key'] + updates = ['local', 'remote', 'dev', 'ttl', 'tos', 'mtu', 'multicast', 'allmulticast'] create = 'ip tunnel add {ifname} mode {type}' @@ -189,9 +189,9 @@ class IP6GREIf(_Tunnel): default = {'type': 'ip6gre'} required = ['local', 'remote'] - options = ['local', 'remote', 'encaplimit', + options = ['local', 'remote', 'dev', 'encaplimit', 'hoplimit', 'tclass', 'flowlabel'] - updates = ['local', 'remote', 'encaplimit', + updates = ['local', 'remote', 'dev', 'encaplimit', 'hoplimit', 'tclass', 'flowlabel', 'mtu', 'multicast', 'allmulticast'] @@ -225,8 +225,8 @@ class IPIPIf(_Tunnel): default = {'type': 'ipip'} required = ['local', 'remote'] - options = ['local', 'remote', 'ttl', 'tos', 'key'] - updates = ['local', 'remote', 'ttl', 'tos', + options = ['local', 'remote', 'dev', 'ttl', 'tos', 'key'] + updates = ['local', 'remote', 'dev', 'ttl', 'tos', 'mtu', 'multicast', 'allmulticast'] create = 'ip tunnel add {ifname} mode {type}' @@ -248,9 +248,9 @@ class IPIP6If(_Tunnel): default = {'type': 'ipip6'} required = ['local', 'remote'] - options = ['local', 'remote', 'encaplimit', + options = ['local', 'remote', 'dev', 'encaplimit', 'hoplimit', 'tclass', 'flowlabel'] - updates = ['local', 'remote', 'encaplimit', + updates = ['local', 'remote', 'dev', 'encaplimit', 'hoplimit', 'tclass', 'flowlabel', 'mtu', 'multicast', 'allmulticast'] @@ -286,8 +286,8 @@ class SitIf(_Tunnel): default = {'type': 'sit'} required = ['local', 'remote'] - options = ['local', 'remote', 'ttl', 'tos', 'key'] - updates = ['local', 'remote', 'ttl', 'tos', + options = ['local', 'remote', 'dev', 'ttl', 'tos', 'key'] + updates = ['local', 'remote', 'dev', 'ttl', 'tos', 'mtu', 'multicast', 'allmulticast'] create = 'ip tunnel add {ifname} mode {type}' diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index 2ab75fcec..9c0c42414 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -255,7 +255,9 @@ default_config_data = { 'ipv6_forwarding': 1, 'ipv6_dad_transmits': 1, # internal + 'interfaces': [], 'tunnel': {}, + 'bridge': '', # the following names are exactly matching the name # for the ip command and must not be changed 'ifname': '', @@ -264,6 +266,7 @@ default_config_data = { 'mtu': '1476', 'local': '', 'remote': '', + 'dev': '', 'multicast': 'disable', 'allmulticast': 'disable', 'ttl': '255', @@ -275,7 +278,6 @@ default_config_data = { 'tclass': 'inherit', '6rd-prefix': '', '6rd-relay-prefix': '', - 'bridge': '', } # dict name -> config name, multiple values, default @@ -286,6 +288,7 @@ mapping = { 'local': ('local-ip', False, None), 'remote': ('remote-ip', False, None), 'multicast': ('multicast', False, None), + 'dev': ('source-interface', False, None), 'ttl': ('parameters ip ttl', False, None), 'tos': ('parameters ip tos', False, None), 'key': ('parameters ip key', False, None), @@ -408,6 +411,7 @@ def get_config(): # check for bridges options['bridge'] = is_bridge_member(conf, ifname) + options['interfaces'] = interfaces() for name in ct: tunnel = ct[name] @@ -483,6 +487,7 @@ def verify(conf): afi_remote = get_afi(tun_remote) tun_ismgre = iftype == 'gre' and not options['remote'] tun_is6rd = iftype == 'sit' and options['6rd-prefix'] + tun_dev = options['dev'] # incompatible options @@ -492,6 +497,9 @@ def verify(conf): if tun_local and options['dhcp-interface']: raise ConfigError(f'Must configure only one of local-ip or dhcp-interface for tunnel {iftype} {ifname}') + if tun_dev and iftype in ('gre-bridge', 'sit'): + raise ConfigError(f'source interface can not be used with {iftype} {ifname}') + # tunnel endpoint if afi_local != afi_remote: @@ -519,9 +527,14 @@ def verify(conf): # vrf check vrf = options['vrf'] - if vrf and vrf not in interfaces(): + if vrf and vrf not in options['interfaces']: raise ConfigError(f'VRF "{vrf}" does not exist') + # source-interface check + + if tun_dev and tun_dev not in options['interfaces']: + raise ConfigError(f'device "{dev}" does not exist') + # tunnel encapsulation check convert = { |