Re-order the Pruning flow
1. sub-ints have to be removed before their parent, particularly bondethernets, because destroying BondEthernet0 will cascade destruction of all of its sub-ints. So: - first prune_sub_interfaces() - then prune_bondethernets() - finally prune_phys() 2. for any interface (loop, bvi, sub, phy, bond), prune_addresses() before destroying the interface Update the README with this new flow.
This commit is contained in:
18
README.md
18
README.md
@ -150,19 +150,19 @@ and finally all objects are synchronized with the configuration (IP addresses, M
|
|||||||
* For interfaces that do not exist in the config (either as source or target):
|
* For interfaces that do not exist in the config (either as source or target):
|
||||||
* Return the interface to L3 mode
|
* Return the interface to L3 mode
|
||||||
* Remove tag-rewrite options on if it has encapsulation
|
* Remove tag-rewrite options on if it has encapsulation
|
||||||
|
1. Retrieve all Tunnels from VPP
|
||||||
|
* Remove those that do not exist in the config
|
||||||
|
* Remove all IP addresses that are not in the config
|
||||||
|
1. Retrieve all sub-interfaces from VPP
|
||||||
|
* Starting with QinQ/QinAD, then Dot1Q/Dot1AD:
|
||||||
|
* Remove those that do not exist in the config
|
||||||
|
* Remove those that do exist in the config but have a different encapsulation
|
||||||
|
* Remove all IP addresses that are not in the config
|
||||||
1. Retrieve all BondEthernets from VPP
|
1. Retrieve all BondEthernets from VPP
|
||||||
* Remove those that do not exist in the config
|
* Remove those that do not exist in the config
|
||||||
* Remove all member interfaces that are not in the config
|
* Remove all member interfaces that are not in the config
|
||||||
* Remove all IP addresses that are not in the config
|
* Remove all IP addresses that are not in the config
|
||||||
1. Retrieve all Tunnels from VPP
|
1. And finally, for each PHY interface:
|
||||||
* Remove those that do not exist in the config
|
|
||||||
* Remove all IP addresses that are not in the config
|
|
||||||
1. Retrieve all interfaces from VPP
|
|
||||||
* Starting with QinQ/QinAD, then Dot1Q/Dot1AD, then (BondEthernets, Tunnels):
|
|
||||||
* Remove those that do not exist in the config
|
|
||||||
* Remove those that do exist in the config but have a different encapsulation
|
|
||||||
* Remove all IP addresses that are not in the config
|
|
||||||
* And finally, for each PHY:
|
|
||||||
* Remove all IP addresses that are not in the config
|
* Remove all IP addresses that are not in the config
|
||||||
* If not in the config, return to default (L3 mode, MTU 9000, admin-state down)
|
* If not in the config, return to default (L3 mode, MTU 9000, admin-state down)
|
||||||
|
|
||||||
|
@ -66,13 +66,16 @@ class Reconciler():
|
|||||||
if not self.prune_l2xcs():
|
if not self.prune_l2xcs():
|
||||||
self.logger.warning("Could not prune L2 Cross Connects from VPP")
|
self.logger.warning("Could not prune L2 Cross Connects from VPP")
|
||||||
ret = False
|
ret = False
|
||||||
if not self.prune_bondethernets():
|
|
||||||
self.logger.warning("Could not prune BondEthernets from VPP")
|
|
||||||
ret = False
|
|
||||||
if not self.prune_vxlan_tunnels():
|
if not self.prune_vxlan_tunnels():
|
||||||
self.logger.warning("Could not prune VXLAN Tunnels from VPP")
|
self.logger.warning("Could not prune VXLAN Tunnels from VPP")
|
||||||
ret = False
|
ret = False
|
||||||
if not self.prune_interfaces():
|
if not self.prune_sub_interfaces():
|
||||||
|
self.logger.warning("Could not prune interfaces from VPP")
|
||||||
|
ret = False
|
||||||
|
if not self.prune_bondethernets():
|
||||||
|
self.logger.warning("Could not prune BondEthernets from VPP")
|
||||||
|
ret = False
|
||||||
|
if not self.prune_phys():
|
||||||
self.logger.warning("Could not prune interfaces from VPP")
|
self.logger.warning("Could not prune interfaces from VPP")
|
||||||
ret = False
|
ret = False
|
||||||
return ret
|
return ret
|
||||||
@ -95,6 +98,7 @@ class Reconciler():
|
|||||||
continue
|
continue
|
||||||
config_ifname, config_iface = loopback.get_by_name(self.cfg, vpp_iface.interface_name)
|
config_ifname, config_iface = loopback.get_by_name(self.cfg, vpp_iface.interface_name)
|
||||||
if not config_iface:
|
if not config_iface:
|
||||||
|
self.prune_addresses(vpp_iface.interface_name, [])
|
||||||
self.logger.info("1> delete loopback interface intfc %s" % vpp_iface.interface_name)
|
self.logger.info("1> delete loopback interface intfc %s" % vpp_iface.interface_name)
|
||||||
continue
|
continue
|
||||||
self.logger.debug("Loopback OK: %s" % (vpp_iface.interface_name))
|
self.logger.debug("Loopback OK: %s" % (vpp_iface.interface_name))
|
||||||
@ -111,6 +115,7 @@ class Reconciler():
|
|||||||
continue
|
continue
|
||||||
config_ifname, config_iface = bridgedomain.get_by_bvi_name(self.cfg, vpp_iface.interface_name)
|
config_ifname, config_iface = bridgedomain.get_by_bvi_name(self.cfg, vpp_iface.interface_name)
|
||||||
if not config_iface:
|
if not config_iface:
|
||||||
|
self.prune_addresses(vpp_iface.interface_name, [])
|
||||||
self.logger.info("1> bvi delete %s" % vpp_iface.interface_name)
|
self.logger.info("1> bvi delete %s" % vpp_iface.interface_name)
|
||||||
continue
|
continue
|
||||||
self.logger.debug("BVI OK: %s" % (vpp_iface.interface_name))
|
self.logger.debug("BVI OK: %s" % (vpp_iface.interface_name))
|
||||||
@ -178,6 +183,7 @@ class Reconciler():
|
|||||||
vpp_ifname = bond.interface_name
|
vpp_ifname = bond.interface_name
|
||||||
config_ifname, config_iface = bondethernet.get_by_name(self.cfg, vpp_ifname)
|
config_ifname, config_iface = bondethernet.get_by_name(self.cfg, vpp_ifname)
|
||||||
if not config_iface:
|
if not config_iface:
|
||||||
|
self.prune_addresses(vpp_ifname, [])
|
||||||
for member in self.vpp.config['bondethernet_members'][idx]:
|
for member in self.vpp.config['bondethernet_members'][idx]:
|
||||||
self.logger.info("1> bond del %s" % self.vpp.config['interfaces'][member].interface_name)
|
self.logger.info("1> bond del %s" % self.vpp.config['interfaces'][member].interface_name)
|
||||||
self.logger.info("1> delete bond %s" % (vpp_ifname))
|
self.logger.info("1> delete bond %s" % (vpp_ifname))
|
||||||
@ -214,17 +220,29 @@ class Reconciler():
|
|||||||
self.logger.debug("VXLAN Tunnel OK: %s" % (vpp_ifname))
|
self.logger.debug("VXLAN Tunnel OK: %s" % (vpp_ifname))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def prune_interfaces(self):
|
def prune_sub_interfaces(self):
|
||||||
""" Remove interfaces from VPP if they are not in the config. Start with inner-most (QinQ/QinAD), then
|
""" Remove interfaces from VPP if they are not in the config. Start with inner-most (QinQ/QinAD), then
|
||||||
Dot1Q/Dot1AD, and finally PHY interfaces (which cannot be removed, but their MTU will be set to
|
Dot1Q/Dot1AD."""
|
||||||
the default of 9000, they will have been set down by prune_interfaces_down(). """
|
for vpp_ifname in self.vpp.get_qinx_interfaces() + self.vpp.get_dot1x_interfaces():
|
||||||
for vpp_ifname in self.vpp.get_qinx_interfaces() + self.vpp.get_dot1x_interfaces() + self.vpp.get_phys():
|
|
||||||
vpp_iface = self.vpp.config['interface_names'][vpp_ifname]
|
vpp_iface = self.vpp.config['interface_names'][vpp_ifname]
|
||||||
config_ifname, config_iface = interface.get_by_name(self.cfg, vpp_ifname)
|
config_ifname, config_iface = interface.get_by_name(self.cfg, vpp_ifname)
|
||||||
if not config_iface:
|
if not config_iface:
|
||||||
if vpp_iface.sub_id > 0:
|
self.prune_addresses(vpp_ifname, [])
|
||||||
self.logger.info("1> delete sub %s" % vpp_ifname)
|
self.logger.info("1> delete sub %s" % vpp_ifname)
|
||||||
else:
|
continue
|
||||||
|
addresses = []
|
||||||
|
if 'addresses' in config_iface:
|
||||||
|
addresses = config_iface['addresses']
|
||||||
|
self.prune_addresses(vpp_ifname, addresses)
|
||||||
|
self.logger.debug("Sub Interface OK: %s" % (vpp_ifname))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def prune_phys(self):
|
||||||
|
""" Set default MTU and remove IPs for PHYs that are not in the config. """
|
||||||
|
for vpp_ifname in self.vpp.get_phys():
|
||||||
|
vpp_iface = self.vpp.config['interface_names'][vpp_ifname]
|
||||||
|
config_ifname, config_iface = interface.get_by_name(self.cfg, vpp_ifname)
|
||||||
|
if not config_iface:
|
||||||
## Interfaces were sent DOWN in the prune_interfaces_down() step previously
|
## Interfaces were sent DOWN in the prune_interfaces_down() step previously
|
||||||
self.prune_addresses(vpp_ifname, [])
|
self.prune_addresses(vpp_ifname, [])
|
||||||
if vpp_iface.link_mtu != 9000:
|
if vpp_iface.link_mtu != 9000:
|
||||||
|
Reference in New Issue
Block a user