diff options
author | Christian Poessinger <christian@poessinger.com> | 2020-11-20 14:05:39 +0100 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2020-11-20 14:05:39 +0100 |
commit | fe8d884b564e1758216b6a2db025bf1b22e56fa7 (patch) | |
tree | eb95406b9edcd44cf4ff5ff6240bd75fd4bf49e0 | |
parent | 7ad026794beee0bc4310a96bac286823283b7fd8 (diff) | |
download | vyos-1x-fe8d884b564e1758216b6a2db025bf1b22e56fa7.tar.gz vyos-1x-fe8d884b564e1758216b6a2db025bf1b22e56fa7.zip |
tunnel: T3072: support changing tunnel encapsulation on-the-fly
-rw-r--r-- | python/vyos/ifconfig/tunnel.py | 36 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-tunnel.py | 23 |
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__': |