3 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
8 from ifupdown2
.ifupdown
.iface
import *
9 from ifupdown2
.ifupdown
.utils
import utils
11 from ifupdown2
.ifupdownaddons
.cache
import *
12 from ifupdown2
.ifupdownaddons
.utilsbase
import *
14 from ifupdown
.iface
import *
15 from ifupdown
.utils
import utils
17 from ifupdownaddons
.cache
import *
18 from ifupdownaddons
.utilsbase
import *
21 class mstpctlutil(utilsBase
):
22 """ This class contains helper methods to interact with mstpd using
23 mstputils commands """
25 _DEFAULT_PORT_PRIO
= '128'
27 _cache_fill_done
= False
29 _bridgeattrmap
= {'bridgeid' : 'bridge-id',
31 'fdelay' : 'forward-delay',
32 'txholdcount' : 'tx-hold-count',
33 'maxhops' : 'max-hops',
34 'ageing' : 'ageing-time',
35 'hello' : 'hello-time',
36 'forcevers' : 'force-protocol-version'}
38 _bridge_jsonAttr_map
= {
39 'treeprio': 'bridgeId',
42 'txholdcount': 'txHoldCounter',
44 'ageing': 'ageingTime',
46 'forcevers': 'forceProtocolVersion',
49 _bridgeportattrmap
= {'portadminedge' : 'admin-edge-port',
50 'portp2p' : 'admin-point-to-point',
51 'portrestrrole' : 'restricted-role',
52 'portrestrtcn' : 'restricted-TCN',
53 'bpduguard' : 'bpdu-guard-port',
54 'portautoedge' : 'auto-edge-port',
55 'portnetwork' : 'network-port',
56 'portbpdufilter' : 'bpdufilter-port',
57 'portpathcost' : 'external-port-cost',
58 'treeportcost' : 'internal-port-cost'}
60 def __init__(self
, *args
, **kargs
):
61 utilsBase
.__init
__(self
, *args
, **kargs
)
65 cls
._cache
_fill
_done
= False
67 def is_mstpd_running(self
):
69 utils
.exec_command('%s mstpd'%utils
.pidof_cmd
)
75 def _extract_bridge_port_prio(self
, portid
):
77 return str(int(portid
[0], 16) * 16)
79 return mstpctlutil
._DEFAULT
_PORT
_PRIO
81 def _get_bridge_and_port_attrs_from_cache(self
, bridgename
):
82 attrs
= MSTPAttrsCache
.get(bridgename
, None)
85 mstpctl_bridgeport_attrs_dict
= {}
87 cmd
= [utils
.mstpctl_cmd
,
88 'showportdetail', bridgename
, 'json']
89 output
= utils
.exec_commandl(cmd
)
91 MSTPAttrsCache
.set(bridgename
, mstpctl_bridgeport_attrs_dict
)
92 return mstpctl_bridgeport_attrs_dict
93 except Exception as e
:
94 self
.logger
.info(str(e
))
95 return mstpctl_bridgeport_attrs_dict
97 mstpctl_bridge_cache
= json
.loads(output
.strip('\n'))
98 for portname
in mstpctl_bridge_cache
.keys():
99 for portid
in mstpctl_bridge_cache
[portname
].keys():
100 mstpctl_bridgeport_attrs_dict
[portname
] = {}
101 mstpctl_bridgeport_attrs_dict
[portname
]['treeportprio'] = self
._extract
_bridge
_port
_prio
(portid
)
102 for jsonAttr
in mstpctl_bridge_cache
[portname
][portid
].keys():
103 jsonVal
= mstpctl_bridge_cache
[portname
][portid
][jsonAttr
]
104 mstpctl_bridgeport_attrs_dict
[portname
][jsonAttr
] = str(jsonVal
)
105 MSTPAttrsCache
.set(bridgename
, mstpctl_bridgeport_attrs_dict
)
106 except Exception as e
:
107 self
.logger
.info('%s: cannot fetch mstpctl bridge port attributes: %s' % str(e
))
109 mstpctl_bridge_attrs_dict
= {}
111 cmd
= [utils
.mstpctl_cmd
,
112 'showbridge', 'json', bridgename
]
113 output
= utils
.exec_commandl(cmd
)
115 return mstpctl_bridge_attrs_dict
116 except Exception as e
:
117 self
.logger
.info(str(e
))
118 return mstpctl_bridge_attrs_dict
120 mstpctl_bridge_cache
= json
.loads(output
.strip('\n'))
121 for jsonAttr
in mstpctl_bridge_cache
[bridgename
].keys():
122 mstpctl_bridge_attrs_dict
[jsonAttr
] = (
123 str(mstpctl_bridge_cache
[bridgename
][jsonAttr
]))
124 mstpctl_bridge_attrs_dict
['treeprio'] = '%d' %(
125 int(mstpctl_bridge_attrs_dict
.get('bridgeId',
126 '').split('.')[0], base
=16) * 4096)
127 del mstpctl_bridge_attrs_dict
['bridgeId']
128 MSTPAttrsCache
.bridges
[bridgename
].update(mstpctl_bridge_attrs_dict
)
129 except Exception as e
:
130 self
.logger
.info('%s: cannot fetch mstpctl bridge attributes: %s' % str(e
))
131 return MSTPAttrsCache
.get(bridgename
)
133 def get_bridge_ports_attrs(self
, bridgename
):
134 return self
._get
_bridge
_and
_port
_attrs
_from
_cache
(bridgename
)
136 def get_bridge_port_attr(self
, bridgename
, portname
, attrname
):
137 attrs
= self
._get
_bridge
_and
_port
_attrs
_from
_cache
(bridgename
)
138 value
= attrs
.get(portname
, {}).get(attrname
, 'no')
139 if value
== 'True' or value
== 'true':
143 def update_bridge_port_cache(self
, bridgename
, portname
, attrname
, value
):
144 attrs
= self
.get_bridge_ports_attrs(bridgename
)
147 if not portname
in attrs
:
149 attrs
[portname
][attrname
] = value
150 MSTPAttrsCache
.set(bridgename
, attrs
)
152 def update_bridge_cache(self
, bridgename
, attrname
, value
):
153 attrs
= self
.get_bridge_ports_attrs(bridgename
)
156 attrs
[attrname
] = value
157 MSTPAttrsCache
.set(bridgename
, attrs
)
159 def set_bridge_port_attr(self
, bridgename
, portname
, attrname
, value
, json_attr
=None):
160 cache_value
= self
.get_bridge_port_attr(bridgename
, portname
, json_attr
)
161 if cache_value
and cache_value
== value
:
163 if attrname
== 'treeportcost' or attrname
== 'treeportprio':
164 utils
.exec_commandl([utils
.mstpctl_cmd
, 'set%s' % attrname
,
165 bridgename
, portname
, '0', value
])
167 utils
.exec_commandl([utils
.mstpctl_cmd
, 'set%s' % attrname
,
168 bridgename
, portname
, value
])
170 self
.update_bridge_port_cache(bridgename
, portname
, json_attr
, value
)
172 def get_bridge_attrs(self
, bridgename
):
175 bridgeattrs
= dict((k
, self
.get_bridge_attr(bridgename
, v
))
176 for k
,v
in self
._bridge
_jsonAttr
_map
.items())
178 self
.logger
.debug(bridgeattrs
)
179 self
.logger
.debug(str(e
))
183 def get_bridge_attr(self
, bridgename
, attrname
):
184 if attrname
== 'bridgeId':
185 attrname
= 'treeprio'
186 return self
._get
_bridge
_and
_port
_attrs
_from
_cache
(bridgename
).get(attrname
)
188 def set_bridge_attr(self
, bridgename
, attrname
, attrvalue
, check
=True):
191 if attrname
== 'treeprio':
192 attrvalue_curr
= self
.get_bridge_attr(bridgename
, attrname
)
194 attrvalue_curr
= self
.get_bridge_attr(bridgename
,
195 self
._bridge
_jsonAttr
_map
[attrname
])
196 if attrvalue_curr
and attrvalue_curr
== attrvalue
:
198 if attrname
== 'treeprio':
199 utils
.exec_commandl([utils
.mstpctl_cmd
, 'set%s' % attrname
,
200 '%s' % bridgename
, '0', '%s' % attrvalue
], stderr
=None)
201 self
.update_bridge_cache(bridgename
, attrname
, str(attrvalue
))
203 utils
.exec_commandl([utils
.mstpctl_cmd
, 'set%s' % attrname
,
204 '%s' % bridgename
, '%s' % attrvalue
], stderr
=None)
205 self
.update_bridge_cache(bridgename
,
206 self
._bridge
_jsonAttr
_map
[attrname
],
209 def set_bridge_attrs(self
, bridgename
, attrdict
, check
=True):
210 for k
, v
in attrdict
.iteritems():
214 self
.set_bridge_attr(bridgename
, k
, v
, check
)
216 self
.logger
.warn('%s: %s' %(bridgename
, str(e
)))
218 def get_bridge_treeprio(self
, bridgename
):
219 return self
.get_bridge_attr(bridgename
, 'treeprio')
221 def set_bridge_treeprio(self
, bridgename
, attrvalue
, check
=True):
223 attrvalue_curr
= self
.get_bridge_treeprio(bridgename
)
224 if attrvalue_curr
and attrvalue_curr
== attrvalue
:
226 utils
.exec_commandl([utils
.mstpctl_cmd
,
227 'settreeprio', bridgename
, '0',
229 self
.update_bridge_cache(bridgename
, 'treeprio', str(attrvalue
))
231 def showbridge(self
, bridgename
=None):
233 return utils
.exec_command('%s showbridge %s' %
234 (utils
.mstpctl_cmd
, bridgename
))
236 return utils
.exec_command('%s showbridge' %utils
.mstpctl_cmd
)
238 def showportdetail(self
, bridgename
):
239 return utils
.exec_command('%s showportdetail %s' %
240 (utils
.mstpctl_cmd
, bridgename
))
242 def mstpbridge_exists(self
, bridgename
):
244 utils
.exec_command('%s showbridge %s' %
245 (utils
.mstpctl_cmd
, bridgename
))