mirror of
https://github.com/CumulusNetworks/ifupdown2.git
synced 2024-05-06 15:54:50 +00:00
minor fixes for ifquery and stp handling
Ticket: CM-3346 Reviewed By: Testing Done: Tested ifupdown2 sanity
This commit is contained in:
115
addons/bridge.py
115
addons/bridge.py
@@ -9,6 +9,7 @@ from ifupdown.iface import *
|
|||||||
from ifupdownaddons.modulebase import moduleBase
|
from ifupdownaddons.modulebase import moduleBase
|
||||||
from ifupdownaddons.bridgeutils import brctl
|
from ifupdownaddons.bridgeutils import brctl
|
||||||
from ifupdownaddons.iproute2 import iproute2
|
from ifupdownaddons.iproute2 import iproute2
|
||||||
|
from collections import Counter
|
||||||
import ifupdown.rtnetlink_api as rtnetlink_api
|
import ifupdown.rtnetlink_api as rtnetlink_api
|
||||||
import itertools
|
import itertools
|
||||||
import re
|
import re
|
||||||
@@ -493,6 +494,12 @@ class bridge(moduleBase):
|
|||||||
stp = ifaceobj.get_attr_value_first('bridge-stp')
|
stp = ifaceobj.get_attr_value_first('bridge-stp')
|
||||||
if stp:
|
if stp:
|
||||||
self.brctlcmd.set_stp(ifaceobj.name, stp)
|
self.brctlcmd.set_stp(ifaceobj.name, stp)
|
||||||
|
else:
|
||||||
|
# If stp not specified and running stp state on, set it to off
|
||||||
|
running_stp_state = self.read_file_oneline(
|
||||||
|
'/sys/class/net/%s/bridge/stp_state' %ifaceobj.name)
|
||||||
|
if running_stp_state and running_stp_state != '0':
|
||||||
|
self.brctlcmd.set_stp(ifaceobj.name, 'no')
|
||||||
# Use the brctlcmd bulk set method: first build a dictionary
|
# Use the brctlcmd bulk set method: first build a dictionary
|
||||||
# and then call set
|
# and then call set
|
||||||
bridgeattrs = { k:v for k,v in
|
bridgeattrs = { k:v for k,v in
|
||||||
@@ -703,7 +710,7 @@ class bridge(moduleBase):
|
|||||||
|
|
||||||
bridge_pvid = ifaceobj.get_attr_value_first('bridge-pvid')
|
bridge_pvid = ifaceobj.get_attr_value_first('bridge-pvid')
|
||||||
if bridge_pvid:
|
if bridge_pvid:
|
||||||
bridge_pvid = re.split(r'[\s\t]\s*', bridge_pvid)
|
bridge_pvid = re.split(r'[\s\t]\s*', bridge_pvid)[0]
|
||||||
else:
|
else:
|
||||||
bridge_pvid = None
|
bridge_pvid = None
|
||||||
|
|
||||||
@@ -825,13 +832,66 @@ class bridge(moduleBase):
|
|||||||
running_attrs['bridge-vids'] = ','.join(running_bridge_vids)
|
running_attrs['bridge-vids'] = ','.join(running_bridge_vids)
|
||||||
return running_attrs
|
return running_attrs
|
||||||
|
|
||||||
def _query_running_vidinfo(self, ifaceobjrunning):
|
def _query_running_vidinfo(self, ifaceobjrunning, ifaceobj_getfunc,
|
||||||
|
bridgeports=None):
|
||||||
running_attrs = {}
|
running_attrs = {}
|
||||||
running_vidinfo = self._get_running_vidinfo()
|
running_vidinfo = self._get_running_vidinfo()
|
||||||
running_bridge_vids = running_vidinfo.get(ifaceobjrunning.name,
|
if not running_vidinfo:
|
||||||
{}).get('vlan')
|
return running_attrs
|
||||||
if running_bridge_vids:
|
|
||||||
running_attrs['bridge-vids'] = ','.join(running_bridge_vids)
|
# 'bridge-vids' under the bridge is all about 'vids' on the port.
|
||||||
|
# so query the ports
|
||||||
|
running_bridgeport_vids = []
|
||||||
|
running_bridgeport_pvids = []
|
||||||
|
for bport in bridgeports:
|
||||||
|
vids = running_vidinfo.get(bport, {}).get('vlan')
|
||||||
|
if vids:
|
||||||
|
running_bridgeport_vids.append(' '.join(vids))
|
||||||
|
pvids = running_vidinfo.get(bport, {}).get('pvid')
|
||||||
|
if pvids:
|
||||||
|
running_bridgeport_pvids.append(pvids[0])
|
||||||
|
|
||||||
|
bridge_vids = None
|
||||||
|
if running_bridgeport_vids:
|
||||||
|
(vidval, freq) = Counter(running_bridgeport_vids).most_common()[0]
|
||||||
|
if freq == len(bridgeports):
|
||||||
|
running_attrs['bridge-vids'] = vidval
|
||||||
|
bridge_vids = vidval.split()
|
||||||
|
|
||||||
|
bridge_pvid = None
|
||||||
|
if running_bridgeport_pvids:
|
||||||
|
(vidval, freq) = Counter(running_bridgeport_pvids).most_common()[0]
|
||||||
|
if freq == len(bridgeports) and vidval != '1':
|
||||||
|
running_attrs['bridge-pvid'] = vidval
|
||||||
|
bridge_pvid = vidval.split()
|
||||||
|
|
||||||
|
# Go through all bridge ports and find their vids
|
||||||
|
for bport in bridgeports:
|
||||||
|
bportifaceobj = ifaceobj_getfunc(bport)
|
||||||
|
if not bportifaceobj:
|
||||||
|
continue
|
||||||
|
bport_vids = None
|
||||||
|
bport_pvids = None
|
||||||
|
vids = running_vidinfo.get(bport, {}).get('vlan')
|
||||||
|
if vids and vids != bridge_vids:
|
||||||
|
bport_vids = vids
|
||||||
|
pvids = running_vidinfo.get(bport, {}).get('pvid')
|
||||||
|
if pvids and pvids[0] != bridge_pvid:
|
||||||
|
bport_pvids = pvids
|
||||||
|
if not bport_vids and bport_pvids and bport_pvids[0] != '1':
|
||||||
|
bportifaceobj[0].replace_config('bridge-access', bport_pvids[0])
|
||||||
|
else:
|
||||||
|
if bport_pvids and bport_pvids[0] != '1':
|
||||||
|
bportifaceobj[0].replace_config('bridge-pvid', bport_pvids[0])
|
||||||
|
else:
|
||||||
|
# delete any stale bridge-vids under ports
|
||||||
|
bportifaceobj[0].delete_config('bridge-pvid')
|
||||||
|
if bport_vids:
|
||||||
|
bportifaceobj[0].replace_config('bridge-vids',
|
||||||
|
' '.join(bport_vids))
|
||||||
|
else:
|
||||||
|
# delete any stale bridge-vids under ports
|
||||||
|
bportifaceobj[0].delete_config('bridge-vids')
|
||||||
return running_attrs
|
return running_attrs
|
||||||
|
|
||||||
def _query_running_mcqv4src(self, ifaceobjrunning):
|
def _query_running_mcqv4src(self, ifaceobjrunning):
|
||||||
@@ -841,7 +901,8 @@ class bridge(moduleBase):
|
|||||||
mcq = ' '.join(mcqs)
|
mcq = ' '.join(mcqs)
|
||||||
return mcq
|
return mcq
|
||||||
|
|
||||||
def _query_running_attrs(self, ifaceobjrunning, bridge_vlan_aware=False):
|
def _query_running_attrs(self, ifaceobjrunning, ifaceobj_getfunc,
|
||||||
|
bridge_vlan_aware=False):
|
||||||
bridgeattrdict = {}
|
bridgeattrdict = {}
|
||||||
userspace_stp = 0
|
userspace_stp = 0
|
||||||
ports = None
|
ports = None
|
||||||
@@ -882,7 +943,9 @@ class bridge(moduleBase):
|
|||||||
bridgeattrdict[attrname] = [v]
|
bridgeattrdict[attrname] = [v]
|
||||||
|
|
||||||
if bridge_vlan_aware:
|
if bridge_vlan_aware:
|
||||||
bridgevidinfo = self._query_running_vidinfo(ifaceobjrunning)
|
bridgevidinfo = self._query_running_vidinfo(ifaceobjrunning,
|
||||||
|
ifaceobj_getfunc,
|
||||||
|
ports.keys())
|
||||||
else:
|
else:
|
||||||
bridgevidinfo = self._query_running_vidinfo_compat(ifaceobjrunning,
|
bridgevidinfo = self._query_running_vidinfo_compat(ifaceobjrunning,
|
||||||
ports)
|
ports)
|
||||||
@@ -1237,15 +1300,16 @@ class bridge(moduleBase):
|
|||||||
self._query_check_bridge_port(ifaceobj, ifaceobjcurr,
|
self._query_check_bridge_port(ifaceobj, ifaceobjcurr,
|
||||||
ifaceobj_getfunc)
|
ifaceobj_getfunc)
|
||||||
|
|
||||||
def _query_running_bridge(self, ifaceobjrunning):
|
def _query_running_bridge(self, ifaceobjrunning, ifaceobj_getfunc):
|
||||||
if self.ipcmd.bridge_is_vlan_aware(ifaceobjrunning.name):
|
if self.ipcmd.bridge_is_vlan_aware(ifaceobjrunning.name):
|
||||||
ifaceobjrunning.update_config('bridge-vlan-aware', 'yes')
|
ifaceobjrunning.update_config('bridge-vlan-aware', 'yes')
|
||||||
ifaceobjrunning.update_config_dict(self._query_running_attrs(
|
ifaceobjrunning.update_config_dict(self._query_running_attrs(
|
||||||
ifaceobjrunning,
|
ifaceobjrunning,
|
||||||
|
ifaceobj_getfunc,
|
||||||
bridge_vlan_aware=True))
|
bridge_vlan_aware=True))
|
||||||
else:
|
else:
|
||||||
ifaceobjrunning.update_config_dict(self._query_running_attrs(
|
ifaceobjrunning.update_config_dict(self._query_running_attrs(
|
||||||
ifaceobjrunning))
|
ifaceobjrunning, None))
|
||||||
|
|
||||||
def _query_running_bridge_port_attrs(self, ifaceobjrunning, bridgename):
|
def _query_running_bridge_port_attrs(self, ifaceobjrunning, bridgename):
|
||||||
if self.sysctl_get('net.bridge.bridge-stp-user-space') == '1':
|
if self.sysctl_get('net.bridge.bridge-stp-user-space') == '1':
|
||||||
@@ -1263,6 +1327,8 @@ class bridge(moduleBase):
|
|||||||
ifaceobj_getfunc=None):
|
ifaceobj_getfunc=None):
|
||||||
bridgename = self.ipcmd.bridge_port_get_bridge_name(
|
bridgename = self.ipcmd.bridge_port_get_bridge_name(
|
||||||
ifaceobjrunning.name)
|
ifaceobjrunning.name)
|
||||||
|
bridge_vids = None
|
||||||
|
bridge_pvid = None
|
||||||
if not bridgename:
|
if not bridgename:
|
||||||
self.logger.warn('%s: unable to find bridgename'
|
self.logger.warn('%s: unable to find bridgename'
|
||||||
%ifaceobjrunning.name)
|
%ifaceobjrunning.name)
|
||||||
@@ -1271,36 +1337,37 @@ class bridge(moduleBase):
|
|||||||
return
|
return
|
||||||
|
|
||||||
running_vidinfo = self._get_running_vidinfo()
|
running_vidinfo = self._get_running_vidinfo()
|
||||||
# Check vidinfo
|
|
||||||
bridge_vids = running_vidinfo.get(bridgename, {}).get('vlan')
|
|
||||||
|
|
||||||
bridge_port_vids = running_vidinfo.get(ifaceobjrunning.name,
|
bridge_port_vids = running_vidinfo.get(ifaceobjrunning.name,
|
||||||
{}).get('vlan')
|
{}).get('vlan')
|
||||||
bridge_port_pvid = running_vidinfo.get(ifaceobjrunning.name,
|
bridge_port_pvid = running_vidinfo.get(ifaceobjrunning.name,
|
||||||
{}).get('pvid')
|
{}).get('pvid')
|
||||||
|
|
||||||
|
bridgeifaceobjlist = ifaceobj_getfunc(bridgename)
|
||||||
|
if bridgeifaceobjlist:
|
||||||
|
bridge_vids = bridgeifaceobjlist[0].get_attr_value('bridge-vids')
|
||||||
|
bridge_pvid = bridgeifaceobjlist[0].get_attr_value_first('bridge-pvid')
|
||||||
|
|
||||||
if not bridge_port_vids and bridge_port_pvid:
|
if not bridge_port_vids and bridge_port_pvid:
|
||||||
# must be an access port
|
# must be an access port
|
||||||
ifaceobjrunning.update_config('bridge-access',
|
if bridge_port_pvid != '1':
|
||||||
|
ifaceobjrunning.update_config('bridge-access',
|
||||||
bridge_port_pvid)
|
bridge_port_pvid)
|
||||||
else:
|
else:
|
||||||
if bridge_port_vids:
|
if bridge_port_vids:
|
||||||
if bridge_vids and bridge_port_vids != bridge_vids:
|
if (not bridge_vids or bridge_port_vids != bridge_vids):
|
||||||
ifaceobjrunning.update_config('bridge-vids',
|
ifaceobjrunning.update_config('bridge-vids',
|
||||||
' '.join(bridge_port_vids))
|
' '.join(bridge_port_vids))
|
||||||
|
|
||||||
if bridge_port_pvid and bridge_port_pvid != '1':
|
if bridge_port_pvid and bridge_port_pvid != '1':
|
||||||
ifaceobjrunning.update_config('bridge-pvid',
|
if (not bridge_pvid or (bridge_port_pvid != bridge_pvid)):
|
||||||
|
ifaceobjrunning.update_config('bridge-pvid',
|
||||||
bridge_port_pvid)
|
bridge_port_pvid)
|
||||||
|
|
||||||
self._query_running_bridge_port_attrs(ifaceobjrunning, bridgename)
|
self._query_running_bridge_port_attrs(ifaceobjrunning, bridgename)
|
||||||
|
|
||||||
|
def _query_running(self, ifaceobjrunning, ifaceobj_getfunc=None):
|
||||||
def _query_running(self, ifaceobjrunning, **extra_args):
|
|
||||||
if self.brctlcmd.bridge_exists(ifaceobjrunning.name):
|
if self.brctlcmd.bridge_exists(ifaceobjrunning.name):
|
||||||
self._query_running_bridge(ifaceobjrunning)
|
self._query_running_bridge(ifaceobjrunning, ifaceobj_getfunc)
|
||||||
elif self.brctlcmd.is_bridge_port(ifaceobjrunning.name):
|
elif self.brctlcmd.is_bridge_port(ifaceobjrunning.name):
|
||||||
self._query_running_bridge_port(ifaceobjrunning)
|
self._query_running_bridge_port(ifaceobjrunning, ifaceobj_getfunc)
|
||||||
|
|
||||||
_run_ops = {'pre-up' : _up,
|
_run_ops = {'pre-up' : _up,
|
||||||
'post-down' : _down,
|
'post-down' : _down,
|
||||||
|
@@ -138,6 +138,7 @@ class mstpctl(moduleBase):
|
|||||||
|
|
||||||
_port_attrs_map = {'mstpctl-portpathcost' : 'portpathcost',
|
_port_attrs_map = {'mstpctl-portpathcost' : 'portpathcost',
|
||||||
'mstpctl-portadminedge' : 'portadminedge',
|
'mstpctl-portadminedge' : 'portadminedge',
|
||||||
|
'mstpctl-portautoedge' : 'portautoedge' ,
|
||||||
'mstpctl-portp2p' : 'portp2p',
|
'mstpctl-portp2p' : 'portp2p',
|
||||||
'mstpctl-portrestrrole' : 'portrestrrole',
|
'mstpctl-portrestrrole' : 'portrestrrole',
|
||||||
'mstpctl-portrestrtcn' : 'portrestrtcn',
|
'mstpctl-portrestrtcn' : 'portrestrtcn',
|
||||||
@@ -298,7 +299,8 @@ class mstpctl(moduleBase):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def _apply_bridge_port_settings(self, ifaceobj, bridgename=None,
|
def _apply_bridge_port_settings(self, ifaceobj, bridgename=None,
|
||||||
bridgeifaceobj=None):
|
bridgeifaceobj=None, stp_on=True,
|
||||||
|
mstpd_running=True):
|
||||||
check = False if self.PERFMODE else True
|
check = False if self.PERFMODE else True
|
||||||
if not bridgename and bridgeifaceobj:
|
if not bridgename and bridgeifaceobj:
|
||||||
bridgename = bridgeifaceobj.name
|
bridgename = bridgeifaceobj.name
|
||||||
@@ -315,6 +317,12 @@ class mstpctl(moduleBase):
|
|||||||
# continue
|
# continue
|
||||||
#else:
|
#else:
|
||||||
continue
|
continue
|
||||||
|
if not stp_on:
|
||||||
|
self.logger.warn('%s: cannot set %s (stp on bridge %s not on)\n'
|
||||||
|
%(ifaceobj.name, attrname, bridgename))
|
||||||
|
continue
|
||||||
|
if not mstpd_running:
|
||||||
|
continue
|
||||||
try:
|
try:
|
||||||
self.mstpctlcmd.set_bridgeport_attr(bridgename,
|
self.mstpctlcmd.set_bridgeport_attr(bridgename,
|
||||||
ifaceobj.name, dstattrname, attrval, check)
|
ifaceobj.name, dstattrname, attrval, check)
|
||||||
@@ -348,9 +356,14 @@ class mstpctl(moduleBase):
|
|||||||
# Check if bridge port
|
# Check if bridge port
|
||||||
bridgename = self.ipcmd.bridge_port_get_bridge_name(ifaceobj.name)
|
bridgename = self.ipcmd.bridge_port_get_bridge_name(ifaceobj.name)
|
||||||
if bridgename:
|
if bridgename:
|
||||||
if self.mstpctlcmd.is_mstpd_running():
|
mstpd_running = (True if self.mstpctlcmd.is_mstpd_running()
|
||||||
self._apply_bridge_port_settings(ifaceobj, bridgename)
|
else False)
|
||||||
ifaceobj.priv_flags |= self._BRIDGE_PORT_PROCESSED
|
stp_on = (True if self.read_file_oneline(
|
||||||
|
'/sys/class/net/%s/bridge/stp_state'
|
||||||
|
%bridgename) == '2' else False)
|
||||||
|
self._apply_bridge_port_settings(ifaceobj, bridgename, None,
|
||||||
|
stp_on, mstpd_running)
|
||||||
|
ifaceobj.priv_flags |= self._BRIDGE_PORT_PROCESSED
|
||||||
return
|
return
|
||||||
if not self._is_bridge(ifaceobj):
|
if not self._is_bridge(ifaceobj):
|
||||||
return
|
return
|
||||||
|
@@ -324,6 +324,17 @@ class iface():
|
|||||||
""" add attribute name and value to the interface config """
|
""" add attribute name and value to the interface config """
|
||||||
self.config.setdefault(attr_name, []).append(attr_value)
|
self.config.setdefault(attr_name, []).append(attr_value)
|
||||||
|
|
||||||
|
def replace_config(self, attr_name, attr_value):
|
||||||
|
""" add attribute name and value to the interface config """
|
||||||
|
self.config[attr_name] = [attr_value]
|
||||||
|
|
||||||
|
def delete_config(self, attr_name):
|
||||||
|
""" add attribute name and value to the interface config """
|
||||||
|
try:
|
||||||
|
del self.config[attr_name]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def update_config_dict(self, attrdict):
|
def update_config_dict(self, attrdict):
|
||||||
self.config.update(attrdict)
|
self.config.update(attrdict)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user