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.
This commit is contained in:
Roopa Prabhu 2016-03-08 20:40:02 -08:00
parent d34bbafef9
commit 99ce689411
3 changed files with 26 additions and 3 deletions

View File

@ -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

View File

@ -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()

View File

@ -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