From cd4d44a2b15f649ad046a5bdadc86ffce88e74a9 Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Thu, 24 Mar 2022 22:02:31 +0000 Subject: [PATCH] Implement Prune Step 3 -- remove BVI and Loopback interfaces and IPs that are not in the config --- README.md | 9 +++------ vpp/reconciler.py | 48 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 406e8c3..a3be6b0 100644 --- a/README.md +++ b/README.md @@ -141,15 +141,12 @@ and finally for all interfaces, they are synchronized with the configuratino (IP for example if `e0` was paired with interface Te1/0/0 but has moved to interface Te1/0/1. 1. Retrieve all Loopbacks and BVIs from VPP * Remove those that do not exist in the config - * For BVIs, remove those that exist in the config but are associated with a different - bridge-domain, for example if `bvi123` exists in bridge-domain 10, but it has moved to - bridge-domain 123. * Remove all IP addresses that are not in the config 1. Retrieve all Bridge Domains from VPP * Remove those that do not exist in the config - * Remove all IP addresses that are not in the config - * Remove all member interfaces that are not in the config, return them to L3 mode - * Remove tag-rewrite options on member interfaces if they have encapsulation + * Remove all member interfaces (including BVIs) that are not in the config, return them to + L3 mode + * Remove tag-rewrite options on removed member interfaces if they have encapsulation 1. For L2 Cross Connects from VPP * For interfaces that do not exist in the config (either as source or target): * Return the interface to L3 mode diff --git a/vpp/reconciler.py b/vpp/reconciler.py index 6d83076..9b3e455 100644 --- a/vpp/reconciler.py +++ b/vpp/reconciler.py @@ -47,18 +47,57 @@ class Reconciler(): """ Remove all addresses from interface ifname, except those in address_list """ idx = self.vpp.config['interface_names'][ifname].sw_if_index for a in self.vpp.config['interface_addresses'][idx]: - self.logger.info("> set interface ip address del %s %s" % (ifname, a)) + if not a in address_list: + self.logger.info("1> set interface ip address del %s %s" % (ifname, a)) + else: + self.logger.debug("Address OK: %s %s" % (ifname, a)) def prune(self): ret = True if not self.prune_addresses_set_interface_down(): self.logger.warning("Could not prune addresses and set interfaces down from VPP that are not in the config") ret = False - if not self.prune_lcp(): + if not self.prune_lcps(): self.logger.warning("Could not prune LCPs from VPP that are not in the config") ret = False + if not self.prune_loopbacks(): + self.logger.warning("Could not prune loopbacks from VPP that are not in the config") + ret = False + if not self.prune_bvis(): + self.logger.warning("Could not prune BVIs from VPP that are not in the config") + ret = False return ret + def prune_loopbacks(self): + for idx, vpp_iface in self.vpp.config['interfaces'].items(): + if vpp_iface.interface_dev_type!='Loopback': + continue + config_ifname, config_iface = loopback.get_by_name(self.cfg, vpp_iface.interface_name) + if not config_iface: + self.logger.info("1> delete loopback interface intfc %s" % vpp_iface.interface_name) + continue + self.logger.debug("Loopback OK: %s" % (vpp_iface.interface_name)) + addresses = [] + if 'addresses' in config_iface: + addresses = config_iface['addresses'] + self.prune_addresses(vpp_iface.interface_name, addresses) + return True + + def prune_bvis(self): + for idx, vpp_iface in self.vpp.config['interfaces'].items(): + if vpp_iface.interface_dev_type!='BVI': + continue + config_ifname, config_iface = bridgedomain.get_by_bvi_name(self.cfg, vpp_iface.interface_name) + if not config_iface: + self.logger.info("1> bvi delete %s" % vpp_iface.interface_name) + continue + self.logger.debug("BVI OK: %s" % (vpp_iface.interface_name)) + addresses = [] + if 'addresses' in config_iface: + addresses = config_iface['addresses'] + self.prune_addresses(vpp_iface.interface_name, addresses) + return True + def __parent_iface_by_encap(self, sup_sw_if_index, outer, dot1ad=True): """ Returns the idx of an interface on a given super_sw_if_index with given dot1q/dot1ad outer and inner-dot1q=0 """ for idx, iface in self.vpp.config['interfaces'].items(): @@ -88,8 +127,7 @@ class Reconciler(): "inner-dot1q": int(inner_dot1q), "exact-match": bool(exact_match) } - - def prune_lcp(self): + def prune_lcps(self): lcps = self.vpp.config['lcps'] ## Remove LCPs for QinX interfaces @@ -217,7 +255,7 @@ class Reconciler(): def prune_addresses_set_interface_down(self): for ifname in self.vpp.get_qinx_interfaces() + self.vpp.get_dot1x_interfaces() + self.vpp.get_bondethernets() + self.vpp.get_vxlan_tunnels() + self.vpp.get_phys(): if not ifname in interface.get_interfaces(self.cfg): - self.logger.info("> set interface state %s down" % ifname) + self.logger.info("1> set interface state %s down" % ifname) self.prune_addresses(ifname, []) return True