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

Merge remote-tracking branch 'origin/dev-next' into dev

This commit is contained in:
Julien Fortin
2017-02-18 01:46:15 +07:00
6 changed files with 176 additions and 43 deletions

View File

@@ -105,7 +105,16 @@ class bond(moduleBase):
'example' : ['bond-slaves swp1 swp2', 'example' : ['bond-slaves swp1 swp2',
'bond-slaves glob swp1-2', 'bond-slaves glob swp1-2',
'bond-slaves regex (swp[1|2)'], 'bond-slaves regex (swp[1|2)'],
'aliases': ['bond-ports']}}} 'aliases': ['bond-ports']},
'bond-updelay' :
{'help' : 'bond updelay',
'default' : '0',
'example' : ['bond-updelay 100']},
'bond-downdelay':
{'help' : 'bond downdelay',
'default' : '0',
'example' : ['bond-downdelay 100']}
}}
_bond_mode_num = {'0': 'balance-rr', _bond_mode_num = {'0': 'balance-rr',
'1': 'active-backup', '1': 'active-backup',
@@ -231,7 +240,9 @@ class bond(moduleBase):
('bond-ad-actor-system' , 'ad_actor_system'), ('bond-ad-actor-system' , 'ad_actor_system'),
('bond-ad-sys-priority' , 'ad_actor_sys_prio'), ('bond-ad-sys-priority' , 'ad_actor_sys_prio'),
('bond-ad-actor-sys-prio' , 'ad_actor_sys_prio'), ('bond-ad-actor-sys-prio' , 'ad_actor_sys_prio'),
('bond-lacp-bypass-allow', 'lacp_bypass')]) ('bond-lacp-bypass-allow', 'lacp_bypass'),
('bond-updelay', 'updelay'),
('bond-downdelay', 'downdelay')])
linkup = self.ipcmd.is_link_up(ifaceobj.name) linkup = self.ipcmd.is_link_up(ifaceobj.name)
try: try:
# order of attributes set matters for bond, so # order of attributes set matters for bond, so
@@ -408,7 +419,11 @@ class bond(moduleBase):
'bond-num-unsol-na' : 'bond-num-unsol-na' :
self.bondcmd.get_num_unsol_na(bondname), self.bondcmd.get_num_unsol_na(bondname),
'bond-num-grat-arp' : 'bond-num-grat-arp' :
self.bondcmd.get_num_grat_arp(bondname)} self.bondcmd.get_num_grat_arp(bondname),
'bond-updelay' :
self.bondcmd.get_updelay(bondname),
'bond-downdelay' :
self.bondcmd.get_downdelay(bondname)}
slaves = self.bondcmd.get_slaves(bondname) slaves = self.bondcmd.get_slaves(bondname)
if slaves: if slaves:
bondattrs['bond-slaves'] = slaves bondattrs['bond-slaves'] = slaves

View File

@@ -144,7 +144,7 @@ class mstpctl(moduleBase):
'validrange' : ['0', '255'], 'validrange' : ['0', '255'],
'default' : '2', 'default' : '2',
'required' : False, 'required' : False,
'jsonAttr': 'portHelloTime', 'jsonAttr': 'helloTime',
'example' : ['mstpctl-hello 2']}, 'example' : ['mstpctl-hello 2']},
'mstpctl-portnetwork' : 'mstpctl-portnetwork' :
{ 'help' : 'enable/disable bridge assurance capability for a port', { 'help' : 'enable/disable bridge assurance capability for a port',
@@ -329,16 +329,32 @@ class mstpctl(moduleBase):
try: try:
# set bridge attributes # set bridge attributes
for attrname, dstattrname in self._attrs_map.items(): for attrname, dstattrname in self._attrs_map.items():
config_val = ifaceobj.get_attr_value_first(attrname)
default_val = policymanager.policymanager_api.get_iface_default(module_name=self.__class__.__name__, ifname=ifaceobj.name, attr=attrname)
if not default_val:
default_val = self.get_mod_subattr(attrname,'default')
jsonAttr = self.get_mod_subattr(attrname, 'jsonAttr')
try:
running_val = self.mstpctlcmd.get_bridge_attr(
ifaceobj.name, jsonAttr)
except:
self.logger.info('%s: could not get running %s value'
%(ifaceobj.name, attrname))
running_val = None
if (not config_val and default_val and (running_val != default_val)):
# this happens when users remove an attribute from a port
# and expect the default to be restored with ifreload.
config_val = default_val
elif not config_val:
# there is nothing configured and no default to reset
continue
try: try:
v = ifaceobj.get_attr_value_first(attrname)
if not v:
continue
if attrname == 'mstpctl-treeprio': if attrname == 'mstpctl-treeprio':
self.mstpctlcmd.set_bridge_treeprio(ifaceobj.name, self.mstpctlcmd.set_bridge_treeprio(ifaceobj.name,
v, check) config_val, check)
else: else:
self.mstpctlcmd.set_bridge_attr(ifaceobj.name, self.mstpctlcmd.set_bridge_attr(ifaceobj.name,
dstattrname, v, check) dstattrname, config_val, check)
except Exception, e: except Exception, e:
self.logger.warn('%s' %str(e)) self.logger.warn('%s' %str(e))
pass pass
@@ -415,7 +431,10 @@ class mstpctl(moduleBase):
else: else:
return 'yes' return 'yes'
else: else:
return self.get_mod_subattr(attr,'default') default_val = policymanager.policymanager_api.get_iface_default(module_name=self.__class__.__name__, ifname=ifaceobj.name, attr=attr)
if not default_val:
return self.get_mod_subattr(attr,'default')
return default_val
def _apply_bridge_port_settings(self, ifaceobj, bridgename=None, def _apply_bridge_port_settings(self, ifaceobj, bridgename=None,
bridgeifaceobj=None, bridgeifaceobj=None,
@@ -660,6 +679,18 @@ class mstpctl(moduleBase):
if v}) if v})
return bridgeattrdict return bridgeattrdict
def _get_config_stp(self, ifaceobj):
stp = (ifaceobj.get_attr_value_first('mstpctl-stp') or
ifaceobj.get_attr_value_first('bridge-stp') or
policymanager.policymanager_api.get_iface_default(module_name=self.__class__.__name__, ifname=ifaceobj.name, attr='mstpctl-stp') or
# this is a temporary method to access policy default value of bridge-stp
policymanager.policymanager_api.get_iface_default(module_name='bridge', ifname=ifaceobj.name, attr='bridge-stp'))
return utils.get_boolean_from_string(stp)
def _get_running_stp(self, ifaceobj):
stp = self.brctlcmd.get_stp(ifaceobj.name)
return utils.get_boolean_from_string(stp)
def _query_check_bridge(self, ifaceobj, ifaceobjcurr, def _query_check_bridge(self, ifaceobj, ifaceobjcurr,
ifaceobj_getfunc=None): ifaceobj_getfunc=None):
# list of attributes that are not supported currently # list of attributes that are not supported currently
@@ -680,6 +711,8 @@ class mstpctl(moduleBase):
#self.logger.info('B' + str(runningattrs)) #self.logger.info('B' + str(runningattrs))
if not runningattrs: if not runningattrs:
runningattrs = {} runningattrs = {}
config_stp = self._get_config_stp(ifaceobj)
running_stp = self._get_running_stp(ifaceobj)
running_port_list = self.brctlcmd.get_bridge_ports(ifaceobj.name) running_port_list = self.brctlcmd.get_bridge_ports(ifaceobj.name)
for k in ifaceattrs: for k in ifaceattrs:
# for all mstpctl options # for all mstpctl options
@@ -691,6 +724,8 @@ class mstpctl(moduleBase):
#unaware bridge #unaware bridge
if not running_port_list: if not running_port_list:
continue continue
if (not config_stp or not running_stp):
continue
v = ifaceobj.get_attr_value_first(k) v = ifaceobj.get_attr_value_first(k)
config_val = {} config_val = {}
running_val = {} running_val = {}
@@ -819,6 +854,10 @@ class mstpctl(moduleBase):
if (self._is_bridge(bifaceobj) and if (self._is_bridge(bifaceobj) and
self.default_vxlan_ports_set_bpduparams and self.default_vxlan_ports_set_bpduparams and
(bifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_VLAN_AWARE)): (bifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_VLAN_AWARE)):
config_stp = self._get_config_stp(bifaceobj)
running_stp = self._get_running_stp(bifaceobj)
if (not config_stp or not running_stp):
continue
for attr in ['mstpctl-portbpdufilter', for attr in ['mstpctl-portbpdufilter',
'mstpctl-bpduguard']: 'mstpctl-bpduguard']:
jsonAttr = self.get_mod_subattr(attr, 'jsonAttr') jsonAttr = self.get_mod_subattr(attr, 'jsonAttr')

View File

@@ -56,7 +56,7 @@ case "$1" in
# Generic stuff done on all configurations # Generic stuff done on all configurations
if [ -f /etc/network/interfaces ] ; then if [ -f /etc/network/interfaces ] ; then
if ! grep -q "^[[:space:]]*iface[[:space:]]\+lo0\?[[:space:]]\+inet[[:space:]]\+loopback\>" /etc/network/interfaces ; then if ! grep -q -E "^[[:space:]]*iface[[:space:]]+l[o0]([[:space:]]+inet([[:space:]]+loopback)?)?[[:space:]]*$" /etc/network/interfaces ; then
report_warn "No 'iface lo' definition found in /etc/network/interfaces" report_warn "No 'iface lo' definition found in /etc/network/interfaces"
fi fi

View File

@@ -210,4 +210,5 @@ class policymanager():
return mod_array return mod_array
policymanager_api = policymanager() policymanager_api = policymanager()

View File

@@ -31,36 +31,76 @@ class bondutil(utilsBase):
except: except:
linkCache.links[bondname] = {'linkinfo': {}} linkCache.links[bondname] = {'linkinfo': {}}
try:
linkCache.set_attr([bondname, 'linkinfo', 'min_links'],
self.read_file_oneline(
'/sys/class/net/%s/bonding/min_links'
% bondname))
except Exception as e:
self.logger.debug(str(e))
try: try:
linkCache.set_attr([bondname, 'linkinfo', 'slaves'], linkCache.set_attr([bondname, 'linkinfo', 'slaves'],
self.read_file_oneline('/sys/class/net/%s/bonding/slaves' self.read_file_oneline('/sys/class/net/%s/bonding/slaves'
%bondname).split()) %bondname).split())
except Exception as e:
self.logger.debug(str(e))
try:
linkCache.set_attr([bondname, 'linkinfo', 'mode'], linkCache.set_attr([bondname, 'linkinfo', 'mode'],
self.read_file_oneline('/sys/class/net/%s/bonding/mode' self.read_file_oneline('/sys/class/net/%s/bonding/mode'
%bondname).split()[0]) %bondname).split()[0])
except Exception as e:
self.logger.debug(str(e))
try:
linkCache.set_attr([bondname, 'linkinfo', 'xmit_hash_policy'], linkCache.set_attr([bondname, 'linkinfo', 'xmit_hash_policy'],
self.read_file_oneline( self.read_file_oneline(
'/sys/class/net/%s/bonding/xmit_hash_policy' '/sys/class/net/%s/bonding/xmit_hash_policy'
%bondname).split()[0]) %bondname).split()[0])
except Exception as e:
self.logger.debug(str(e))
try:
linkCache.set_attr([bondname, 'linkinfo', 'lacp_rate'], linkCache.set_attr([bondname, 'linkinfo', 'lacp_rate'],
self.read_file_oneline('/sys/class/net/%s/bonding/lacp_rate' self.read_file_oneline('/sys/class/net/%s/bonding/lacp_rate'
%bondname).split()[1]) %bondname).split()[1])
except Exception as e:
self.logger.debug(str(e))
try:
linkCache.set_attr([bondname, 'linkinfo', 'ad_actor_sys_prio'], linkCache.set_attr([bondname, 'linkinfo', 'ad_actor_sys_prio'],
self.read_file_oneline('/sys/class/net/%s/bonding/ad_actor_sys_prio' self.read_file_oneline('/sys/class/net/%s/bonding/ad_actor_sys_prio'
%bondname)) %bondname))
except Exception as e:
self.logger.debug(str(e))
try:
linkCache.set_attr([bondname, 'linkinfo', 'ad_actor_system'], linkCache.set_attr([bondname, 'linkinfo', 'ad_actor_system'],
self.read_file_oneline('/sys/class/net/%s/bonding/ad_actor_system' self.read_file_oneline('/sys/class/net/%s/bonding/ad_actor_system'
%bondname)) %bondname))
except Exception as e:
self.logger.debug(str(e))
try:
linkCache.set_attr([bondname, 'linkinfo', 'lacp_bypass'], linkCache.set_attr([bondname, 'linkinfo', 'lacp_bypass'],
self.read_file_oneline('/sys/class/net/%s/bonding/lacp_bypass' self.read_file_oneline('/sys/class/net/%s/bonding/lacp_bypass'
%bondname).split()[1]) %bondname).split()[1])
except Exception as e:
self.logger.debug(str(e))
try:
linkCache.set_attr([bondname, 'linkinfo', 'updelay'],
self.read_file_oneline('/sys/class/net/%s/bonding/updelay'
%bondname))
except Exception as e:
self.logger.debug(str(e))
try:
linkCache.set_attr([bondname, 'linkinfo', 'downdelay'],
self.read_file_oneline('/sys/class/net/%s/bonding/downdelay'
%bondname))
except Exception as e:
self.logger.debug(str(e))
try:
map(lambda x: linkCache.set_attr([bondname, 'linkinfo', x], map(lambda x: linkCache.set_attr([bondname, 'linkinfo', x],
self.read_file_oneline('/sys/class/net/%s/bonding/%s' self.read_file_oneline('/sys/class/net/%s/bonding/%s'
%(bondname, x))), %(bondname, x))),
['use_carrier', 'miimon', 'min_links', 'num_unsol_na', ['use_carrier', 'miimon', 'min_links', 'num_unsol_na',
'num_grat_arp']) 'num_grat_arp'])
except Exception, e: except Exception as e:
pass self.logger.debug(str(e))
def _bond_linkinfo_fill_all(self): def _bond_linkinfo_fill_all(self):
bondstr = self.read_file_oneline('/sys/class/net/bonding_masters') bondstr = self.read_file_oneline('/sys/class/net/bonding_masters')
@@ -285,6 +325,12 @@ class bondutil(utilsBase):
def get_num_grat_arp(self, bondname): def get_num_grat_arp(self, bondname):
return self._cache_get([bondname, 'linkinfo', 'num_grat_arp']) return self._cache_get([bondname, 'linkinfo', 'num_grat_arp'])
def get_updelay(self, bondname):
return self._cache_get([bondname, 'linkinfo', 'updelay'])
def get_downdelay(self, bondname):
return self._cache_get([bondname, 'linkinfo', 'downdelay'])
def enslave_slave(self, bondname, slave, prehook=None, posthook=None): def enslave_slave(self, bondname, slave, prehook=None, posthook=None):
slaves = self._cache_get([bondname, 'linkinfo', 'slaves']) slaves = self._cache_get([bondname, 'linkinfo', 'slaves'])
if slaves and slave in slaves: return if slaves and slave in slaves: return

View File

@@ -28,6 +28,17 @@ class mstpctlutil(utilsBase):
'hello' : 'hello-time', 'hello' : 'hello-time',
'forcevers' : 'force-protocol-version'} 'forcevers' : 'force-protocol-version'}
_bridge_jsonAttr_map = {
'treeprio': 'bridgeId',
'maxage': 'maxAge',
'fdelay': 'fwdDelay',
'txholdcount': 'txHoldCounter',
'maxhops': 'maxHops',
'ageing': 'ageingTime',
'hello': 'helloTime',
'forcevers': 'forceProtocolVersion',
}
_bridgeportattrmap = {'portadminedge' : 'admin-edge-port', _bridgeportattrmap = {'portadminedge' : 'admin-edge-port',
'portp2p' : 'admin-point-to-point', 'portp2p' : 'admin-point-to-point',
'portrestrrole' : 'restricted-role', 'portrestrrole' : 'restricted-role',
@@ -56,7 +67,7 @@ class mstpctlutil(utilsBase):
except: except:
return mstpctlutil._DEFAULT_PORT_PRIO return mstpctlutil._DEFAULT_PORT_PRIO
def _get_bridge_port_attrs_from_cache(self, bridgename): def _get_bridge_and_port_attrs_from_cache(self, bridgename):
attrs = MSTPAttrsCache.get(bridgename) attrs = MSTPAttrsCache.get(bridgename)
if attrs: if attrs:
return attrs return attrs
@@ -81,19 +92,41 @@ class mstpctlutil(utilsBase):
MSTPAttrsCache.set(bridgename, mstpctl_bridgeport_attrs_dict) MSTPAttrsCache.set(bridgename, mstpctl_bridgeport_attrs_dict)
except Exception as e: except Exception as e:
self.logger.info('%s: cannot fetch mstpctl bridge port attributes: %s' % str(e)) self.logger.info('%s: cannot fetch mstpctl bridge port attributes: %s' % str(e))
return mstpctl_bridgeport_attrs_dict
mstpctl_bridge_attrs_dict = {}
try:
cmd = ['/sbin/mstpctl', 'showbridge', 'json', bridgename]
output = utils.exec_commandl(cmd)
if not output:
return mstpctl_bridge_attrs_dict
except Exception as e:
self.logger.info(str(e))
return mstpctl_bridge_attrs_dict
try:
mstpctl_bridge_cache = json.loads(output.strip('\n'))
for jsonAttr in mstpctl_bridge_cache[bridgename].keys():
mstpctl_bridge_attrs_dict[jsonAttr] = (
str(mstpctl_bridge_cache[bridgename][jsonAttr]))
mstpctl_bridge_attrs_dict['treeprio'] = '%d' %(
int(mstpctl_bridge_attrs_dict.get('bridgeId',
'').split('.')[0], base=16) * 4096)
del mstpctl_bridge_attrs_dict['bridgeId']
MSTPAttrsCache.bridges[bridgename].update(mstpctl_bridge_attrs_dict)
except Exception as e:
self.logger.info('%s: cannot fetch mstpctl bridge attributes: %s' % str(e))
return MSTPAttrsCache.get(bridgename)
def get_bridge_ports_attrs(self, bridgename): def get_bridge_ports_attrs(self, bridgename):
return self._get_bridge_port_attrs_from_cache(bridgename) return self._get_bridge_and_port_attrs_from_cache(bridgename)
def get_bridge_port_attr(self, bridgename, portname, attrname): def get_bridge_port_attr(self, bridgename, portname, attrname):
attrs = self._get_bridge_port_attrs_from_cache(bridgename) attrs = self._get_bridge_and_port_attrs_from_cache(bridgename)
value = attrs.get(portname, {}).get(attrname, 'no') value = attrs.get(portname, {}).get(attrname, 'no')
if value == 'True' or value == 'true': if value == 'True' or value == 'true':
return 'yes' return 'yes'
return str(value) return str(value)
def update_cache(self, bridgename, portname, attrname, value): def update_bridge_port_cache(self, bridgename, portname, attrname, value):
attrs = self.get_bridge_ports_attrs(bridgename) attrs = self.get_bridge_ports_attrs(bridgename)
if not attrs: if not attrs:
attrs = {} attrs = {}
@@ -102,6 +135,13 @@ class mstpctlutil(utilsBase):
attrs[portname][attrname] = value attrs[portname][attrname] = value
MSTPAttrsCache.set(bridgename, attrs) MSTPAttrsCache.set(bridgename, attrs)
def update_bridge_cache(self, bridgename, attrname, value):
attrs = self.get_bridge_ports_attrs(bridgename)
if not attrs:
attrs = {}
attrs[attrname] = value
MSTPAttrsCache.set(bridgename, attrs)
def set_bridge_port_attr(self, bridgename, portname, attrname, value, json_attr=None): def set_bridge_port_attr(self, bridgename, portname, attrname, value, json_attr=None):
cache_value = self.get_bridge_port_attr(bridgename, portname, json_attr) cache_value = self.get_bridge_port_attr(bridgename, portname, json_attr)
if cache_value and cache_value == value: if cache_value and cache_value == value:
@@ -113,16 +153,13 @@ class mstpctlutil(utilsBase):
utils.exec_commandl(['/sbin/mstpctl', 'set%s' % attrname, utils.exec_commandl(['/sbin/mstpctl', 'set%s' % attrname,
bridgename, portname, value]) bridgename, portname, value])
if json_attr: if json_attr:
self.update_cache(bridgename, portname, json_attr, value) self.update_bridge_port_cache(bridgename, portname, json_attr, value)
def get_bridge_attrs(self, bridgename): def get_bridge_attrs(self, bridgename):
bridgeattrs = {} bridgeattrs = {}
try: try:
bridgeattrs = dict((k, self.get_bridge_attr(bridgename, k)) bridgeattrs = dict((k, self.get_bridge_attr(bridgename, v))
for k in self._bridgeattrmap.keys()) for k,v in self._bridge_jsonAttr_map.items())
bridgeattrs['treeprio'] = '%d' %(int(bridgeattrs.get('bridgeid',
'').split('.')[0], base=16) * 4096)
del bridgeattrs['bridgeid']
except Exception, e: except Exception, e:
self.logger.debug(bridgeattrs) self.logger.debug(bridgeattrs)
self.logger.debug(str(e)) self.logger.debug(str(e))
@@ -130,28 +167,32 @@ class mstpctlutil(utilsBase):
return bridgeattrs return bridgeattrs
def get_bridge_attr(self, bridgename, attrname): def get_bridge_attr(self, bridgename, attrname):
try: if attrname == 'bridgeId':
cmdl = ['/sbin/mstpctl', 'showbridge', bridgename, attrname = 'treeprio'
self._bridgeattrmap[attrname]] return self._get_bridge_and_port_attrs_from_cache(bridgename).get(attrname)
return utils.exec_commandl(cmdl).strip('\n')
except Exception, e:
pass
return None
def set_bridge_attr(self, bridgename, attrname, attrvalue, check=True): def set_bridge_attr(self, bridgename, attrname, attrvalue, check=True):
if check: if check:
attrvalue_curr = self.get_bridge_attr(bridgename, attrname) if attrname == 'treeprio':
attrvalue_curr = self.get_bridge_attr(bridgename, attrname)
else:
attrvalue_curr = self.get_bridge_attr(bridgename,
self._bridge_jsonAttr_map[attrname])
if attrvalue_curr and attrvalue_curr == attrvalue: if attrvalue_curr and attrvalue_curr == attrvalue:
return return
if attrname == 'treeprio': if attrname == 'treeprio':
utils.exec_commandl(['/sbin/mstpctl', 'set%s' % attrname, utils.exec_commandl(['/sbin/mstpctl', 'set%s' % attrname,
'%s' % bridgename, '0', '%s' % attrvalue], '%s' % bridgename, '0', '%s' % attrvalue],
stdout=False, stderr=None) stdout=False, stderr=None)
self.update_bridge_cache(bridgename, attrname, str(attrvalue))
else: else:
utils.exec_commandl(['/sbin/mstpctl', 'set%s' % attrname, utils.exec_commandl(['/sbin/mstpctl', 'set%s' % attrname,
'%s' % bridgename, '%s' % attrvalue], '%s' % bridgename, '%s' % attrvalue],
stdout=False, stderr=None) stdout=False, stderr=None)
self.update_bridge_cache(bridgename,
self._bridge_jsonAttr_map[attrname],
str(attrvalue))
def set_bridge_attrs(self, bridgename, attrdict, check=True): def set_bridge_attrs(self, bridgename, attrdict, check=True):
for k, v in attrdict.iteritems(): for k, v in attrdict.iteritems():
@@ -163,17 +204,7 @@ class mstpctlutil(utilsBase):
self.logger.warn('%s: %s' %(bridgename, str(e))) self.logger.warn('%s: %s' %(bridgename, str(e)))
def get_bridge_treeprio(self, bridgename): def get_bridge_treeprio(self, bridgename):
try: return self.get_bridge_attr(bridgename, 'treeprio')
cmdl = ['/sbin/mstpctl',
'showbridge',
bridgename,
self._bridgeattrmap['bridgeid']]
bridgeid = utils.exec_commandl(cmdl).strip('\n')
return '%d' %(int(bridgeid.split('.')[0], base=16) * 4096)
except:
pass
return None
def set_bridge_treeprio(self, bridgename, attrvalue, check=True): def set_bridge_treeprio(self, bridgename, attrvalue, check=True):
if check: if check:
@@ -182,6 +213,7 @@ class mstpctlutil(utilsBase):
return return
utils.exec_commandl(['/sbin/mstpctl', 'settreeprio', bridgename, '0', utils.exec_commandl(['/sbin/mstpctl', 'settreeprio', bridgename, '0',
str(attrvalue)]) str(attrvalue)])
self.update_bridge_cache(bridgename, 'treeprio', str(attrvalue))
def showbridge(self, bridgename=None): def showbridge(self, bridgename=None):
if bridgename: if bridgename: