1
0
mirror of https://github.com/CumulusNetworks/ifupdown2.git synced 2024-05-06 15:54:50 +00:00

Add check for shared dependents during building dependency list

Ticket: CM-5373
Reviewed By: sam
Testing Done: Tested with shared slaves in bridge and bonds
This commit is contained in:
Roopa Prabhu
2015-04-03 21:24:25 -07:00
parent a4912b996e
commit 45ca0b6d42
4 changed files with 64 additions and 1 deletions

View File

@@ -221,6 +221,7 @@ class bridge(moduleBase):
if ifaceobj.link_type != ifaceLinkType.LINK_NA:
ifaceobj.link_type = ifaceLinkType.LINK_MASTER
ifaceobj.link_kind = ifaceLinkKind.BRIDGE
ifaceobj.dependency_type = ifaceDependencyType.MASTER_SLAVE
return self.parse_port_list(ifaceobj.get_attr_value_first(
'bridge-ports'), ifacenames_all)

View File

@@ -118,7 +118,7 @@ class ifenslave(moduleBase):
return None
slave_list = self.parse_port_list(ifaceobj.get_attr_value_first(
'bond-slaves'), ifacenames_all)
ifaceobj.dependency_type = ifaceDependencyType.MASTER_SLAVE
# Also save a copy for future use
ifaceobj.priv_data = list(slave_list)
if ifaceobj.link_type != ifaceLinkType.LINK_NA:

View File

@@ -33,6 +33,36 @@ class ifaceLinkType():
LINK_MASTER = 0x2
LINK_NA = 0x3
class ifaceDependencyType():
""" Indicates type of dependency.
This class enumerates types of dependency relationships
between interfaces.
iface dependency relationships can be classified
into:
- link
- master/slave
In a 'link' dependency relationship, dependency can be shared
between interfaces. example: swp1.100 and
swp1.200 can both have 'link' swp1. swp1 is also a dependency
of swp1.100 and swp1.200. As you can see dependency
swp1 is shared between swp1.100 and swp1.200.
In a master/slave relationship like bridge and
its ports: eg: bridge br0 and its ports swp1 and swp2.
dependency swp1 and swp2 cannot be shared with any other
interface with the same dependency relationship.
ie, swp1 and swp2 cannot be in a slave relationship
with another interface. Understanding the dependency type is
required for any semantic checks between dependencies.
"""
UNKNOWN = 0x0
LINK = 0x1
MASTER_SLAVE = 0x2
class ifaceStatus():
"""Enumerates iface status """
@@ -230,6 +260,10 @@ class iface():
self.link_type = ifaceLinkType.LINK_UNKNOWN
self.link_kind = ifaceLinkKind.UNKNOWN
# The below attribute is used to disambiguate between various
# types of dependencies
self.dependency_type = ifaceDependencyType.UNKNOWN
def _set_attrs_from_dict(self, attrdict):
self.auto = attrdict.get('auto', False)
self.name = attrdict.get('name')
@@ -416,6 +450,7 @@ class iface():
del odict['env']
del odict['link_type']
del odict['link_kind']
del odict['dependency_type']
return odict
def __setstate__(self, dict):
@@ -434,6 +469,7 @@ class iface():
self.flags |= self._PICKLED
self.link_type = ifaceLinkType.LINK_NA
self.link_kind = ifaceLinkKind.UNKNOWN
self.dependency_type = ifaceDependencyType.UNKNOWN
def dump_raw(self, logger):
indent = ' '

View File

@@ -384,6 +384,27 @@ class ifupdownMain(ifupdownBase):
if not ifaceobj: return True
return self.is_ifaceobj_noconfig(ifaceobj)
def check_shared_dependents(self, ifaceobj, dlist):
""" Check if dlist intersects with any other
interface with slave dependents.
example: bond and bridges.
This function logs such errors """
setdlist = Set(dlist)
for ifacename, ifacedlist in self.dependency_graph.items():
if not ifacedlist:
continue
check_depends = False
iobjs = self.get_ifaceobjs(ifacename)
for i in iobjs:
if (i.dependency_type == ifaceDependencyType.MASTER_SLAVE):
check_depends = True
if check_depends:
common = Set(ifacedlist).intersection(setdlist)
if common:
self.logger.error('iface %s and %s '
%(ifaceobj.name, ifacename) +
'have common dependents %s' %str(list(common)))
def preprocess_dependency_list(self, upperifaceobj, dlist, ops):
""" We go through the dependency list and
delete or add interfaces from the interfaces dict by
@@ -401,6 +422,10 @@ class ifupdownMain(ifupdownBase):
"""
del_list = []
if (upperifaceobj.dependency_type ==
ifaceDependencyType.MASTER_SLAVE):
self.check_shared_dependents(upperifaceobj, dlist)
for d in dlist:
dilist = self.get_ifaceobjs(d)
if not dilist:
@@ -451,6 +476,7 @@ class ifupdownMain(ifupdownBase):
if dlist: ret_dlist.extend(dlist)
return list(set(ret_dlist))
def populate_dependency_info(self, ops, ifacenames=None):
""" recursive function to generate iface dependency info """