]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdownaddons/bondutil.py
3 # Copyright 2014 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
9 import ifupdown
.ifupdownflags
as ifupdownflags
10 from ifupdown
.utils
import utils
11 from ifupdown
.iface
import *
12 from utilsbase
import *
13 from iproute2
import *
16 class bondutil(utilsBase
):
17 """ This class contains methods to interact with linux kernel bond
18 related interfaces """
20 _cache_fill_done
= False
22 def __init__(self
, *args
, **kargs
):
23 utilsBase
.__init
__(self
, *args
, **kargs
)
24 if ifupdownflags
.flags
.CACHE
and not self
._cache
_fill
_done
:
25 self
._bond
_linkinfo
_fill
_all
()
26 self
._cache
_fill
_done
= True
28 def _bond_linkinfo_fill_attrs(self
, bondname
):
30 linkCache
.links
[bondname
]['linkinfo'] = {}
32 linkCache
.links
[bondname
] = {'linkinfo': {}}
35 linkCache
.set_attr([bondname
, 'linkinfo', 'min_links'],
36 self
.read_file_oneline(
37 '/sys/class/net/%s/bonding/min_links'
39 except Exception as e
:
40 self
.logger
.debug(str(e
))
42 linkCache
.set_attr([bondname
, 'linkinfo', 'slaves'],
43 self
.read_file_oneline('/sys/class/net/%s/bonding/slaves'
45 except Exception as e
:
46 self
.logger
.debug(str(e
))
48 linkCache
.set_attr([bondname
, 'linkinfo', 'mode'],
49 self
.read_file_oneline('/sys/class/net/%s/bonding/mode'
50 %bondname
).split()[0])
51 except Exception as e
:
52 self
.logger
.debug(str(e
))
54 linkCache
.set_attr([bondname
, 'linkinfo', 'xmit_hash_policy'],
55 self
.read_file_oneline(
56 '/sys/class/net/%s/bonding/xmit_hash_policy'
57 %bondname
).split()[0])
58 except Exception as e
:
59 self
.logger
.debug(str(e
))
61 linkCache
.set_attr([bondname
, 'linkinfo', 'lacp_rate'],
62 self
.read_file_oneline('/sys/class/net/%s/bonding/lacp_rate'
63 %bondname
).split()[1])
64 except Exception as e
:
65 self
.logger
.debug(str(e
))
67 linkCache
.set_attr([bondname
, 'linkinfo', 'ad_actor_sys_prio'],
68 self
.read_file_oneline('/sys/class/net/%s/bonding/ad_actor_sys_prio'
70 except Exception as e
:
71 self
.logger
.debug(str(e
))
73 linkCache
.set_attr([bondname
, 'linkinfo', 'ad_actor_system'],
74 self
.read_file_oneline('/sys/class/net/%s/bonding/ad_actor_system'
76 except Exception as e
:
77 self
.logger
.debug(str(e
))
79 linkCache
.set_attr([bondname
, 'linkinfo', 'lacp_bypass'],
80 self
.read_file_oneline('/sys/class/net/%s/bonding/lacp_bypass'
81 %bondname
).split()[1])
82 except Exception as e
:
83 self
.logger
.debug(str(e
))
85 linkCache
.set_attr([bondname
, 'linkinfo', 'updelay'],
86 self
.read_file_oneline('/sys/class/net/%s/bonding/updelay'
88 except Exception as e
:
89 self
.logger
.debug(str(e
))
91 linkCache
.set_attr([bondname
, 'linkinfo', 'downdelay'],
92 self
.read_file_oneline('/sys/class/net/%s/bonding/downdelay'
94 except Exception as e
:
95 self
.logger
.debug(str(e
))
97 map(lambda x
: linkCache
.set_attr([bondname
, 'linkinfo', x
],
98 self
.read_file_oneline('/sys/class/net/%s/bonding/%s'
100 ['use_carrier', 'miimon', 'min_links', 'num_unsol_na',
102 except Exception as e
:
103 self
.logger
.debug(str(e
))
105 def _bond_linkinfo_fill_all(self
):
106 bondstr
= self
.read_file_oneline('/sys/class/net/bonding_masters')
109 [self
._bond
_linkinfo
_fill
_attrs
(b
) for b
in bondstr
.split()]
111 def _bond_linkinfo_fill(self
, bondname
, refresh
=False):
114 linkCache
.get_attr([bondname
, 'linkinfo', 'slaves'])
118 bondstr
= self
.read_file_oneline('/sys/class/net/bonding_masters')
119 if (not bondstr
or bondname
not in bondstr
.split()):
120 raise Exception('bond %s not found' %bondname
)
121 self
._bond
_linkinfo
_fill
_attrs
(bondname
)
123 def _cache_get(self
, attrlist
, refresh
=False):
125 if ifupdownflags
.flags
.DRYRUN
:
127 if ifupdownflags
.flags
.CACHE
:
128 if not bondutil
._cache
_fill
_done
:
129 self
._bond
_linkinfo
_fill
_all
()
130 bondutil
._cache
_fill
_done
= True
131 return linkCache
.get_attr(attrlist
)
133 return linkCache
.get_attr(attrlist
)
134 self
._bond
_linkinfo
_fill
(attrlist
[0], refresh
)
135 return linkCache
.get_attr(attrlist
)
137 self
.logger
.debug('_cache_get(%s) : [%s]'
138 %(str(attrlist
), str(e
)))
142 def _cache_check(self
, attrlist
, value
, refresh
=False):
144 attrvalue
= self
._cache
_get
(attrlist
, refresh
)
145 if attrvalue
and attrvalue
== value
:
148 self
.logger
.debug('_cache_check(%s) : [%s]'
149 %(str(attrlist
), str(e
)))
153 def _cache_update(self
, attrlist
, value
):
154 if ifupdownflags
.flags
.DRYRUN
: return
156 if attrlist
[-1] == 'slaves':
157 linkCache
.add_to_attrlist(attrlist
, value
)
159 linkCache
.add_attr(attrlist
, value
)
163 def _cache_delete(self
, attrlist
, value
=None):
164 if ifupdownflags
.flags
.DRYRUN
: return
166 if attrlist
[-1] == 'slaves':
167 linkCache
.remove_from_attrlist(attrlist
, value
)
169 linkCache
.del_attr(attrlist
)
173 def _cache_invalidate(self
):
174 if ifupdownflags
.flags
.DRYRUN
: return
175 linkCache
.invalidate()
177 def set_attrs(self
, bondname
, attrdict
, prehook
):
178 for attrname
, attrval
in attrdict
.items():
179 if (self
._cache
_check
([bondname
, 'linkinfo',
180 attrname
], attrval
)):
182 if (attrname
== 'mode' or attrname
== 'xmit_hash_policy' or
183 attrname
== 'lacp_rate' or attrname
== 'min_links'):
187 if ((attrname
not in ['lacp_rate',
189 self
._cache
_check
([bondname
, 'linkinfo', 'mode'], '802.3ad',
191 self
.write_file('/sys/class/net/%s/bonding/%s'
192 %(bondname
, attrname
), attrval
)
194 if ifupdownflags
.flags
.FORCE
:
195 self
.logger
.warn(str(e
))
200 def set_use_carrier(self
, bondname
, use_carrier
):
201 if not use_carrier
or (use_carrier
!= '0' and use_carrier
!= '1'):
203 if (self
._cache
_check
([bondname
, 'linkinfo', 'use_carrier'],
206 self
.write_file('/sys/class/net/%s' %bondname
+
207 '/bonding/use_carrier', use_carrier
)
208 self
._cache
_update
([bondname
, 'linkinfo',
209 'use_carrier'], use_carrier
)
211 def get_use_carrier(self
, bondname
):
212 return self
._cache
_get
([bondname
, 'linkinfo', 'use_carrier'])
214 def set_xmit_hash_policy(self
, bondname
, hash_policy
, prehook
=None):
215 valid_values
= ['layer2', 'layer3+4', 'layer2+3']
218 if hash_policy
not in valid_values
:
219 raise Exception('invalid hash policy value %s' %hash_policy
)
220 if (self
._cache
_check
([bondname
, 'linkinfo', 'xmit_hash_policy'],
225 self
.write_file('/sys/class/net/%s' %bondname
+
226 '/bonding/xmit_hash_policy', hash_policy
)
227 self
._cache
_update
([bondname
, 'linkinfo', 'xmit_hash_policy'],
230 def get_xmit_hash_policy(self
, bondname
):
231 return self
._cache
_get
([bondname
, 'linkinfo', 'xmit_hash_policy'])
233 def set_miimon(self
, bondname
, miimon
):
234 if (self
._cache
_check
([bondname
, 'linkinfo', 'miimon'],
237 self
.write_file('/sys/class/net/%s' %bondname
+
238 '/bonding/miimon', miimon
)
239 self
._cache
_update
([bondname
, 'linkinfo', 'miimon'], miimon
)
241 def get_miimon(self
, bondname
):
242 return self
._cache
_get
([bondname
, 'linkinfo', 'miimon'])
244 def set_mode(self
, bondname
, mode
, prehook
=None):
245 valid_modes
= ['balance-rr', 'active-backup', 'balance-xor',
246 'broadcast', '802.3ad', 'balance-tlb', 'balance-alb']
249 if mode
not in valid_modes
:
250 raise Exception('invalid mode %s' %mode
)
251 if (self
._cache
_check
([bondname
, 'linkinfo', 'mode'],
256 self
.write_file('/sys/class/net/%s' %bondname
+ '/bonding/mode', mode
)
257 self
._cache
_update
([bondname
, 'linkinfo', 'mode'], mode
)
259 def get_mode(self
, bondname
):
260 return self
._cache
_get
([bondname
, 'linkinfo', 'mode'])
262 def set_lacp_rate(self
, bondname
, lacp_rate
, prehook
=None, posthook
=None):
263 if not lacp_rate
or (lacp_rate
!= '0' and lacp_rate
!= '1'):
265 if (self
._cache
_check
([bondname
, 'linkinfo', 'lacp_rate'],
271 self
.write_file('/sys/class/net/%s' %bondname
+
272 '/bonding/lacp_rate', lacp_rate
)
278 self
._cache
_update
([bondname
, 'linkinfo',
279 'lacp_rate'], lacp_rate
)
281 def get_lacp_rate(self
, bondname
):
282 return self
._cache
_get
([bondname
, 'linkinfo', 'lacp_rate'])
284 def set_lacp_bypass_allow(self
, bondname
, allow
, prehook
=None, posthook
=None):
285 if (self
._cache
_check
([bondname
, 'linkinfo', 'lacp_bypass'], allow
)):
290 self
.write_file('/sys/class/net/%s' %bondname
+
291 '/bonding/lacp_bypass', allow
)
297 self
._cache
_update
([bondname
, 'linkinfo',
298 'lacp_bypass'], allow
)
300 def get_lacp_bypass_allow(self
, bondname
):
301 return self
._cache
_get
([bondname
, 'linkinfo', 'lacp_bypass'])
303 def set_min_links(self
, bondname
, min_links
, prehook
=None):
304 if (self
._cache
_check
([bondname
, 'linkinfo', 'min_links'],
309 self
.write_file('/sys/class/net/%s/bonding/min_links' %bondname
,
311 self
._cache
_update
([bondname
, 'linkinfo', 'min_links'], min_links
)
313 def get_min_links(self
, bondname
):
314 return self
._cache
_get
([bondname
, 'linkinfo', 'min_links'])
316 def get_ad_actor_system(self
, bondname
):
317 return self
._cache
_get
([bondname
, 'linkinfo', 'ad_actor_system'])
319 def get_ad_actor_sys_prio(self
, bondname
):
320 return self
._cache
_get
([bondname
, 'linkinfo', 'ad_actor_sys_prio'])
322 def get_num_unsol_na(self
, bondname
):
323 return self
._cache
_get
([bondname
, 'linkinfo', 'num_unsol_na'])
325 def get_num_grat_arp(self
, bondname
):
326 return self
._cache
_get
([bondname
, 'linkinfo', 'num_grat_arp'])
328 def get_updelay(self
, bondname
):
329 return self
._cache
_get
([bondname
, 'linkinfo', 'updelay'])
331 def get_downdelay(self
, bondname
):
332 return self
._cache
_get
([bondname
, 'linkinfo', 'downdelay'])
334 def enslave_slave(self
, bondname
, slave
, prehook
=None, posthook
=None):
335 slaves
= self
._cache
_get
([bondname
, 'linkinfo', 'slaves'])
336 if slaves
and slave
in slaves
: return
339 self
.write_file('/sys/class/net/%s' %bondname
+
340 '/bonding/slaves', '+' + slave
)
343 self
._cache
_update
([bondname
, 'linkinfo', 'slaves'], slave
)
345 def remove_slave(self
, bondname
, slave
):
346 slaves
= self
._cache
_get
([bondname
, 'linkinfo', 'slaves'])
347 if slave
not in slaves
:
349 sysfs_bond_path
= ('/sys/class/net/%s' %bondname
+
351 if not os
.path
.exists(sysfs_bond_path
):
353 self
.write_file(sysfs_bond_path
, '-' + slave
)
354 self
._cache
_delete
([bondname
, 'linkinfo', 'slaves'], slave
)
356 def remove_slaves_all(self
, bondname
):
357 if not self
._cache
_get
([bondname
, 'linkinfo', 'slaves']):
360 sysfs_bond_path
= ('/sys/class/net/%s' %bondname
+
364 with
open(sysfs_bond_path
, 'r') as f
:
365 slaves
= f
.readline().strip().split()
367 raise Exception('error reading slaves of bond %s' %bondname
368 + '(' + str(e
) + ')')
370 ipcmd
.ip_link_down(slave
)
372 self
.remove_slave(bondname
, slave
)
374 if not ifupdownflags
.flags
.FORCE
:
375 raise Exception('error removing slave %s'
376 %slave
+ ' from bond %s' %bondname
+
380 self
._cache
_del
([bondname
, 'linkinfo', 'slaves'])
382 def load_bonding_module(self
):
383 return utils
.exec_command('modprobe -q bonding')
385 def create_bond(self
, bondname
):
386 if self
.bond_exists(bondname
):
388 sysfs_net
= '/sys/class/net/'
389 sysfs_bonding_masters
= sysfs_net
+ 'bonding_masters'
390 if not os
.path
.exists(sysfs_bonding_masters
):
391 self
.logger
.debug('loading bonding driver')
392 self
.load_bonding_module()
393 self
.write_file(sysfs_bonding_masters
, '+' + bondname
)
394 self
._cache
_update
([bondname
], {})
396 def delete_bond(self
, bondname
):
397 if not os
.path
.exists('/sys/class/net/%s' %bondname
):
399 self
.write_file('/sys/class/net/bonding_masters', '-' + bondname
)
400 self
._cache
_delete
([bondname
])
402 def unset_master(self
, bondname
):
403 print 'Do nothing yet'
406 def get_slaves(self
, bondname
):
407 slaves
= self
._cache
_get
([bondname
, 'linkinfo', 'slaves'])
410 slavefile
= '/sys/class/net/%s/bonding/slaves' %bondname
411 if os
.path
.exists(slavefile
):
412 buf
= self
.read_file_oneline(slavefile
)
417 self
._cache
_update
([bondname
, 'linkinfo', 'slaves'], slaves
)
420 def bond_slave_exists(self
, bond
, slave
):
421 slaves
= self
.get_slaves(bond
)
422 if not slaves
: return False
423 return slave
in slaves
425 def bond_exists(self
, bondname
):
426 return os
.path
.exists('/sys/class/net/%s/bonding' %bondname
)