mirror of
https://github.com/CumulusNetworks/ifupdown2.git
synced 2024-05-06 15:54:50 +00:00
addons: tunnel: support non-disruptive config change
Current design destroys existing tunnel when a config change is detected. This behaviour causes traffic loss. Signed-off-by: Julien Fortin <jfortin@nvidia.com>
This commit is contained in:
@ -155,6 +155,7 @@ class tunnel(Addon, moduleBase):
|
||||
}.get(link_kind, lambda x: {})(self.cache.get_link_info_data(ifname))
|
||||
|
||||
def _up(self, ifaceobj):
|
||||
ifname = ifaceobj.name
|
||||
attr_map = {
|
||||
# attr_name -> ip route param name
|
||||
'tunnel-local': 'local',
|
||||
@ -181,26 +182,32 @@ class tunnel(Addon, moduleBase):
|
||||
if tos and tos != 'inherit':
|
||||
attrs_mapped['tos'] = "{:x}".format(int(tos))
|
||||
|
||||
link_exists = self.cache.link_exists(ifname)
|
||||
|
||||
# Create the tunnel if it doesn't exist yet...
|
||||
if not self.cache.link_exists(ifaceobj.name):
|
||||
self.iproute2.tunnel_create(ifaceobj.name, mode, attrs_mapped)
|
||||
if not link_exists:
|
||||
self.iproute2.tunnel_create(ifname, mode, attrs_mapped)
|
||||
return
|
||||
|
||||
# If it's present, check if there were changes
|
||||
current_mode = self.cache.get_link_kind(ifaceobj.name)
|
||||
current_attrs = self.get_linkinfo_attrs(ifaceobj.name, current_mode)
|
||||
current_mode = self.cache.get_link_kind(ifname)
|
||||
current_attrs = self.get_linkinfo_attrs(ifname, current_mode)
|
||||
|
||||
self.convert_user_config_to_ipnetwork(attrs, "tunnel-local")
|
||||
self.convert_user_config_to_ipnetwork(attrs, "tunnel-endpoint")
|
||||
|
||||
try:
|
||||
if current_attrs and current_mode != mode or self._has_config_changed(current_attrs, attrs):
|
||||
# Mode and some other changes are not possible without recreating the interface,
|
||||
# so just recreate it IFF there have been changes.
|
||||
self.netlink.link_del(ifaceobj.name)
|
||||
self.iproute2.tunnel_create(ifaceobj.name, mode, attrs_mapped)
|
||||
|
||||
if link_exists and current_mode != mode:
|
||||
# Mode and some other changes are not possible without recreating the interface,
|
||||
# so just recreate it IFF there have been changes.
|
||||
self.netlink.link_del(ifaceobj.name)
|
||||
link_exists = False
|
||||
|
||||
self.iproute2.tunnel_create(ifaceobj.name, mode, attrs_mapped, link_exists=link_exists)
|
||||
except Exception as e:
|
||||
self.log_warn(str(e))
|
||||
self.log_error(str(e), ifaceobj)
|
||||
|
||||
def _down(self, ifaceobj):
|
||||
if not ifupdownflags.flags.PERFMODE and not self.cache.link_exists(ifaceobj.name):
|
||||
|
@ -443,18 +443,20 @@ class IPRoute2(Cache, Requirements):
|
||||
# TUNNEL
|
||||
############################################################################
|
||||
|
||||
def tunnel_create(self, tunnelname, mode, attrs=None):
|
||||
if self.cache.link_exists(tunnelname):
|
||||
return
|
||||
def tunnel_create(self, tunnelname, mode, attrs=None, link_exists=False):
|
||||
if link_exists:
|
||||
op = "change"
|
||||
else:
|
||||
op = "add"
|
||||
|
||||
cmd = []
|
||||
if "6" in mode:
|
||||
cmd.append("-6")
|
||||
|
||||
if mode in ["gretap"]:
|
||||
cmd.append("link add %s type %s" % (tunnelname, mode))
|
||||
cmd.append("link %s %s type %s" % (op, tunnelname, mode))
|
||||
else:
|
||||
cmd.append("tunnel add %s mode %s" % (tunnelname, mode))
|
||||
cmd.append("tunnel %s %s mode %s" % (op, tunnelname, mode))
|
||||
|
||||
if attrs:
|
||||
for k, v in attrs.items():
|
||||
|
Reference in New Issue
Block a user