From 99ce689411b78f031ebeac19beb0f94e631c27c7 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Tue, 8 Mar 2016 20:40:02 -0800 Subject: [PATCH] ifupdownmain: squash multiple iface stanzas for the same interface Ticket: Reviewed By: CCR-4268 Testing Done: Tested squashing of interfaces with multiple iface stanzas This is controlled by ifaceobj_squash config variable in /etc/network/ifupdown2/ifupdown2.conf. With ifaceobj_squash=1, ifquery and all commands will output squashed interfaces. $cat /etc/network/interfaces auto swp3 iface swp3 mtu 9000 auto swp3 iface swp3 inet static address 10.0.17.3/24 auto swp3 iface swp3 inet static address 10.0.18.3/24 address 2000:1000:1000:1000:3::5/128 $ifquery -a auto lo iface lo inet loopback auto eth0 iface eth0 inet dhcp auto swp3 iface swp3 mtu 9000 address 10.0.17.3/24 address 10.0.18.3/24 address 2000:1000:1000:1000:3::5/128 When and why do we need this ? - If we preserve multiple ifaceobjects for the same iface, it gets tricky in some cases to set default policy values because the addon module run methods are called on each ifaceobject. - Each ifaceobject belonging to the same interface is treated as a separate interface. It is difficult to remember things accross addon module run methods - we have a few hacks in place which we would like to get rid of Why not turn it on by default ? - still debating about it. Dont want to break existing scripts with change of output. Will get some feedback before I switch the default to squash. --- config/ifupdown2.conf | 5 +++++ ifupdown/iface.py | 10 ++++++++++ ifupdown/ifupdownmain.py | 14 +++++++++++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/config/ifupdown2.conf b/config/ifupdown2.conf index cc7fd0f..d5b808a 100644 --- a/config/ifupdown2.conf +++ b/config/ifupdown2.conf @@ -53,3 +53,8 @@ ifreload_down_changed=0 # squash all addr config when you process the first interface addr_config_squash=0 + +# squash iface config into one when you have multiple +# ifaces stanzas for an interface +ifaceobj_squash=0 + diff --git a/ifupdown/iface.py b/ifupdown/iface.py index 2f7fd1c..e7e2e89 100644 --- a/ifupdown/iface.py +++ b/ifupdown/iface.py @@ -527,6 +527,16 @@ class iface(): if v != dstiface.config.get(k)): return False return True + def squash(self, newifaceobj): + """ This squashes the iface object """ + for attrname, attrlist in newifaceobj.config.iteritems(): + # if allready present add it to the list + # else add it to the end of the dictionary + # We need to maintain order. + if self.config.get(attrname): + self.config[attrname].extend(attrlist) + else: + self.config.update([(attrname, attrlist)]) def __getstate__(self): odict = self.__dict__.copy() diff --git a/ifupdown/ifupdownmain.py b/ifupdown/ifupdownmain.py index b759f68..686b6bf 100644 --- a/ifupdown/ifupdownmain.py +++ b/ifupdown/ifupdownmain.py @@ -262,6 +262,9 @@ class ifupdownMain(ifupdownBase): 'state changes will be delayed till the ' + 'masters admin state change.') + self._ifaceobj_squash = True if self.config.get( + 'ifaceobj_squash', '0') == '1' else False + # initialize global config object with config passed by the user # This makes config available to addon modules ifupdownConfig.config = self.config @@ -661,9 +664,14 @@ class ifupdownMain(ifupdownBase): ifaceobj.link_type = ifaceLinkType.LINK_NA currentifaceobjlist = self.ifaceobjdict.get(ifaceobj.name) if not currentifaceobjlist: - self.ifaceobjdict[ifaceobj.name]= [ifaceobj] - ifaceobj.flags |= ifaceobj.YOUNGEST_SIBLING - return + self.ifaceobjdict[ifaceobj.name]= [ifaceobj] + if not self._ifaceobj_squash: + ifaceobj.flags |= ifaceobj.YOUNGEST_SIBLING + return + if self._ifaceobj_squash: + # squash with old iface object + currentifaceobjlist[0].squash(ifaceobj) + return if ifaceobj.compare(currentifaceobjlist[0]): self.logger.warn('duplicate interface %s found' %ifaceobj.name) return