]> git.proxmox.com Git - mirror_ifupdown2.git/blame - ifupdown2/ifupdownaddons/mstpctlutil.py
bridge: vlan-aware: add new boolean policy "vlan_aware_bridge_address_support"
[mirror_ifupdown2.git] / ifupdown2 / ifupdownaddons / mstpctlutil.py
CommitLineData
15ef32ea
RP
1#!/usr/bin/python
2#
d486dd0d 3# Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
15ef32ea
RP
4# Author: Roopa Prabhu, roopa@cumulusnetworks.com
5#
6
d486dd0d
JF
7try:
8 from ifupdown2.ifupdown.iface import *
9 from ifupdown2.ifupdown.utils import utils
10
11 from ifupdown2.ifupdownaddons.cache import *
12 from ifupdown2.ifupdownaddons.utilsbase import *
13except ImportError:
14 from ifupdown.iface import *
15 from ifupdown.utils import utils
16
17 from ifupdownaddons.cache import *
18 from ifupdownaddons.utilsbase import *
19
15ef32ea
RP
20
21class mstpctlutil(utilsBase):
22 """ This class contains helper methods to interact with mstpd using
23 mstputils commands """
24
bfceb635
JF
25 _DEFAULT_PORT_PRIO = '128'
26
15ef32ea
RP
27 _cache_fill_done = False
28
29 _bridgeattrmap = {'bridgeid' : 'bridge-id',
30 'maxage' : 'max-age',
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'}
37
e3089aa8
N
38 _bridge_jsonAttr_map = {
39 'treeprio': 'bridgeId',
40 'maxage': 'maxAge',
41 'fdelay': 'fwdDelay',
42 'txholdcount': 'txHoldCounter',
43 'maxhops': 'maxHops',
44 'ageing': 'ageingTime',
45 'hello': 'helloTime',
46 'forcevers': 'forceProtocolVersion',
47 }
48
15ef32ea 49 _bridgeportattrmap = {'portadminedge' : 'admin-edge-port',
2ca1b884 50 'portp2p' : 'admin-point-to-point',
15ef32ea
RP
51 'portrestrrole' : 'restricted-role',
52 'portrestrtcn' : 'restricted-TCN',
53 'bpduguard' : 'bpdu-guard-port',
54 'portautoedge' : 'auto-edge-port',
55 'portnetwork' : 'network-port',
22945dd6
N
56 'portbpdufilter' : 'bpdufilter-port',
57 'portpathcost' : 'external-port-cost',
58 'treeportcost' : 'internal-port-cost'}
15ef32ea
RP
59
60 def __init__(self, *args, **kargs):
61 utilsBase.__init__(self, *args, **kargs)
62
d486dd0d
JF
63 @classmethod
64 def reset(cls):
65 cls._cache_fill_done = False
66
15ef32ea
RP
67 def is_mstpd_running(self):
68 try:
d486dd0d 69 utils.exec_command('%s mstpd'%utils.pidof_cmd)
15ef32ea
RP
70 except:
71 return False
72 else:
73 return True
74
bfceb635
JF
75 def _extract_bridge_port_prio(self, portid):
76 try:
77 return str(int(portid[0], 16) * 16)
78 except:
9d3f53c6 79 return mstpctlutil._DEFAULT_PORT_PRIO
bfceb635 80
d03b0695 81 def _get_bridge_and_port_attrs_from_cache(self, bridgename):
b47ce90d 82 attrs = MSTPAttrsCache.get(bridgename)
9d3f53c6
JF
83 if attrs:
84 return attrs
85 mstpctl_bridgeport_attrs_dict = {}
86 try:
d486dd0d
JF
87 cmd = [utils.mstpctl_cmd,
88 'showportdetail', bridgename, 'json']
9d3f53c6
JF
89 output = utils.exec_commandl(cmd)
90 if not output:
b47ce90d 91 return mstpctl_bridgeport_attrs_dict
9d3f53c6
JF
92 except Exception as e:
93 self.logger.info(str(e))
94 return mstpctl_bridgeport_attrs_dict
95 try:
96 mstpctl_bridge_cache = json.loads(output.strip('\n'))
97 for portname in mstpctl_bridge_cache.keys():
98 for portid in mstpctl_bridge_cache[portname].keys():
99 mstpctl_bridgeport_attrs_dict[portname] = {}
100 mstpctl_bridgeport_attrs_dict[portname]['treeportprio'] = self._extract_bridge_port_prio(portid)
101 for jsonAttr in mstpctl_bridge_cache[portname][portid].keys():
102 jsonVal = mstpctl_bridge_cache[portname][portid][jsonAttr]
103 mstpctl_bridgeport_attrs_dict[portname][jsonAttr] = str(jsonVal)
104 MSTPAttrsCache.set(bridgename, mstpctl_bridgeport_attrs_dict)
105 except Exception as e:
106 self.logger.info('%s: cannot fetch mstpctl bridge port attributes: %s' % str(e))
9d3f53c6 107
e3089aa8
N
108 mstpctl_bridge_attrs_dict = {}
109 try:
d486dd0d
JF
110 cmd = [utils.mstpctl_cmd,
111 'showbridge', 'json', bridgename]
e3089aa8
N
112 output = utils.exec_commandl(cmd)
113 if not output:
114 return mstpctl_bridge_attrs_dict
115 except Exception as e:
116 self.logger.info(str(e))
117 return mstpctl_bridge_attrs_dict
118 try:
119 mstpctl_bridge_cache = json.loads(output.strip('\n'))
120 for jsonAttr in mstpctl_bridge_cache[bridgename].keys():
121 mstpctl_bridge_attrs_dict[jsonAttr] = (
122 str(mstpctl_bridge_cache[bridgename][jsonAttr]))
123 mstpctl_bridge_attrs_dict['treeprio'] = '%d' %(
124 int(mstpctl_bridge_attrs_dict.get('bridgeId',
125 '').split('.')[0], base=16) * 4096)
126 del mstpctl_bridge_attrs_dict['bridgeId']
d03b0695 127 MSTPAttrsCache.bridges[bridgename].update(mstpctl_bridge_attrs_dict)
e3089aa8
N
128 except Exception as e:
129 self.logger.info('%s: cannot fetch mstpctl bridge attributes: %s' % str(e))
d03b0695 130 return MSTPAttrsCache.get(bridgename)
e3089aa8 131
9d3f53c6 132 def get_bridge_ports_attrs(self, bridgename):
d03b0695 133 return self._get_bridge_and_port_attrs_from_cache(bridgename)
9d3f53c6
JF
134
135 def get_bridge_port_attr(self, bridgename, portname, attrname):
d03b0695 136 attrs = self._get_bridge_and_port_attrs_from_cache(bridgename)
9d3f53c6
JF
137 value = attrs.get(portname, {}).get(attrname, 'no')
138 if value == 'True' or value == 'true':
139 return 'yes'
140 return str(value)
141
e3089aa8 142 def update_bridge_port_cache(self, bridgename, portname, attrname, value):
9d3f53c6 143 attrs = self.get_bridge_ports_attrs(bridgename)
b47ce90d 144 if not attrs:
9d3f53c6
JF
145 attrs = {}
146 if not portname in attrs:
147 attrs[portname] = {}
148 attrs[portname][attrname] = value
149 MSTPAttrsCache.set(bridgename, attrs)
150
e3089aa8
N
151 def update_bridge_cache(self, bridgename, attrname, value):
152 attrs = self.get_bridge_ports_attrs(bridgename)
153 if not attrs:
154 attrs = {}
155 attrs[attrname] = value
156 MSTPAttrsCache.set(bridgename, attrs)
157
9d3f53c6
JF
158 def set_bridge_port_attr(self, bridgename, portname, attrname, value, json_attr=None):
159 cache_value = self.get_bridge_port_attr(bridgename, portname, json_attr)
160 if cache_value and cache_value == value:
161 return
15ef32ea 162 if attrname == 'treeportcost' or attrname == 'treeportprio':
d486dd0d 163 utils.exec_commandl([utils.mstpctl_cmd, 'set%s' % attrname,
9d3f53c6 164 bridgename, portname, '0', value])
15ef32ea 165 else:
d486dd0d 166 utils.exec_commandl([utils.mstpctl_cmd, 'set%s' % attrname,
9d3f53c6
JF
167 bridgename, portname, value])
168 if json_attr:
e3089aa8 169 self.update_bridge_port_cache(bridgename, portname, json_attr, value)
15ef32ea
RP
170
171 def get_bridge_attrs(self, bridgename):
172 bridgeattrs = {}
173 try:
e3089aa8
N
174 bridgeattrs = dict((k, self.get_bridge_attr(bridgename, v))
175 for k,v in self._bridge_jsonAttr_map.items())
15ef32ea 176 except Exception, e:
2ca1b884
RP
177 self.logger.debug(bridgeattrs)
178 self.logger.debug(str(e))
15ef32ea
RP
179 pass
180 return bridgeattrs
181
182 def get_bridge_attr(self, bridgename, attrname):
e3089aa8
N
183 if attrname == 'bridgeId':
184 attrname = 'treeprio'
d03b0695 185 return self._get_bridge_and_port_attrs_from_cache(bridgename).get(attrname)
15ef32ea
RP
186
187 def set_bridge_attr(self, bridgename, attrname, attrvalue, check=True):
188
189 if check:
e3089aa8
N
190 if attrname == 'treeprio':
191 attrvalue_curr = self.get_bridge_attr(bridgename, attrname)
192 else:
193 attrvalue_curr = self.get_bridge_attr(bridgename,
194 self._bridge_jsonAttr_map[attrname])
15ef32ea
RP
195 if attrvalue_curr and attrvalue_curr == attrvalue:
196 return
197 if attrname == 'treeprio':
d486dd0d
JF
198 utils.exec_commandl([utils.mstpctl_cmd, 'set%s' % attrname,
199 '%s' % bridgename, '0', '%s' % attrvalue], stderr=None)
e3089aa8 200 self.update_bridge_cache(bridgename, attrname, str(attrvalue))
15ef32ea 201 else:
d486dd0d
JF
202 utils.exec_commandl([utils.mstpctl_cmd, 'set%s' % attrname,
203 '%s' % bridgename, '%s' % attrvalue], stderr=None)
e3089aa8
N
204 self.update_bridge_cache(bridgename,
205 self._bridge_jsonAttr_map[attrname],
206 str(attrvalue))
15ef32ea
RP
207
208 def set_bridge_attrs(self, bridgename, attrdict, check=True):
209 for k, v in attrdict.iteritems():
210 if not v:
211 continue
212 try:
213 self.set_bridge_attr(bridgename, k, v, check)
214 except Exception, e:
215 self.logger.warn('%s: %s' %(bridgename, str(e)))
15ef32ea
RP
216
217 def get_bridge_treeprio(self, bridgename):
e3089aa8 218 return self.get_bridge_attr(bridgename, 'treeprio')
15ef32ea
RP
219
220 def set_bridge_treeprio(self, bridgename, attrvalue, check=True):
221 if check:
222 attrvalue_curr = self.get_bridge_treeprio(bridgename)
223 if attrvalue_curr and attrvalue_curr == attrvalue:
224 return
d486dd0d
JF
225 utils.exec_commandl([utils.mstpctl_cmd,
226 'settreeprio', bridgename, '0',
a193d8d1 227 str(attrvalue)])
e3089aa8 228 self.update_bridge_cache(bridgename, 'treeprio', str(attrvalue))
15ef32ea
RP
229
230 def showbridge(self, bridgename=None):
231 if bridgename:
d486dd0d
JF
232 return utils.exec_command('%s showbridge %s' %
233 (utils.mstpctl_cmd, bridgename))
15ef32ea 234 else:
d486dd0d 235 return utils.exec_command('%s showbridge' %utils.mstpctl_cmd)
15ef32ea
RP
236
237 def showportdetail(self, bridgename):
d486dd0d
JF
238 return utils.exec_command('%s showportdetail %s' %
239 (utils.mstpctl_cmd, bridgename))
15ef32ea
RP
240
241 def mstpbridge_exists(self, bridgename):
242 try:
d486dd0d
JF
243 utils.exec_command('%s showbridge %s' %
244 (utils.mstpctl_cmd, bridgename))
15ef32ea
RP
245 return True
246 except:
247 return False