mirror of
https://github.com/CumulusNetworks/ifupdown2.git
synced 2024-05-06 15:54:50 +00:00
mstpctl: cache improvement to reduce subprocess calls, vxlan opti
Ticket: CM-11274 Reviewed By: Roopa, Nikhil Testing Done: ifupdown2 smoke, vxlan_aa smoke The mstpctl addon and mstpctlutils file now contains a unified way to access cached data (from mstpctl showportdetails json). Some numbers: - Without the patch ifreload -a on a scale vxlan config (1k vxlan) we used to execute 5098 subcommands. - With the patch "only" ~3000 (it should be 2k but clag ip link set protodown needs to be move to netlink). for ifquery -r -a: 11052 calls before patch, 1031 after. This should improve time execution as well as CPU usage. Signed-off-by: Julien Fortin <julien@cumulusnetworks.com>
This commit is contained in:
@@ -1286,7 +1286,7 @@ class bridge(moduleBase):
|
||||
ports = None
|
||||
skip_kernel_stp_attrs = 0
|
||||
|
||||
if self.sysctl_get('net.bridge.bridge-stp-user-space') == '1':
|
||||
if self.systcl_get_net_bridge_stp_user_space() == '1':
|
||||
userspace_stp = 1
|
||||
|
||||
tmpbridgeattrdict = self.brctlcmd.get_bridge_attrs(ifaceobjrunning.name)
|
||||
@@ -1745,7 +1745,7 @@ class bridge(moduleBase):
|
||||
ifaceobjrunning, None))
|
||||
|
||||
def _query_running_bridge_port_attrs(self, ifaceobjrunning, bridgename):
|
||||
if self.sysctl_get('net.bridge.bridge-stp-user-space') == '1':
|
||||
if self.systcl_get_net_bridge_stp_user_space() == '1':
|
||||
return
|
||||
|
||||
v = self.brctlcmd.get_pathcost(bridgename, ifaceobjrunning.name)
|
||||
|
@@ -46,29 +46,34 @@ class mstpctl(moduleBase):
|
||||
'validrange' : ['0', '4096'],
|
||||
'default' : '300',
|
||||
'required' : False,
|
||||
'jsonAttr': 'ageingTime',
|
||||
'example' : ['mstpctl-ageing 300']},
|
||||
'mstpctl-maxage' :
|
||||
{ 'help' : 'max message age',
|
||||
'validrange' : ['0', '255'],
|
||||
'default' : '20',
|
||||
'jsonAttr': 'maxAge',
|
||||
'required' : False,
|
||||
'example' : ['mstpctl-maxage 20']},
|
||||
'mstpctl-fdelay' :
|
||||
{ 'help' : 'set forwarding delay',
|
||||
'validrange' : ['0', '255'],
|
||||
'default' : '15',
|
||||
'jsonAttr': 'fwdDelay',
|
||||
'required' : False,
|
||||
'example' : ['mstpctl-fdelay 15']},
|
||||
'mstpctl-maxhops' :
|
||||
{ 'help' : 'bridge max hops',
|
||||
'validrange' : ['0', '255'],
|
||||
'default' : '15',
|
||||
'jsonAttr': 'maxHops',
|
||||
'required' : False,
|
||||
'example' : ['mstpctl-maxhops 15']},
|
||||
'mstpctl-txholdcount' :
|
||||
{ 'help' : 'bridge transmit holdcount',
|
||||
'validrange' : ['0', '255'],
|
||||
'default' : '6',
|
||||
'jsonAttr': 'txHoldCounter',
|
||||
'required' : False,
|
||||
'example' : ['mstpctl-txholdcount 6']},
|
||||
'mstpctl-forcevers' :
|
||||
@@ -76,6 +81,7 @@ class mstpctl(moduleBase):
|
||||
'validvals' : ['rstp', ],
|
||||
'default' : 'rstp',
|
||||
'required' : False,
|
||||
'jsonAttr': 'forceProtocolVersion',
|
||||
'example' : ['mstpctl-forcevers rstp']},
|
||||
'mstpctl-portpathcost' :
|
||||
{ 'help' : 'bridge port path cost',
|
||||
@@ -127,6 +133,7 @@ class mstpctl(moduleBase):
|
||||
'default' : '128',
|
||||
'validvals': ['<interface-range-list>'],
|
||||
'validrange' : ['0', '240'],
|
||||
'jsonAttr': 'treeportprio',
|
||||
'required' : False,
|
||||
'example' : ['under the bridge: mstpctl-treeportprio swp1=128 swp2=128',
|
||||
'under the port (recommended): mstpctl-treeportprio 128']},
|
||||
@@ -135,6 +142,7 @@ class mstpctl(moduleBase):
|
||||
'validrange' : ['0', '255'],
|
||||
'default' : '2',
|
||||
'required' : False,
|
||||
'jsonAttr': 'portHelloTime',
|
||||
'example' : ['mstpctl-hello 2']},
|
||||
'mstpctl-portnetwork' :
|
||||
{ 'help' : 'enable/disable bridge assurance capability for a port',
|
||||
@@ -163,7 +171,9 @@ class mstpctl(moduleBase):
|
||||
'mstpctl-treeportcost' :
|
||||
{ 'help' : 'port tree cost',
|
||||
'validrange' : ['0', '255'],
|
||||
'required' : False},
|
||||
'required' : False,
|
||||
'jsonAttr': 'extPortCost',
|
||||
},
|
||||
'mstpctl-portbpdufilter' :
|
||||
{ 'help' : 'enable/disable bpdu filter on a port. ' +
|
||||
'syntax varies when defined under a bridge ' +
|
||||
@@ -240,6 +250,12 @@ class mstpctl(moduleBase):
|
||||
return None
|
||||
return self.brctlcmd.get_bridge_ports(ifaceobj.name)
|
||||
|
||||
def _get_bridge_port_attr_value(self, bridgename, portname, attr):
|
||||
json_attr = self.get_mod_subattr(attr, 'jsonAttr')
|
||||
return self.mstpctlcmd.get_bridge_port_attr(bridgename,
|
||||
portname,
|
||||
json_attr)
|
||||
|
||||
def _get_bridge_port_list(self, ifaceobj):
|
||||
|
||||
# port list is also available in the previously
|
||||
@@ -330,12 +346,11 @@ class mstpctl(moduleBase):
|
||||
for port in bridgeports:
|
||||
if not self.brctlcmd.is_bridge_port(port):
|
||||
continue
|
||||
running_val = self.mstpctlcmd.get_mstpctl_bridgeport_attr(ifaceobj.name,
|
||||
port, jsonAttr)
|
||||
if running_val != default_val:
|
||||
# we will not bother checking since we already checked
|
||||
self.mstpctlcmd.set_bridgeport_attr(ifaceobj.name,
|
||||
port, dstattrname, default_val, False)
|
||||
self.mstpctlcmd.set_bridge_port_attr(ifaceobj.name,
|
||||
port,
|
||||
dstattrname,
|
||||
default_val,
|
||||
json_attr=jsonAttr)
|
||||
except:
|
||||
self.logger.info('%s: not resetting %s config'
|
||||
%(ifaceobj.name, attrname))
|
||||
@@ -355,8 +370,12 @@ class mstpctl(moduleBase):
|
||||
# if it is not bridge port, continue
|
||||
if not os.path.exists('/sys/class/net/%s/brport' %port):
|
||||
continue
|
||||
self.mstpctlcmd.set_bridgeport_attr(ifaceobj.name,
|
||||
port, dstattrname, val, check)
|
||||
json_attr = self.get_mod_subattr(attrname, 'jsonAttr')
|
||||
self.mstpctlcmd.set_bridge_port_attr(ifaceobj.name,
|
||||
port,
|
||||
dstattrname,
|
||||
val,
|
||||
json_attr=json_attr)
|
||||
except Exception, e:
|
||||
self.log_error('%s: error setting %s (%s)'
|
||||
%(ifaceobj.name, attrname, str(e)),
|
||||
@@ -409,11 +428,15 @@ class mstpctl(moduleBase):
|
||||
(ifaceobj.link_kind & ifaceLinkKind.VXLAN)):
|
||||
for attr in ['mstpctl-portbpdufilter',
|
||||
'mstpctl-bpduguard']:
|
||||
config_val = self._get_default_val(attr, ifaceobj, bridgeifaceobj)
|
||||
json_attr = self.get_mod_subattr(attr, 'jsonAttr')
|
||||
config_val = self._get_default_val(attr, ifaceobj,
|
||||
bridgeifaceobj)
|
||||
try:
|
||||
self.mstpctlcmd.set_bridgeport_attr(bridgename,
|
||||
ifaceobj.name, self._port_attrs_map[attr],
|
||||
config_val, check)
|
||||
self.mstpctlcmd.set_bridge_port_attr(bridgename,
|
||||
ifaceobj.name,
|
||||
self._port_attrs_map[attr],
|
||||
config_val,
|
||||
json_attr=json_attr)
|
||||
except Exception, e:
|
||||
self.log_warn('%s: error setting %s (%s)'
|
||||
% (ifaceobj.name, attr, str(e)))
|
||||
@@ -427,7 +450,7 @@ class mstpctl(moduleBase):
|
||||
# to see the running value, stp would have to be on
|
||||
# so we would have parsed mstpctl showportdetail json output
|
||||
try:
|
||||
running_val = self.mstpctlcmd.get_mstpctl_bridgeport_attr(bridgename,
|
||||
running_val = self.mstpctlcmd.get_bridge_port_attr(bridgename,
|
||||
ifaceobj.name, jsonAttr)
|
||||
except:
|
||||
self.logger.info('%s %s: could not get running %s value'
|
||||
@@ -442,8 +465,8 @@ class mstpctl(moduleBase):
|
||||
continue
|
||||
|
||||
try:
|
||||
self.mstpctlcmd.set_bridgeport_attr(bridgename,
|
||||
ifaceobj.name, dstattrname, config_val, check)
|
||||
self.mstpctlcmd.set_bridge_port_attr(bridgename,
|
||||
ifaceobj.name, dstattrname, config_val, json_attr=jsonAttr)
|
||||
applied = True
|
||||
except Exception, e:
|
||||
self.log_error('%s: error setting %s (%s)'
|
||||
@@ -568,6 +591,7 @@ class mstpctl(moduleBase):
|
||||
bridgeattrdict = {}
|
||||
|
||||
tmpbridgeattrdict = self.mstpctlcmd.get_bridge_attrs(ifaceobjrunning.name)
|
||||
#self.logger.info('A' + str(tmpbridgeattrdict))
|
||||
if not tmpbridgeattrdict:
|
||||
return bridgeattrdict
|
||||
|
||||
@@ -590,7 +614,6 @@ class mstpctl(moduleBase):
|
||||
'mstpctl-portnetwork' : '',
|
||||
'mstpctl-portpathcost' : '',
|
||||
'mstpctl-portadminedge' : '',
|
||||
'mstpctl-portautoedge' : '',
|
||||
'mstpctl-portp2p' : '',
|
||||
'mstpctl-portrestrrole' : '',
|
||||
'mstpctl-portrestrtcn' : '',
|
||||
@@ -599,70 +622,26 @@ class mstpctl(moduleBase):
|
||||
'mstpctl-treeportcost' : ''}
|
||||
|
||||
for p in ports:
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
|
||||
p, 'portautoedge')
|
||||
|
||||
for attr in ['mstpctl-portautoedge',
|
||||
'mstpctl-portbpdufilter',
|
||||
'mstpctl-portnetwork',
|
||||
'mstpctl-portadminedge',
|
||||
'mstpctl-portp2p',
|
||||
'mstpctl-portrestrrole',
|
||||
'mstpctl-portrestrtcn',
|
||||
'mstpctl-bpduguard',
|
||||
'']:
|
||||
v = self._get_bridge_port_attr_value(ifaceobjrunning.name,
|
||||
p, attr)
|
||||
if v and v != 'no':
|
||||
portconfig['mstpctl-portautoedge'] += ' %s=%s' %(p, v)
|
||||
portconfig[attr] += ' %s=%s' % (p, v)
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
|
||||
p, 'portbpdufilter')
|
||||
if v and v != 'no':
|
||||
portconfig['mstpctl-portbpdufilter'] += ' %s=%s' %(p, v)
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
|
||||
p, 'portnetwork')
|
||||
if v and v != 'no':
|
||||
portconfig['mstpctl-portnetwork'] += ' %s=%s' %(p, v)
|
||||
|
||||
# XXX: Can we really get path cost of a port ???
|
||||
#v = self.mstpctlcmd.get_portpathcost(ifaceobjrunning.name, p)
|
||||
#if v and v != self.get_mod_subattr('mstpctl-portpathcost',
|
||||
# 'default'):
|
||||
# portconfig['mstpctl-portpathcost'] += ' %s=%s' %(p, v)
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
|
||||
p, 'portadminedge')
|
||||
if v and v != 'no':
|
||||
portconfig['mstpctl-portadminedge'] += ' %s=%s' %(p, v)
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
|
||||
p, 'portp2p')
|
||||
if v and v != 'no':
|
||||
portconfig['mstpctl-portp2p'] += ' %s=%s' %(p, v)
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
|
||||
p, 'portrestrrole')
|
||||
if v and v != 'no':
|
||||
portconfig['mstpctl-portrestrrole'] += ' %s=%s' %(p, v)
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
|
||||
p, 'portrestrtcn')
|
||||
if v and v != 'no':
|
||||
portconfig['mstpctl-portrestrtcn'] += ' %s=%s' %(p, v)
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
|
||||
p, 'bpduguard')
|
||||
if v and v != 'no':
|
||||
portconfig['mstpctl-bpduguard'] += ' %s=%s' %(p, v)
|
||||
|
||||
# XXX: Can we really get path cost of a port ???
|
||||
#v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
|
||||
# p, 'treeprio')
|
||||
#if v and v != self.get_mod_subattr('mstpctl-treeportprio',
|
||||
# 'default'):
|
||||
# portconfig['mstpctl-treeportprio'] += ' %s=%s' %(p, v)
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
|
||||
p, 'portpathcost')
|
||||
if v and v != self.get_mod_subattr('mstpctl-portpathcost',
|
||||
'default'):
|
||||
portconfig['mstpctl-portpathcost'] += ' %s=%s' %(p, v)
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
|
||||
p, 'treeportcost')
|
||||
if v and v != self.get_mod_subattr('mstpctl-treeportcost',
|
||||
'default'):
|
||||
portconfig['mstpctl-treeportcost'] += ' %s=%s' %(p, v)
|
||||
for attr in ['mstpctl-portpathcost', 'mstpctl-treeportcost']:
|
||||
v = self._get_bridge_port_attr_value(ifaceobjrunning.name,
|
||||
p, attr)
|
||||
if v and v != self.get_mod_subattr(attr, 'default'):
|
||||
portconfig[attr] += ' %s=%s' % (p, v)
|
||||
|
||||
bridgeattrdict.update({k : [v] for k, v in portconfig.items()
|
||||
if v})
|
||||
@@ -685,6 +664,7 @@ class mstpctl(moduleBase):
|
||||
if not ifaceattrs:
|
||||
return
|
||||
runningattrs = self.mstpctlcmd.get_bridge_attrs(ifaceobj.name)
|
||||
#self.logger.info('B' + str(runningattrs))
|
||||
if not runningattrs:
|
||||
runningattrs = {}
|
||||
running_port_list = self.brctlcmd.get_bridge_ports(ifaceobj.name)
|
||||
@@ -728,7 +708,7 @@ class mstpctl(moduleBase):
|
||||
conf = config_val[bport]
|
||||
jsonAttr = self.get_mod_subattr(k, 'jsonAttr')
|
||||
try:
|
||||
running_val = self.mstpctlcmd.get_mstpctl_bridgeport_attr(ifaceobj.name, bport, jsonAttr)
|
||||
running_val = self.mstpctlcmd.get_bridge_port_attr(ifaceobj.name, bport, jsonAttr)
|
||||
except:
|
||||
self.logger.info('%s %s: could not get running %s value'
|
||||
%(ifaceobj.name, bport, attr))
|
||||
@@ -797,8 +777,7 @@ class mstpctl(moduleBase):
|
||||
for vlistitem in vlist:
|
||||
try:
|
||||
(p, v) = vlistitem.split('=')
|
||||
currv = self.mstpctlcmd.get_bridgeport_attr(
|
||||
ifaceobj.name, p, mstpctlcmdattrname)
|
||||
currv = self._get_bridge_port_attr_value(ifaceobj.name, p, k)
|
||||
if currv:
|
||||
currstr += ' %s=%s' %(p, currv)
|
||||
else:
|
||||
@@ -844,7 +823,7 @@ class mstpctl(moduleBase):
|
||||
continue
|
||||
config_val = 'yes'
|
||||
try:
|
||||
running_val = self.mstpctlcmd.get_mstpctl_bridgeport_attr(bifaceobj.name,
|
||||
running_val = self.mstpctlcmd.get_bridge_port_attr(bifaceobj.name,
|
||||
ifaceobj.name, jsonAttr)
|
||||
except:
|
||||
self.logger.info('%s %s: could not get running %s value'
|
||||
@@ -876,6 +855,7 @@ class mstpctl(moduleBase):
|
||||
if not ifaceattrs:
|
||||
return
|
||||
runningattrs = self.mstpctlcmd.get_bridge_attrs(ifaceobj.name)
|
||||
#self.logger.info('C' + str(runningattrs))
|
||||
if not runningattrs:
|
||||
runningattrs = {}
|
||||
for k in ifaceattrs:
|
||||
@@ -885,8 +865,7 @@ class mstpctl(moduleBase):
|
||||
if not v or k in blacklistedattrs:
|
||||
ifaceobjcurr.update_config_with_status(k, v, -1)
|
||||
continue
|
||||
currv = self.mstpctlcmd.get_bridgeport_attr(bridgename,
|
||||
ifaceobj.name, self._port_attrs_map.get(k))
|
||||
currv = self._get_bridge_port_attr_value(bridgename, ifaceobj.name, k)
|
||||
if currv:
|
||||
if currv != v:
|
||||
ifaceobjcurr.update_config_with_status(k, currv, 1)
|
||||
@@ -904,6 +883,15 @@ class mstpctl(moduleBase):
|
||||
else:
|
||||
self._query_check_bridge_port(ifaceobj, ifaceobjcurr)
|
||||
|
||||
def _query_bridge_port_attr(self, ifaceobjrunning, bridgename, attr, value_cmp):
|
||||
v = self._get_bridge_port_attr_value(bridgename,
|
||||
ifaceobjrunning.name,
|
||||
attr)
|
||||
if v and value_cmp and v != value_cmp:
|
||||
ifaceobjrunning.update_config(attr, v)
|
||||
elif v and not value_cmp:
|
||||
ifaceobjrunning.update_config(attr, v)
|
||||
|
||||
def _query_running_bridge_port(self, ifaceobjrunning):
|
||||
bridgename = self.ipcmd.bridge_port_get_bridge_name(
|
||||
ifaceobjrunning.name)
|
||||
@@ -915,27 +903,20 @@ class mstpctl(moduleBase):
|
||||
# This bridge does not run stp, return
|
||||
return
|
||||
# if userspace stp not set, return
|
||||
if self.sysctl_get('net.bridge.bridge-stp-user-space') != '1':
|
||||
if self.systcl_get_net_bridge_stp_user_space() != '1':
|
||||
return
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
|
||||
ifaceobjrunning.name,
|
||||
'portautoedge')
|
||||
if v and v != self.get_mod_subattr('mstpctl-portautoedge',
|
||||
'default'):
|
||||
ifaceobjrunning.update_config('mstpctl-portautoedge', v)
|
||||
self._query_bridge_port_attr(ifaceobjrunning, bridgename,
|
||||
'mstpctl-portautoedge',
|
||||
self.get_mod_subattr('mstpctl-portautoedge', 'default'))
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
|
||||
ifaceobjrunning.name,
|
||||
'portbpdufilter')
|
||||
if v and v != 'no':
|
||||
ifaceobjrunning.update_config('mstpctl-portbpdufilter', v)
|
||||
self._query_bridge_port_attr(ifaceobjrunning, bridgename,
|
||||
'mstpctl-portbpdufilter',
|
||||
'no')
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
|
||||
ifaceobjrunning.name,
|
||||
'portnetwork')
|
||||
if v and v != 'no':
|
||||
ifaceobjrunning.update_config('mstpctl-portnetwork', v)
|
||||
self._query_bridge_port_attr(ifaceobjrunning, bridgename,
|
||||
'mstpctl-portnetwork',
|
||||
'no')
|
||||
|
||||
# XXX: Can we really get path cost of a port ???
|
||||
#v = self.mstpctlcmd.get_portpathcost(ifaceobjrunning.name, p)
|
||||
@@ -943,30 +924,25 @@ class mstpctl(moduleBase):
|
||||
# 'default'):
|
||||
# ifaceobjrunning.update_config('mstpctl-network', v)
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
|
||||
ifaceobjrunning.name, 'portadminedge')
|
||||
if v and v != 'no':
|
||||
ifaceobjrunning.update_config('mstpctl-portadminedge', v)
|
||||
self._query_bridge_port_attr(ifaceobjrunning, bridgename,
|
||||
'mstpctl-portadminedge',
|
||||
'no')
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
|
||||
ifaceobjrunning.name,'portp2p')
|
||||
if v and v != 'auto':
|
||||
ifaceobjrunning.update_config('mstpctl-portp2p', v)
|
||||
self._query_bridge_port_attr(ifaceobjrunning, bridgename,
|
||||
'mstpctl-portp2p',
|
||||
'auto')
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
|
||||
ifaceobjrunning.name, 'portrestrrole')
|
||||
if v and v != 'no':
|
||||
ifaceobjrunning.update_config('mstpctl-portrestrrole', v)
|
||||
self._query_bridge_port_attr(ifaceobjrunning, bridgename,
|
||||
'mstpctl-portrestrrole',
|
||||
'no')
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
|
||||
ifaceobjrunning.name, 'portrestrtcn')
|
||||
if v and v != 'no':
|
||||
ifaceobjrunning.update_config('mstpctl-portrestrtcn', v)
|
||||
self._query_bridge_port_attr(ifaceobjrunning, bridgename,
|
||||
'mstpctl-portrestrtcn',
|
||||
'no')
|
||||
|
||||
v = self.mstpctlcmd.get_bridgeport_attr(bridgename,
|
||||
ifaceobjrunning.name, 'bpduguard')
|
||||
if v and v != 'no':
|
||||
ifaceobjrunning.update_config('mstpctl-bpduguard', v)
|
||||
self._query_bridge_port_attr(ifaceobjrunning, bridgename,
|
||||
'mstpctl-bpduguard',
|
||||
'no')
|
||||
|
||||
# XXX: Can we really get path cost of a port ???
|
||||
#v = self.mstpctlcmd.get_bridgeport_attr(ifaceobjrunning.name,
|
||||
@@ -986,7 +962,7 @@ class mstpctl(moduleBase):
|
||||
# This bridge does not run stp, return
|
||||
return
|
||||
# if userspace stp not set, return
|
||||
if self.sysctl_get('net.bridge.bridge-stp-user-space') != '1':
|
||||
if self.systcl_get_net_bridge_stp_user_space() != '1':
|
||||
return
|
||||
# Check if mstp really knows about this bridge
|
||||
if not self.mstpctlcmd.mstpbridge_exists(ifaceobjrunning.name):
|
||||
|
@@ -37,6 +37,8 @@ class moduleBase(object):
|
||||
re.compile(r"([A-Za-z0-9\-]+[A-Za-z])(\d+)\-(\d+)(.*)"),
|
||||
re.compile(r"([A-Za-z0-9\-]+)\[(\d+)\-(\d+)\](.*)")]
|
||||
|
||||
self._bridge_stp_user_space = None
|
||||
|
||||
|
||||
def log_warn(self, str, ifaceobj=None):
|
||||
""" log a warning if err str is not one of which we should ignore """
|
||||
@@ -251,6 +253,12 @@ class moduleBase(object):
|
||||
""" get value of sysctl variable """
|
||||
return utils.exec_command('sysctl %s' % variable).split('=')[1].strip()
|
||||
|
||||
def systcl_get_net_bridge_stp_user_space(self):
|
||||
if self._bridge_stp_user_space:
|
||||
return self._bridge_stp_user_space
|
||||
self._bridge_stp_user_space = self.sysctl_get('net.bridge.bridge-stp-user-space')
|
||||
return self._bridge_stp_user_space
|
||||
|
||||
def set_iface_attr(self, ifaceobj, attr_name, attr_valsetfunc,
|
||||
prehook=None, prehookargs=None):
|
||||
ifacename = ifaceobj.name
|
||||
|
@@ -9,7 +9,6 @@ from utilsbase import *
|
||||
from ifupdown.iface import *
|
||||
from ifupdown.utils import utils
|
||||
from cache import *
|
||||
import re
|
||||
import json
|
||||
|
||||
class mstpctlutil(utilsBase):
|
||||
@@ -51,51 +50,28 @@ class mstpctlutil(utilsBase):
|
||||
else:
|
||||
return True
|
||||
|
||||
def get_bridgeport_attr(self, bridgename, portname, attrname):
|
||||
try:
|
||||
cmdl = ['/sbin/mstpctl', 'showportdetail', bridgename, portname,
|
||||
self._bridgeportattrmap[attrname]]
|
||||
return utils.exec_commandl(cmdl).strip('\n')
|
||||
except Exception, e:
|
||||
pass
|
||||
return None
|
||||
|
||||
def get_bridgeport_attrs(self, bridgename, portname):
|
||||
bridgeattrs = {}
|
||||
try:
|
||||
bridgeattrs = dict((k, self.get_bridgeport_attr(bridgename, v))
|
||||
for k, v in self._bridgeattrmap.items())
|
||||
bridgeattrs['treeprio'] = int(bridgeattrs.get('bridgeid',
|
||||
'').split('.')[0], base=16) * 4096
|
||||
except Exception, e:
|
||||
self.logger.warn(str(e))
|
||||
pass
|
||||
return bridgeattrs
|
||||
|
||||
def _extract_bridge_port_prio(self, portid):
|
||||
try:
|
||||
return str(int(portid[0], 16) * 16)
|
||||
except:
|
||||
pass
|
||||
return mstpctlutil._DEFAULT_PORT_PRIO
|
||||
|
||||
def _get_mstpctl_bridgeport_attr_from_cache(self, bridgename):
|
||||
def _get_bridge_port_attrs_from_cache(self, bridgename):
|
||||
attrs = MSTPAttrsCache.get(bridgename)
|
||||
if not attrs:
|
||||
if attrs:
|
||||
return attrs
|
||||
mstpctl_bridgeport_attrs_dict = {}
|
||||
try:
|
||||
cmd = ['/sbin/mstpctl', 'showportdetail', bridgename, 'json']
|
||||
output = utils.exec_commandl(cmd)
|
||||
if not output:
|
||||
return None
|
||||
return mstpctl_bridgeport_attrs_dict
|
||||
except Exception as e:
|
||||
self.logger.info(str(e))
|
||||
return None
|
||||
mstpctl_bridgeport_attrs_dict = {}
|
||||
return mstpctl_bridgeport_attrs_dict
|
||||
try:
|
||||
mstpctl_bridge_cache = json.loads(output.strip('\n'))
|
||||
for portname in mstpctl_bridge_cache.keys():
|
||||
# we will ignore the portid for now and just index
|
||||
# by bridgename, portname, and json attribute
|
||||
for portid in mstpctl_bridge_cache[portname].keys():
|
||||
mstpctl_bridgeport_attrs_dict[portname] = {}
|
||||
mstpctl_bridgeport_attrs_dict[portname]['treeportprio'] = self._extract_bridge_port_prio(portid)
|
||||
@@ -103,62 +79,41 @@ class mstpctlutil(utilsBase):
|
||||
jsonVal = mstpctl_bridge_cache[portname][portid][jsonAttr]
|
||||
mstpctl_bridgeport_attrs_dict[portname][jsonAttr] = str(jsonVal)
|
||||
MSTPAttrsCache.set(bridgename, mstpctl_bridgeport_attrs_dict)
|
||||
return mstpctl_bridgeport_attrs_dict
|
||||
except Exception as e:
|
||||
self.logger.info('%s: cannot fetch mstpctl bridge port attributes: %s', str(e))
|
||||
return attrs
|
||||
self.logger.info('%s: cannot fetch mstpctl bridge port attributes: %s' % str(e))
|
||||
return mstpctl_bridgeport_attrs_dict
|
||||
|
||||
def get_mstpctl_bridgeport_attr(self, bridgename, portname, attr):
|
||||
attrs = self._get_mstpctl_bridgeport_attr_from_cache(bridgename)
|
||||
def get_bridge_ports_attrs(self, bridgename):
|
||||
return self._get_bridge_port_attrs_from_cache(bridgename)
|
||||
|
||||
def get_bridge_port_attr(self, bridgename, portname, attrname):
|
||||
attrs = self._get_bridge_port_attrs_from_cache(bridgename)
|
||||
value = attrs.get(portname, {}).get(attrname, 'no')
|
||||
if value == 'True' or value == 'true':
|
||||
return 'yes'
|
||||
return str(value)
|
||||
|
||||
def update_cache(self, bridgename, portname, attrname, value):
|
||||
attrs = self.get_bridge_ports_attrs(bridgename)
|
||||
if not attrs:
|
||||
return 'no'
|
||||
else:
|
||||
val = attrs.get(portname,{}).get(attr, 'no')
|
||||
if val == 'True':
|
||||
val = 'yes'
|
||||
return str(val)
|
||||
attrs = {}
|
||||
if not portname in attrs:
|
||||
attrs[portname] = {}
|
||||
attrs[portname][attrname] = value
|
||||
MSTPAttrsCache.set(bridgename, attrs)
|
||||
|
||||
def set_bridgeport_attrs(self, bridgename, bridgeportname, attrdict,
|
||||
check=True):
|
||||
for k, v in attrdict.iteritems():
|
||||
if not v:
|
||||
continue
|
||||
try:
|
||||
self.set_bridgeport_attr(bridgename, bridgeportname,
|
||||
k, v, check)
|
||||
except Exception, e:
|
||||
self.logger.warn(str(e))
|
||||
|
||||
def _get_bridge_port_attr_with_prio(self,
|
||||
bridgename,
|
||||
bridgeportname,
|
||||
attrname):
|
||||
attrvalue_curr = self.get_bridgeport_attr(bridgename,
|
||||
bridgeportname, attrname)
|
||||
if attrname == 'treeportprio':
|
||||
try:
|
||||
attrs = self._get_mstpctl_bridgeport_attr_from_cache(bridgename)
|
||||
attrvalue_curr = attrs[bridgeportname]['treeportprio']
|
||||
except:
|
||||
pass
|
||||
return attrvalue_curr
|
||||
|
||||
def set_bridgeport_attr(self, bridgename, bridgeportname, attrname,
|
||||
attrvalue, check=True):
|
||||
if check:
|
||||
attrvalue_curr = self._get_bridge_port_attr_with_prio(bridgename,
|
||||
bridgeportname,
|
||||
attrname)
|
||||
if attrvalue_curr and attrvalue_curr == attrvalue:
|
||||
def set_bridge_port_attr(self, bridgename, portname, attrname, value, json_attr=None):
|
||||
cache_value = self.get_bridge_port_attr(bridgename, portname, json_attr)
|
||||
if cache_value and cache_value == value:
|
||||
return
|
||||
if attrname == 'treeportcost' or attrname == 'treeportprio':
|
||||
utils.exec_commandl(['/sbin/mstpctl', 'set%s' % attrname,
|
||||
'%s' % bridgename, '%s' % bridgeportname, '0',
|
||||
'%s' % attrvalue])
|
||||
bridgename, portname, '0', value])
|
||||
else:
|
||||
utils.exec_commandl(['/sbin/mstpctl', 'set%s' % attrname,
|
||||
'%s' % bridgename, '%s' % bridgeportname,
|
||||
'%s' % attrvalue])
|
||||
bridgename, portname, value])
|
||||
if json_attr:
|
||||
self.update_cache(bridgename, portname, json_attr, value)
|
||||
|
||||
def get_bridge_attrs(self, bridgename):
|
||||
bridgeattrs = {}
|
||||
@@ -206,7 +161,6 @@ class mstpctlutil(utilsBase):
|
||||
self.set_bridge_attr(bridgename, k, v, check)
|
||||
except Exception, e:
|
||||
self.logger.warn('%s: %s' %(bridgename, str(e)))
|
||||
pass
|
||||
|
||||
def get_bridge_treeprio(self, bridgename):
|
||||
try:
|
||||
|
Reference in New Issue
Block a user