From b207b83d8c9c5b6b89f9adabfd510e21d91fc169 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 10 Jan 2017 14:59:32 -0800 Subject: [PATCH] vxlan: add new attribute vxlan-purge-remotes to make purging remotes explicit Ticket: CM-13815 Reviewed By: Testing Done: Tested remote purging vxlan purging remotes is a feature where we clean up existing fdb remote entries in favor of the ones specified in the interfaces file. Obviously in precense of an external controller like bgp or vxrd this is not a good thing because these remotes maybe installed by these external controller daemons. This patch makes the purgining behaviour explicit by a new attribute. We will ship with a default policy file which sets vxlan-purge-remotes to no. This also cleans up a bug introduced by fix to CM-13767 where we were trying to delete default remote entry pointing to the local ip. more details below. problem: for static configuration, ifupdown2 has some code to "purge" existing default remote fdb entries and install new ones corresponding to the ones specified in the interfaces file (with vxlan-remoteip). For non-static configuration (ie in presence of an external controller), it skips this "purge"...because these entries maybe added by an external controller. To detect that there is no external controller running..., today it checks if the vxrd process is running or not. We need to extend this check to now include bgp (for evpn)...and it gets trickier with bgp since just checking the quagga pid is not good. Solution: I would like to make this purging explicit with an attribute. This patch adds a 'vxlan-purge-remotes yes|no' attribute. vxlan remote address purging will take into affect when: vxlan-remoteip attribute is present in the interfaces file or vxlan-purge-remotes is set to 'yes' We will ship a ifupdown2 default policy file to disable purging by default (vxlan-purge-remotes no). For existing customer deployed static configs, since the interfaces file will already have remote entries, this change will behave as existing code (ie purge = yes). For existing vxrd deployments, as long as already deployed interfaces files have no vxlan-remoteip entries, this patch does not change any behavior (can people confirm that existing vxrd deployments have no vxlan-remoteip entries in their interfaces ?) Signed-off-by: Roopa Prabhu --- addons/vxlan.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/addons/vxlan.py b/addons/vxlan.py index 8bdcd9f..328f20c 100644 --- a/addons/vxlan.py +++ b/addons/vxlan.py @@ -9,6 +9,7 @@ from ifupdown.netlink import netlink from ipaddr import IPv4Address import ifupdown.ifupdownflags as ifupdownflags import logging +import ifupdown.policymanager as policymanager import os from sets import Set @@ -42,12 +43,21 @@ class vxlan(moduleBase): 'validrange' : ['0', '4096'], 'example': ['vxlan-ageing 300'], 'default': '300'}, + 'vxlan-purge-remotes' : + {'help' : 'vxlan purge existing remote entries', + 'validvals' : ['yes', 'no'], + 'example': ['vxlan-purge-remotes yes']} }} _clagd_vxlan_anycast_ip = "" def __init__(self, *args, **kargs): moduleBase.__init__(self, *args, **kargs) self.ipcmd = None + purge_remotes = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vxlan-purge-remotes') + if purge_remotes: + self._purge_remotes = utils.get_boolean_from_string(purge_remotes) + else: + self._purge_remotes = False def get_dependent_ifacenames(self, ifaceobj, ifaceobjs_all=None): if self._is_vxlan_device(ifaceobj): @@ -74,7 +84,12 @@ class vxlan(moduleBase): local = ifaceobj.get_attr_value_first('vxlan-local-tunnelip') ageing = ifaceobj.get_attr_value_first('vxlan-ageing') learning = utils.get_onoff_bool(ifaceobj.get_attr_value_first('vxlan-learning')) - + purge_remotes = ifaceobj.get_attr_value_first('vxlan-purge-remotes') + if purge_remotes: + purge_remotes = utils.get_boolean_from_string(purge_remotes) + else: + purge_remotes = self._purge_remotes + if self.ipcmd.link_exists(ifaceobj.name): vxlanattrs = self.ipcmd.get_vxlandev_attrs(ifaceobj.name) # on ifreload do not overwrite anycast_ip to individual ip @@ -91,13 +106,14 @@ class vxlan(moduleBase): ageing=ageing, group=group) - if not systemUtils.is_service_running(None, '/var/run/vxrd.pid'): - remoteips = ifaceobj.get_attr_value('vxlan-remoteip') + remoteips = ifaceobj.get_attr_value('vxlan-remoteip') + if purge_remotes or remoteips: # figure out the diff for remotes and do the bridge fdb updates - # only if provisioned by user and not by vxrd + # only if provisioned by user and not by an vxlan external + # controller. peers = self.ipcmd.get_vxlan_peers(ifaceobj.name, group) - if local: - peers.append(local) + if local and remoteips and local in remoteips: + remoteips.remove(local) cur_peers = set(peers) if remoteips: new_peers = set(remoteips)