summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2020-11-20 14:05:39 +0100
committerChristian Poessinger <christian@poessinger.com>2020-11-20 14:05:39 +0100
commitfe8d884b564e1758216b6a2db025bf1b22e56fa7 (patch)
treeeb95406b9edcd44cf4ff5ff6240bd75fd4bf49e0
parent7ad026794beee0bc4310a96bac286823283b7fd8 (diff)
downloadvyos-1x-fe8d884b564e1758216b6a2db025bf1b22e56fa7.tar.gz
vyos-1x-fe8d884b564e1758216b6a2db025bf1b22e56fa7.zip
tunnel: T3072: support changing tunnel encapsulation on-the-fly
-rw-r--r--python/vyos/ifconfig/tunnel.py36
-rwxr-xr-xsrc/conf_mode/interfaces-tunnel.py23
2 files changed, 21 insertions, 38 deletions
diff --git a/python/vyos/ifconfig/tunnel.py b/python/vyos/ifconfig/tunnel.py
index 7264b6296..4040187e7 100644
--- a/python/vyos/ifconfig/tunnel.py
+++ b/python/vyos/ifconfig/tunnel.py
@@ -85,7 +85,6 @@ class _Tunnel(Interface):
updates = []
create = ''
- change = ''
delete = ''
ip = [] # AFI of the families which can be used in the tunnel
@@ -107,21 +106,14 @@ class _Tunnel(Interface):
cmd = self.delete.format(**self.config)
return self._cmd(cmd)
- def set_interface(self, option, value):
- try:
- return Interface.set_interface(self, option, value)
- except Exception:
- pass
-
- if value == '':
- # remove the value so that it is not used
- self.config.pop(option, '')
-
- if self.change:
- self._cmd('{} {} {}'.format(
- self.change.format(**self.config), option, value))
- return True
+ def change_options(self):
+ change = 'ip tunnel cha {ifname} mode {type}'
+ # add " option-name option-name-value ..." for all options set
+ options = " ".join(["{} {}".format(k, self.config[k])
+ for k in self.options if k in self.config and self.config[k]])
+ print(options)
+ self._cmd('{} {}'.format(change.format(**self.config), options))
@classmethod
def get_config(cls):
@@ -229,7 +221,6 @@ class GRETapIf(_Tunnel):
updates = ['mtu', ]
create = 'ip link add {ifname} type {type}'
- change = ''
delete = 'ip link del {ifname}'
@@ -255,18 +246,8 @@ class IP6GREIf(_Tunnel):
'mtu', 'multicast', 'allmulticast']
create = 'ip tunnel add {ifname} mode {type}'
- change = 'ip tunnel cha {ifname} mode {type}'
delete = 'ip tunnel del {ifname}'
- # using "ip tunnel change" without using "mode" causes errors
- # sudo ip tunnel add tun100 mode ip6gre local ::1 remote 1::1
- # sudo ip tunnel cha tun100 hoplimit 100
- # *** stack smashing detected ** *: < unknown > terminated
- # sudo ip tunnel cha tun100 local: : 2
- # Error: an IP address is expected rather than "::2"
- # works if mode is explicit
-
-
class IPIPIf(_Tunnel):
"""
IPIP: IP Encapsulation within IP
@@ -289,7 +270,6 @@ class IPIPIf(_Tunnel):
'mtu', 'multicast', 'allmulticast']
create = 'ip tunnel add {ifname} mode {type}'
- change = 'ip tunnel cha {ifname}'
delete = 'ip tunnel del {ifname}'
@@ -314,7 +294,6 @@ class IPIP6If(_Tunnel):
'mtu', 'multicast', 'allmulticast']
create = 'ip -6 tunnel add {ifname} mode {type}'
- change = 'ip -6 tunnel cha {ifname}'
delete = 'ip -6 tunnel del {ifname}'
@@ -350,7 +329,6 @@ class SitIf(_Tunnel):
'mtu', 'multicast', 'allmulticast']
create = 'ip tunnel add {ifname} mode {type}'
- change = 'ip tunnel cha {ifname}'
delete = 'ip tunnel del {ifname}'
diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py
index 78fc9667c..bf643f3d1 100755
--- a/src/conf_mode/interfaces-tunnel.py
+++ b/src/conf_mode/interfaces-tunnel.py
@@ -17,7 +17,7 @@
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
@@ -46,8 +46,8 @@ 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
+ 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
@@ -62,6 +62,9 @@ def get_config(config=None):
if 'mtu' not in tmp:
tunnel['mtu'] = '1476'
+ tmp = leaf_node_changed(conf, ['encapsulation'])
+ if tmp: tunnel.update({'encapsulation_changed': {}})
+
# We must check if our interface is configured to be a DMVPN member
nhrp_base = ['protocols', 'nhrp', 'tunnel']
conf.set_level(nhrp_base)
@@ -123,10 +126,12 @@ def generate(tunnel):
return None
def apply(tunnel):
- if 'deleted' in tunnel:
- tmp = Interface(tunnel['ifname'])
- tmp.remove()
- return None
+ if 'deleted' in tunnel or 'encapsulation_changed' in tunnel:
+ if tunnel['ifname'] in interfaces():
+ tmp = Interface(tunnel['ifname'])
+ tmp.remove()
+ if 'deleted' in tunnel:
+ return None
dispatch = {
'gre': GREIf,
@@ -173,10 +178,10 @@ def apply(tunnel):
if dict_search(our_key, tunnel) and their_key in conf:
conf[their_key] = dict_search(our_key, tunnel)
- # TODO: support encapsulation change per tunnel
-
tun = klass(tunnel['ifname'], **conf)
+ tun.change_options()
tun.update(tunnel)
+
return None
if __name__ == '__main__':