mirror of
https://github.com/CumulusNetworks/ifupdown2.git
synced 2024-05-06 15:54:50 +00:00
ifupdownmain: redo shared dependent checks
Ticket: CM-10027 Reviewed By: julien, nikhil Testing Done: Tested with an interfaces file with shared dependents In the process of fixing this saw a few more issues with link kind handing. Its better to separate kind from interface private flags like bond slave and bridge port. this patch cleans up all that handling. Example errors: error: misconfig..? swp5.2 vrfslave is enslaved to multiple interfaces ['vrf1012', 'br2'] error: misconfig..? swp5.2 bridgeport is enslaved to multiple interfaces ['vrf1012', 'br2']
This commit is contained in:
@@ -128,8 +128,10 @@ class address(moduleBase):
|
||||
if not addrs:
|
||||
continue
|
||||
|
||||
if ((ifaceobj.role & ifaceRole.SLAVE) or
|
||||
(ifaceobj.link_kind & ifaceLinkKind.BRIDGE_VLAN_AWARE)):
|
||||
if (((ifaceobj.role & ifaceRole.SLAVE) and
|
||||
not (ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE)) or
|
||||
((ifaceobj.link_kind & ifaceLinkKind.BRIDGE) and
|
||||
(ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_VLAN_AWARE))):
|
||||
# we must not configure an IP address if the interface is
|
||||
# enslaved or is a VLAN AWARE BRIDGE
|
||||
self.logger.info('%s: ignoring ip address. Interface is '
|
||||
|
@@ -244,7 +244,8 @@ class bridge(moduleBase):
|
||||
ifaceobj.link_kind |= ifaceLinkKind.BRIDGE
|
||||
# for special vlan aware bridges, we need to add another bit
|
||||
if ifaceobj.get_attr_value_first('bridge-vlan-aware') == 'yes':
|
||||
ifaceobj.link_kind |= ifaceLinkKind.BRIDGE_VLAN_AWARE
|
||||
ifaceobj.link_kind |= ifaceLinkKind.BRIDGE
|
||||
ifaceobj.link_privflags |= ifaceLinkPrivFlags.BRIDGE_VLAN_AWARE
|
||||
ifaceobj.role |= ifaceRole.MASTER
|
||||
ifaceobj.dependency_type = ifaceDependencyType.MASTER_SLAVE
|
||||
return self.parse_port_list(ifaceobj.name,
|
||||
@@ -987,7 +988,7 @@ class bridge(moduleBase):
|
||||
add_port = False
|
||||
bridgename = self.ipcmd.bridge_port_get_bridge_name(ifaceobj.name)
|
||||
if (not bridgename and
|
||||
(ifaceobj.link_kind & ifaceLinkKind.BRIDGE_PORT)):
|
||||
(ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_PORT)):
|
||||
# get bridgename and add port to bridge
|
||||
bridgename = self._get_bridgename(ifaceobj)
|
||||
add_port = True
|
||||
|
@@ -169,7 +169,7 @@ class vrf(moduleBase):
|
||||
if not vrf_iface_name:
|
||||
return None
|
||||
ifaceobj.link_type = ifaceLinkType.LINK_SLAVE
|
||||
ifaceobj.link_kind |= ifaceLinkKind.VRF_SLAVE
|
||||
ifaceobj.link_privflags |= ifaceLinkPrivFlags.VRF_SLAVE
|
||||
|
||||
return [vrf_iface_name]
|
||||
|
||||
|
@@ -26,10 +26,9 @@ class ifaceStatusUserStrs():
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
class ifaceType():
|
||||
UNKNOWN = 0x0
|
||||
IFACE = 0x1
|
||||
BRIDGE_VLAN = 0x2
|
||||
|
||||
UNKNOWN = 0x00
|
||||
IFACE = 0x01
|
||||
BRIDGE_VLAN = 0x10
|
||||
|
||||
class ifaceRole():
|
||||
""" ifaceRole is used to classify the ifaceobj.role of
|
||||
@@ -37,9 +36,9 @@ class ifaceRole():
|
||||
with bond-slaves or bridge-ports. A bond in a bridge
|
||||
is both a master and slave (0x3)
|
||||
"""
|
||||
UNKNOWN = 0x0
|
||||
SLAVE = 0x1
|
||||
MASTER = 0x2
|
||||
UNKNOWN = 0x00
|
||||
SLAVE = 0x01
|
||||
MASTER = 0x10
|
||||
|
||||
class ifaceLinkKind():
|
||||
""" ifaceLlinkKind is used to identify interfaces
|
||||
@@ -47,16 +46,47 @@ class ifaceLinkKind():
|
||||
bond have an ifaceobj.role attribute of SLAVE and the bridge or
|
||||
bond itself has ifaceobj.role of MASTER.
|
||||
"""
|
||||
UNKNOWN = 0x0
|
||||
BRIDGE = 0x1
|
||||
BOND = 0x2
|
||||
VLAN = 0x4
|
||||
VXLAN = 0x8
|
||||
BRIDGE_VLAN_AWARE = 0x10
|
||||
BRIDGE_PORT = 0x20
|
||||
BOND_SLAVE = 0x40
|
||||
VRF = 0x80
|
||||
VRF_SLAVE = 0x100
|
||||
UNKNOWN = 0x000000
|
||||
BRIDGE = 0x000001
|
||||
BOND = 0x000010
|
||||
VLAN = 0x000100
|
||||
VXLAN = 0x001000
|
||||
VRF = 0x010000
|
||||
|
||||
class ifaceLinkPrivFlags():
|
||||
""" This corresponds to kernel netdev->priv_flags
|
||||
and can be BRIDGE_PORT, BOND_SLAVE etc """
|
||||
UNKNOWN = 0x0000
|
||||
BRIDGE_PORT = 0x0001
|
||||
BOND_SLAVE = 0x0010
|
||||
VRF_SLAVE = 0x0100
|
||||
BRIDGE_VLAN_AWARE = 0x1000
|
||||
|
||||
@classmethod
|
||||
def get_str(cls, flag):
|
||||
if flag == cls.UNKNOWN:
|
||||
return 'unknown'
|
||||
elif flag == cls.BRIDGE_PORT:
|
||||
return 'bridge port'
|
||||
elif flag == cls.BOND_SLAVE:
|
||||
return 'bond slave'
|
||||
elif flag == cls.VRF_SLAVE:
|
||||
return 'vrf slave'
|
||||
elif flag == cls.BRIDGE_VLAN_AWARE:
|
||||
return 'vlan aware bridge'
|
||||
|
||||
@classmethod
|
||||
def get_all_str(cls, flags):
|
||||
str = ''
|
||||
if (flags & cls.BRIDGE_PORT):
|
||||
str += 'bridgeport '
|
||||
if (flags == cls.BOND_SLAVE):
|
||||
str += 'bondslave '
|
||||
elif flags == cls.VRF_SLAVE:
|
||||
str += 'vrfslave '
|
||||
elif flags == cls.BRIDGE_VLAN_AWARE:
|
||||
str += 'vlanawarebridge '
|
||||
return str
|
||||
|
||||
class ifaceLinkType():
|
||||
LINK_UNKNOWN = 0x0
|
||||
@@ -344,6 +374,7 @@ class iface():
|
||||
self.realname = None
|
||||
self.link_type = ifaceLinkType.LINK_UNKNOWN
|
||||
self.link_kind = ifaceLinkKind.UNKNOWN
|
||||
self.link_privflags = ifaceLinkPrivFlags.UNKNOWN
|
||||
|
||||
# The below attribute is used to disambiguate between various
|
||||
# types of dependencies
|
||||
@@ -561,6 +592,7 @@ class iface():
|
||||
del odict['env']
|
||||
del odict['link_type']
|
||||
del odict['link_kind']
|
||||
del odict['link_privflags']
|
||||
del odict['role']
|
||||
del odict['dependency_type']
|
||||
del odict['blacklisted']
|
||||
@@ -584,6 +616,7 @@ class iface():
|
||||
self.flags |= self._PICKLED
|
||||
self.link_type = ifaceLinkType.LINK_NA
|
||||
self.link_kind = ifaceLinkKind.UNKNOWN
|
||||
self.link_privflags = ifaceLinkPrivFlags.UNKNOWN
|
||||
self.dependency_type = ifaceDependencyType.UNKNOWN
|
||||
self.blacklisted = False
|
||||
|
||||
|
@@ -140,7 +140,7 @@ class ifupdownMain(ifupdownBase):
|
||||
def run_down(self, ifaceobj):
|
||||
# Skip link sets on ifaceobjs of type 'vlan' (used for l2 attrs)
|
||||
# there is no real interface behind it
|
||||
if ifaceobj.kind & ifaceLinkKind.VRF:
|
||||
if ifaceobj.link_kind & ifaceLinkKind.VRF:
|
||||
return
|
||||
if ifaceobj.type == ifaceType.BRIDGE_VLAN:
|
||||
return
|
||||
@@ -417,7 +417,7 @@ class ifupdownMain(ifupdownBase):
|
||||
return self.is_ifaceobj_noconfig(ifaceobj)
|
||||
|
||||
def check_shared_dependents(self, ifaceobj, dlist):
|
||||
""" Check if dlist intersects with any other
|
||||
""" ABSOLETE: Check if dlist intersects with any other
|
||||
interface with slave dependents.
|
||||
example: bond and bridges.
|
||||
This function logs such errors """
|
||||
@@ -439,22 +439,38 @@ class ifupdownMain(ifupdownBase):
|
||||
%(ifaceobj.name, ifacename) +
|
||||
'seem to share dependents/ports %s' %str(list(common)))
|
||||
|
||||
def _set_iface_role(self, ifaceobj, role):
|
||||
if (self.flags.CHECK_SHARED_DEPENDENTS and
|
||||
(ifaceobj.role & ifaceRole.SLAVE) and role == ifaceRole.SLAVE):
|
||||
self.logger.error("misconfig..? %s %s is enslaved to multiple interfaces %s"
|
||||
%(ifaceobj.name,
|
||||
ifaceLinkPrivFlags.get_all_str(ifaceobj.link_privflags), str(ifaceobj.upperifaces)))
|
||||
ifaceobj.set_status(ifaceStatus.ERROR)
|
||||
return
|
||||
ifaceobj.role = role
|
||||
|
||||
def _set_iface_role_n_kind(self, ifaceobj, upperifaceobj):
|
||||
|
||||
if (upperifaceobj.link_kind & ifaceLinkKind.BOND):
|
||||
ifaceobj.role |= ifaceRole.SLAVE
|
||||
ifaceobj.link_kind |= ifaceLinkKind.BOND_SLAVE
|
||||
self._set_iface_role(ifaceobj, ifaceRole.SLAVE)
|
||||
ifaceobj.link_privflags |= ifaceLinkPrivFlags.BOND_SLAVE
|
||||
|
||||
if (upperifaceobj.link_kind & ifaceLinkKind.BRIDGE):
|
||||
ifaceobj.role |= ifaceRole.SLAVE
|
||||
ifaceobj.link_kind |= ifaceLinkKind.BRIDGE_PORT
|
||||
self._set_iface_role(ifaceobj, ifaceRole.SLAVE)
|
||||
ifaceobj.link_privflags |= ifaceLinkPrivFlags.BRIDGE_PORT
|
||||
|
||||
# vrf masters get processed after slaves, which means
|
||||
# check both link_kind vrf and vrf slave
|
||||
if ((upperifaceobj.link_kind & ifaceLinkKind.VRF) or
|
||||
(ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE)):
|
||||
self._set_iface_role(ifaceobj, ifaceRole.SLAVE)
|
||||
ifaceobj.link_privflags |= ifaceLinkPrivFlags.VRF_SLAVE
|
||||
if self._link_master_slave:
|
||||
if upperifaceobj.link_type == ifaceLinkType.LINK_MASTER:
|
||||
ifaceobj.link_type = ifaceLinkType.LINK_SLAVE
|
||||
else:
|
||||
upperifaceobj.link_type = ifaceLinkType.LINK_NA
|
||||
ifaceobj.link_type = ifaceLinkType.LINK_NA
|
||||
if (ifaceobj.link_kind == ifaceLinkKind.BOND_SLAVE and
|
||||
len(ifaceobj.upperifaces) > 1):
|
||||
self.logger.warn("misconfig..? bond slave \'%s\' is enslaved to multiple interfaces %s" %(ifaceobj.name, str(ifaceobj.upperifaces)))
|
||||
|
||||
def dump_iface_dependency_info(self):
|
||||
""" debug funtion to print raw dependency
|
||||
@@ -485,10 +501,6 @@ class ifupdownMain(ifupdownBase):
|
||||
"""
|
||||
del_list = []
|
||||
|
||||
if (upperifaceobj.dependency_type == ifaceDependencyType.MASTER_SLAVE
|
||||
and self.flags.CHECK_SHARED_DEPENDENTS):
|
||||
self.check_shared_dependents(upperifaceobj, dlist)
|
||||
|
||||
for d in dlist:
|
||||
dilist = self.get_ifaceobjs(d)
|
||||
if not dilist:
|
||||
@@ -630,6 +642,7 @@ class ifupdownMain(ifupdownBase):
|
||||
ifaceobj = self.get_ifaceobj_first(i)
|
||||
if not ifaceobj:
|
||||
continue
|
||||
|
||||
if ifaceobj.blacklisted and not ifaceobj.upperifaces:
|
||||
# if blacklisted and was not picked up as a
|
||||
# dependent of a upper interface, delete the
|
||||
@@ -649,6 +662,7 @@ class ifupdownMain(ifupdownBase):
|
||||
pass
|
||||
self.logger.debug("populate_dependency_info: deleting blacklisted interface %s" %i)
|
||||
del self.dependency_graph[i]
|
||||
continue
|
||||
|
||||
def _check_config_no_repeats(self, ifaceobj):
|
||||
""" check if object has an attribute that is
|
||||
|
Reference in New Issue
Block a user