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

Fix bridge pvid add/del order

Ticket: CM-5832
Reviewed By: CCR-2875
Testing Done: Tested with test case in the bug and other orders

kernel(upstream and us) does not seem to honor the vidinfo flags
during the deletes. Hence, this reordering becomes necessary.

tested with the example in the bug and also some other examples.

code wise this combines two existing methods but leaves the two existing methods
around for future use. Will remove them if they become completely
unnecessary.
This commit is contained in:
Roopa Prabhu
2015-04-30 12:59:16 -07:00
parent 26434da621
commit 978e17d23f

View File

@ -670,12 +670,90 @@ class bridge(moduleBase):
self.log_warn('%s: failed to set pvid `%s` (%s)'
%(bportifaceobj.name, pvid, str(e)))
def _apply_bridge_vids_and_pvid(self, bportifaceobj, vids, running_vids,
pvid, running_pvid, isbridge):
""" This method is a combination of methods _apply_bridge_vids and
_apply_bridge_port_pvids above. A combined function is
found necessary to do the deletes first and the adds later
because kernel does honor vid info flags during deletes.
"""
try:
if not self._check_vids(bportifaceobj, vids):
return
vids_to_del = []
vids_to_add = vids
pvid_to_del = None
pvid_to_add = pvid if pvid else '1'
if running_vids:
(vids_to_del, vids_to_add) = \
self._diff_vids(vids, running_vids)
if running_pvid:
if running_pvid != pvid:
pvid_to_del = running_pvid
if (pvid_to_del and (pvid_to_del in vids) and
(pvid_to_del not in vids_to_add)):
# kernel deletes dont take into account
# bridge vid flags and its possible that
# the pvid deletes we do end up deleting
# the vids. Be proactive and add the pvid
# to the vid add list if it is in the vids
# and not already part of vids_to_add.
# This helps with a small corner case:
# - running
# pvid 100
# vid 101 102
# - new change is going to move the state to
# pvid 101
# vid 100 102
vids_to_add.append(pvid_to_del)
except Exception, e:
self.log_warn('%s: failed to process vids/pvids'
%bportifaceobj.name + ' vids = %s' %str(vids) +
'pvid = %s ' %pvid + '(%s)' %str(e))
try:
if vids_to_del:
self.ipcmd.bridge_vids_del(bportifaceobj.name,
vids_to_del, isbridge)
except Exception, e:
self.log_warn('%s: failed to del vid `%s` (%s)'
%(bportifaceobj.name, str(vids_to_del), str(e)))
try:
if pvid_to_del:
self.ipcmd.bridge_port_pvid_del(bportifaceobj.name,
pvid_to_del)
except Exception, e:
self.log_warn('%s: failed to del pvid `%s` (%s)'
%(bportifaceobj.name, pvid_to_del, str(e)))
try:
if vids_to_add:
self.ipcmd.bridge_vids_add(bportifaceobj.name,
vids_to_add, isbridge)
except Exception, e:
self.log_warn('%s: failed to set vid `%s` (%s)'
%(bportifaceobj.name, str(vids_to_add), str(e)))
try:
self.ipcmd.bridge_port_pvid_add(bportifaceobj.name, pvid_to_add)
except Exception, e:
self.log_warn('%s: failed to set pvid `%s` (%s)'
%(bportifaceobj.name, pvid_to_add, str(e)))
def _apply_bridge_vlan_aware_port_settings_all(self, bportifaceobj,
bridge_vids=None,
bridge_pvid=None):
running_vidinfo = self._get_running_vidinfo()
vids = None
pvids = None
vids_final = []
pvid_final = None
bport_access = bportifaceobj.get_attr_value_first('bridge-access')
if bport_access:
vids = re.split(r'[\s\t]\s*', bport_access)
@ -689,28 +767,21 @@ class bridge(moduleBase):
if bport_pvids:
pvids = re.split(r'[\s\t]\s*', bport_pvids)
if pvids:
self._apply_bridge_port_pvids(bportifaceobj, pvids[0],
running_vidinfo.get(bportifaceobj.name, {}).get('pvid'))
elif bridge_pvid:
self._apply_bridge_port_pvids(bportifaceobj,
bridge_pvid, running_vidinfo.get(bportifaceobj.name,
{}).get('pvid'))
# XXX: default pvid is already one
#else:
# self._apply_bridge_port_pvids(bportifaceobj,
# '1', running_vidinfo.get(bportifaceobj.name,
# {}).get('pvid'))
if vids:
self._apply_bridge_vids(bportifaceobj, vids,
running_vidinfo.get(bportifaceobj.name,
{}).get('vlan'), False)
vids_final = vids
elif bridge_vids:
self._apply_bridge_vids(bportifaceobj,
bridge_vids, running_vidinfo.get(
bportifaceobj.name, {}).get('vlan'), False)
vids_final = bridge_vids
if pvids:
pvid_final = pvids[0]
elif bridge_pvid:
pvid_final = bridge_pvid
self._apply_bridge_vids_and_pvid(bportifaceobj, vids_final,
running_vidinfo.get(bportifaceobj.name, {}).get('vlan'),
pvid_final,
running_vidinfo.get(bportifaceobj.name, {}).get('pvid'),
False)
def _apply_bridge_port_settings(self, bportifaceobj, bridgename=None,
bridgeifaceobj=None):