]> git.proxmox.com Git - mirror_ifupdown2.git/blame - addons/vrf.py
addons: vrf: fix typo in vrf default attribute name get at init
[mirror_ifupdown2.git] / addons / vrf.py
CommitLineData
8465de90
RP
1#!/usr/bin/python
2#
3# Copyright 2014 Cumulus Networks, Inc. All rights reserved.
4# Author: Roopa Prabhu, roopa@cumulusnetworks.com
5#
6
7import os
8import atexit
9from ifupdown.iface import *
54616d3f 10import ifupdown.policymanager as policymanager
8465de90 11import ifupdownaddons
768b4ec5 12import ifupdown.rtnetlink_api as rtnetlink_api
8465de90
RP
13from ifupdownaddons.modulebase import moduleBase
14from ifupdownaddons.bondutil import bondutil
15from ifupdownaddons.iproute2 import iproute2
16
17class vrf(moduleBase):
18 """ ifupdown2 addon module to configure vrfs """
19 _modinfo = { 'mhelp' : 'vrf configuration module',
20 'attrs' : {
21 'vrf-table':
22 {'help' : 'vrf device table id. key to ' +
23 'creating a vrf device',
24 'example': ['vrf-table-id 1']},
54616d3f
N
25 'vrf-default-route':
26 {'help' : 'vrf device default route ' +
27 'to avoid communication outside the vrf device',
28 'example': ['vrf-default-route yes/no']},
8465de90
RP
29 'vrf':
30 {'help' : 'vrf the interface is part of.',
31 'example': ['vrf blue']}}}
32
a1c23686 33 iproute2_vrf_filename = '/etc/iproute2/rt_tables.d/ifupdown2_vrf_map.conf'
8465de90
RP
34 iproute2_vrf_filehdr = '# This file is autogenerated by ifupdown2.\n' + \
35 '# It contains the vrf name to table mapping.\n' + \
6f2890fc
RP
36 '# Reserved table range %s %s\n'
37 VRF_TABLE_START = 1001
38 VRF_TABLE_END = 5000
8465de90
RP
39
40 def __init__(self, *args, **kargs):
41 ifupdownaddons.modulebase.moduleBase.__init__(self, *args, **kargs)
42 self.ipcmd = None
43 self.bondcmd = None
44 try:
45 ip_rules = self.exec_command('/sbin/ip rule show').splitlines()
46 self.ip_rule_cache = [' '.join(r.split()) for r in ip_rules]
47 except Exception, e:
48 self.ip_rule_cache = []
49 self.logger.warn('%s' %str(e))
50
51 try:
52 ip_rules = self.exec_command('/sbin/ip -6 rule show').splitlines()
53 self.ip6_rule_cache = [' '.join(r.split()) for r in ip_rules]
54 except Exception, e:
55 self.ip6_rule_cache = []
56 self.logger.warn('%s' %str(e))
57
58 #self.logger.debug("vrf: ip rule cache")
59 #self.logger.info(self.ip_rule_cache)
60
61 #self.logger.info("vrf: ip -6 rule cache")
62 #self.logger.info(self.ip6_rule_cache)
63
64 # XXX: check for vrf reserved overlap in /etc/iproute2/rt_tables
65 self.iproute2_vrf_map = {}
66 # read or create /etc/iproute2/rt_tables.d/ifupdown2.vrf_map
67 if os.path.exists(self.iproute2_vrf_filename):
68 self.vrf_map_fd = open(self.iproute2_vrf_filename, 'a+')
69 lines = self.vrf_map_fd.readlines()
70 for l in lines:
71 l = l.strip()
72 if l[0] == '#':
73 continue
74 try:
75 (table, vrf_name) = l.strip().split()
76 self.iproute2_vrf_map[table] = vrf_name
77 except Exception, e:
78 self.logger.info('vrf: iproute2_vrf_map: unable to parse %s'
79 %l)
80 pass
81 #self.logger.info("vrf: dumping iproute2_vrf_map")
82 #self.logger.info(self.iproute2_vrf_map)
83
84 # purge vrf table entries that are not around
85 iproute2_vrf_map_pruned = {}
86 for t, v in self.iproute2_vrf_map.iteritems():
87 if os.path.exists('/sys/class/net/%s' %v):
88 iproute2_vrf_map_pruned[t] = v
89 else:
90 try:
91 # cleanup rules
92 self._del_vrf_rules(v, t)
93 except Exception:
94 pass
95 self.iproute2_vrf_map = iproute2_vrf_map_pruned
96
6f2890fc
RP
97 self.vrf_table_id_start = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vrf-table-id-start')
98 if not self.vrf_table_id_start:
99 self.vrf_table_id_start = self.VRF_TABLE_START
100 self.vrf_table_id_end = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vrf-table-id-end')
101 if not self.vrf_table_id_end:
102 self.vrf_table_id_end = self.VRF_TABLE_END
103 self.vrf_max_count = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vf-max-count')
104
105 last_used_vrf_table = None
106 for t in range(self.vrf_table_id_start,
107 self.vrf_table_id_end):
8465de90
RP
108 if not self.iproute2_vrf_map.get(t):
109 break
6f2890fc 110 last_used_vrf_table = t
8465de90
RP
111 self.last_used_vrf_table = last_used_vrf_table
112 self.iproute2_write_vrf_map = False
113 atexit.register(self.iproute2_vrf_map_write)
3fcb15fe 114 self.vrf_fix_local_table = True
6f2890fc 115 self.vrf_count = 0
83841a51 116 self.vrf_cgroup_create = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vrf-cgroup-create')
6f2890fc
RP
117 if not self.vrf_cgroup_create:
118 self.vrf_cgroup_create = False
119 elif self.vrf_cgroup_create == 'yes':
120 self.vrf_cgroup_create = True
121 else:
122 self.vrf_cgroup_create = False
8465de90
RP
123
124 def iproute2_vrf_map_write(self):
125 if not self.iproute2_write_vrf_map:
126 return
127 self.logger.info('vrf: writing table map to %s'
128 %self.iproute2_vrf_filename)
129 with open(self.iproute2_vrf_filename, 'w') as f:
6f2890fc
RP
130 f.write(self.iproute2_vrf_filehdr %(self.vrf_table_id_start,
131 self.vrf_table_id_end))
8465de90
RP
132 for t, v in self.iproute2_vrf_map.iteritems():
133 f.write('%s %s\n' %(t, v))
134
135 def _is_vrf(self, ifaceobj):
136 if ifaceobj.get_attr_value_first('vrf-table'):
137 return True
138 return False
139
768b4ec5 140 def get_upper_ifacenames(self, ifaceobj, ifacenames_all=None):
8465de90
RP
141 """ Returns list of interfaces dependent on ifaceobj """
142
768b4ec5
RP
143 vrf_table = ifaceobj.get_attr_value_first('vrf-table')
144 if vrf_table:
145 ifaceobj.link_type = ifaceLinkType.LINK_MASTER
146 ifaceobj.link_kind |= ifaceLinkKind.VRF
8465de90
RP
147 vrf_iface_name = ifaceobj.get_attr_value_first('vrf')
148 if not vrf_iface_name:
149 return None
768b4ec5 150 ifaceobj.link_type = ifaceLinkType.LINK_SLAVE
8465de90
RP
151 return [vrf_iface_name]
152
768b4ec5 153 def get_upper_ifacenames_running(self, ifaceobj):
8465de90
RP
154 return None
155
156 def _get_iproute2_vrf_table(self, vrf_dev_name):
157 for t, v in self.iproute2_vrf_map.iteritems():
158 if v == vrf_dev_name:
159 return t
160 return None
161
162 def _get_avail_vrf_table_id(self):
6f2890fc
RP
163 if self.last_used_vrf_table == None:
164 table_id_start = self.vrf_table_id_start
165 else:
166 table_id_start = self.last_used_vrf_table + 1
167 for t in range(table_id_start,
168 self.vrf_table_id_end):
8465de90
RP
169 if not self.iproute2_vrf_map.get(t):
170 self.last_used_vrf_table = t
6f2890fc 171 return str(t)
8465de90
RP
172 return None
173
174 def _iproute2_vrf_table_entry_add(self, vrf_dev_name, table_id):
175 self.iproute2_vrf_map[table_id] = vrf_dev_name
176 self.iproute2_write_vrf_map = True
177
178 def _iproute2_vrf_table_entry_del(self, table_id):
179 try:
180 del self.iproute2_vrf_map[table_id]
181 self.iproute2_write_vrf_map = True
182 except Exception, e:
183 self.logger.info('vrf: iproute2 vrf map del failed for %d (%s)'
184 %(table_id, str(e)))
185 pass
186
768b4ec5 187 def _up_vrf_slave(self, ifacename, vrfname):
8465de90 188 try:
768b4ec5
RP
189 if self.ipcmd.link_exists(vrfname):
190 self.ipcmd.link_set(ifacename, 'master', vrfname)
8465de90 191 except Exception, e:
768b4ec5 192 self.logger.warn('%s: %s' %(ifacename, str(e)))
8465de90
RP
193
194 def _del_vrf_rules(self, vrf_dev_name, vrf_table):
195 pref = 200
196 ip_rule_out_format = '%s: from all %s %s lookup %s'
197 ip_rule_cmd = 'ip %s rule del pref %s %s %s table %s'
198
4ce47ce4 199 rule = ip_rule_out_format %(pref, 'oif', vrf_dev_name, vrf_dev_name)
8465de90
RP
200 if rule in self.ip_rule_cache:
201 rule_cmd = ip_rule_cmd %('', pref, 'oif', vrf_dev_name, vrf_table)
202 self.exec_command(rule_cmd)
203
4ce47ce4 204 rule = ip_rule_out_format %(pref, 'iif', vrf_dev_name, vrf_dev_name)
8465de90
RP
205 if rule in self.ip_rule_cache:
206 rule_cmd = ip_rule_cmd %('', pref, 'iif', vrf_dev_name, vrf_table)
207 self.exec_command(rule_cmd)
208
4ce47ce4 209 rule = ip_rule_out_format %(pref, 'oif', vrf_dev_name, vrf_dev_name)
8465de90
RP
210 if rule in self.ip_rule_cache:
211 rule_cmd = ip_rule_cmd %('-6', pref, 'oif', vrf_dev_name,
212 vrf_table)
213 self.exec_command(rule_cmd)
214
4ce47ce4 215 rule = ip_rule_out_format %(pref, 'iif', vrf_dev_name, vrf_dev_name)
8465de90
RP
216 if rule in self.ip_rule_cache:
217 rule_cmd = ip_rule_cmd %('-6', pref, 'iif', vrf_dev_name,
218 vrf_table)
219 self.exec_command(rule_cmd)
220
221 def _add_vrf_rules(self, vrf_dev_name, vrf_table):
222 pref = 200
223 ip_rule_out_format = '%s: from all %s %s lookup %s'
224 ip_rule_cmd = 'ip %s rule add pref %s %s %s table %s'
659097a0
N
225 if self.vrf_fix_local_table:
226 self.vrf_fix_local_table = False
227 rule = '0: from all lookup local'
228 if rule in self.ip_rule_cache:
229 try:
3fcb15fe
N
230 self.exec_command('ip rule del pref 0')
231 self.exec_command('ip rule add pref 32765 table local')
659097a0
N
232 except Exception, e:
233 self.logger.info('%s' %str(e))
234 pass
8465de90 235
3fcb15fe
N
236 #Example ip rule
237 #200: from all oif blue lookup blue
238 #200: from all iif blue lookup blue
239
240 rule = ip_rule_out_format %(pref, 'oif', vrf_dev_name, vrf_dev_name)
8465de90
RP
241 if rule not in self.ip_rule_cache:
242 rule_cmd = ip_rule_cmd %('', pref, 'oif', vrf_dev_name, vrf_table)
243 self.exec_command(rule_cmd)
244
3fcb15fe 245 rule = ip_rule_out_format %(pref, 'iif', vrf_dev_name, vrf_dev_name)
8465de90
RP
246 if rule not in self.ip_rule_cache:
247 rule_cmd = ip_rule_cmd %('', pref, 'iif', vrf_dev_name, vrf_table)
248 self.exec_command(rule_cmd)
249
3fcb15fe 250 rule = ip_rule_out_format %(pref, 'oif', vrf_dev_name, vrf_dev_name)
8465de90 251 if rule not in self.ip_rule_cache:
3fcb15fe 252 rule_cmd = ip_rule_cmd %('-6', pref, 'oif', vrf_dev_name, vrf_table)
8465de90
RP
253 self.exec_command(rule_cmd)
254
3fcb15fe 255 rule = ip_rule_out_format %(pref, 'iif', vrf_dev_name, vrf_dev_name)
8465de90
RP
256 if rule not in self.ip_rule_cache:
257 rule_cmd = ip_rule_cmd %('-6', pref, 'iif', vrf_dev_name,
258 vrf_table)
259 self.exec_command(rule_cmd)
260
768b4ec5
RP
261 def _add_vrf_slaves(self, ifaceobj):
262 running_slaves = self.ipcmd.link_get_lowers(ifaceobj.name)
263 config_slaves = ifaceobj.lowerifaces
b94e4d24 264 if not config_slaves and not running_slaves:
867e11a2 265 return
768b4ec5
RP
266 add_slaves = set(config_slaves).difference(set(running_slaves))
267 del_slaves = set(running_slaves).difference(set(config_slaves))
268 if add_slaves:
269 for s in add_slaves:
270 try:
271 self._up_vrf_slave(s, ifaceobj.name)
272 except Exception, e:
273 self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
274
275 if del_slaves:
276 for s in del_slaves:
277 try:
278 self._down_vrf_slave(s, ifaceobj.name)
279 except Exception, e:
280 self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
281
282 if ifaceobj.link_type == ifaceLinkType.LINK_MASTER:
283 for s in config_slaves:
284 try:
285 rtnetlink_api.rtnl_api.link_set(s, "up")
286 except Exception, e:
287 self.logger.debug('%s: %s: link set up (%s)'
288 %(ifaceobj.name, s, str(e)))
289 pass
8465de90 290
2df6a60f 291 def _create_cgroup(self, ifaceobj):
6f2890fc
RP
292 if not self.vrf_cgroup_create:
293 return
2df6a60f 294 try:
d1e1c43b
RP
295 if not os.path.exists('/sys/fs/cgroup/l3mdev/%s' %ifaceobj.name):
296 self.exec_command('cgcreate -g l3mdev:%s' %ifaceobj.name)
2df6a60f
RP
297 self.exec_command('cgset -r l3mdev.master-device=%s %s'
298 %(ifaceobj.name, ifaceobj.name))
299 except Exception, e:
300 self.log_warn('%s: cgroup create failed (%s)\n'
301 %(ifaceobj.name, str(e)), ifaceobj)
302
8465de90 303 def _up_vrf_dev(self, ifaceobj, vrf_table):
8465de90 304
2df6a60f 305 if not self.ipcmd.link_exists(ifaceobj.name):
6f2890fc
RP
306 if vrf_table == 'auto':
307 vrf_table = self._get_avail_vrf_table_id()
308 if not vrf_table:
309 self.log_error('%s: unable to get an auto table id'
310 %ifaceobj.name)
311 self.logger.info('%s: table id auto: selected table id %s\n'
312 %(ifaceobj.name, vrf_table))
313 # XXX: If we decide to not allow vrf id usages out of
314 # the reserved ifupdown range, then uncomment this code.
315 #else:
316 # if (int(vrf_table) < self.vrf_table_id_start or
317 # int(vrf_table) > self.vrf_table_id_end):
318 # self.log_error('%s: vrf table id %s out of reserved range [%d,%d]'
319 # %(ifaceobj.name, vrf_table,
320 # self.vrf_table_id_start,
321 # self.vrf_table_id_end))
2df6a60f 322 try:
8465de90
RP
323 self.ipcmd.link_create(ifaceobj.name, 'vrf',
324 {'table' : '%s' %vrf_table})
2df6a60f
RP
325 except Exception, e:
326 self.log_error('%s: create failed (%s)\n'
327 %(ifaceobj.name, str(e)))
328 else:
6f2890fc
RP
329 vrf_table = self._get_iproute2_vrf_table(ifaceobj.name)
330 if not vrf_table:
331 self.log_error('%s: unable to get vrf table id'
332 %ifaceobj.name)
333
2df6a60f
RP
334 # if the device exists, check if table id is same
335 vrfdev_attrs = self.ipcmd.link_get_linkinfo_attrs(ifaceobj.name)
336 if vrfdev_attrs:
337 running_table = vrfdev_attrs.get('table', None)
338 if vrf_table != running_table:
6f2890fc
RP
339 self.log_error('%s: cannot change vrf table id,running table id %s is different from config id %s' %(ifaceobj.name,
340 running_table, vrf_table))
2df6a60f
RP
341
342 try:
8465de90
RP
343 self._iproute2_vrf_table_entry_add(ifaceobj.name, vrf_table)
344 self._add_vrf_rules(ifaceobj.name, vrf_table)
768b4ec5 345 self._add_vrf_slaves(ifaceobj)
2df6a60f 346 self._create_cgroup(ifaceobj)
8465de90 347 except Exception, e:
2df6a60f 348 self.log_error('%s: %s' %(ifaceobj.name, str(e)))
54616d3f
N
349
350 def _up_vrf_default_route(self, ifaceobj, vrf_table):
351 vrf_default_route = ifaceobj.get_attr_value_first('vrf-default-route')
352 if not vrf_default_route:
353 vrf_default_route = policymanager.policymanager_api.get_attr_default(
354 module_name=self.__class__.__name__, attr='vrf-default-route')
355 if not vrf_default_route:
356 return
357 if str(vrf_default_route).lower() == "yes":
358 try:
359 self.exec_command('ip route add table %s unreachable default' %vrf_table)
360 except OSError, e:
361 if e.errno != 17:
362 raise
363 pass
364
0ba9abeb
N
365 try:
366 self.exec_command('ip -6 route add table %s unreachable default' %vrf_table)
367 except OSError, e:
368 if e.errno != 17:
369 raise
370 pass
371
8465de90
RP
372 def _up(self, ifaceobj):
373 try:
374 vrf_table = ifaceobj.get_attr_value_first('vrf-table')
375 if vrf_table:
6f2890fc
RP
376 if self.vrf_count == self.vrf_max_count:
377 self.log_error('%s: max vrf count %d hit...not '
378 'creating vrf' %(ifaceobj.name,
379 self.vrf_count))
8465de90 380 self._up_vrf_dev(ifaceobj, vrf_table)
54616d3f 381 self._up_vrf_default_route(ifaceobj, vrf_table)
8465de90
RP
382 else:
383 vrf = ifaceobj.get_attr_value_first('vrf')
384 if vrf:
768b4ec5 385 self._up_vrf_slave(ifaceobj.name, vrf)
8465de90
RP
386 except Exception, e:
387 self.log_error(str(e))
388
2df6a60f
RP
389 def _delete_cgroup(self, ifaceobj):
390 try:
d1e1c43b
RP
391 if os.path.exists('/sys/fs/cgroup/l3mdev/%s' %ifaceobj.name):
392 self.exec_command('cgdelete -g l3mdev:%s' %ifaceobj.name)
2df6a60f 393 except Exception, e:
d1e1c43b 394 self.log_warn('%s: cgroup delete failed (%s)\n'
2df6a60f
RP
395 %(ifaceobj.name, str(e)), ifaceobj)
396
8465de90
RP
397 def _down_vrf_dev(self, ifaceobj, vrf_table):
398 if vrf_table == 'auto':
399 vrf_table = self._get_iproute2_vrf_table(ifaceobj.name)
400 try:
401 self.ipcmd.link_delete(ifaceobj.name)
768b4ec5
RP
402 except Exception, e:
403 self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
404 pass
405
406 try:
8465de90 407 self._iproute2_vrf_table_entry_del(vrf_table)
2df6a60f 408 self._delete_cgroup(ifaceobj)
768b4ec5
RP
409 except Exception, e:
410 self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
411 pass
412
413 try:
8465de90
RP
414 self._del_vrf_rules(ifaceobj.name, vrf_table)
415 except Exception, e:
768b4ec5
RP
416 self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
417 pass
8465de90 418
768b4ec5 419 def _down_vrf_slave(self, ifacename, vrf):
8465de90 420 try:
768b4ec5 421 self.ipcmd.link_set(ifacename, 'nomaster')
8465de90 422 except Exception, e:
768b4ec5 423 self.logger.warn('%s: %s' %(ifacename, str(e)))
8465de90
RP
424
425 def _down(self, ifaceobj):
426 try:
427 vrf_table = ifaceobj.get_attr_value_first('vrf-table')
428 if vrf_table:
429 self._down_vrf_dev(ifaceobj, vrf_table)
430 else:
431 vrf = ifaceobj.get_attr_value_first('vrf')
432 if vrf:
768b4ec5 433 self._down_vrf_slave(ifaceobj.name, vrf)
8465de90
RP
434 except Exception, e:
435 self.log_warn(str(e))
436
437 def _query_check_vrf_slave(self, ifaceobj, ifaceobjcurr, vrf):
438 try:
54616d3f 439 master = self.ipcmd.link_get_master(ifaceobj.name)
8465de90
RP
440 if not master or master != vrf:
441 ifaceobjcurr.update_config_with_status('vrf', master, 1)
442 else:
443 ifaceobjcurr.update_config_with_status('vrf', master, 0)
444 except Exception, e:
445 self.log_warn(str(e))
446
447 def _query_check_vrf_dev(self, ifaceobj, ifaceobjcurr, vrf_table):
448 try:
449 if not self.ipcmd.link_exists(ifaceobj.name):
450 self.logger.info('%s: vrf: does not exist' %(ifaceobj.name))
451 return
452 if vrf_table == 'auto':
453 config_table = self._get_iproute2_vrf_table(ifaceobj.name)
454 else:
455 config_table = vrf_table
456 vrfdev_attrs = self.ipcmd.link_get_linkinfo_attrs(ifaceobj.name)
457 if not vrfdev_attrs:
458 ifaceobjcurr.update_config_with_status('vrf-table', 'None', 1)
459 return
460 running_table = vrfdev_attrs.get('table')
461 if not running_table:
462 ifaceobjcurr.update_config_with_status('vrf-table', 'None', 1)
463 return
464 if config_table != running_table:
465 ifaceobjcurr.update_config_with_status('vrf-table',
466 running_table, 1)
467 else:
468 ifaceobjcurr.update_config_with_status('vrf-table',
469 running_table, 0)
470 except Exception, e:
471 self.log_warn(str(e))
472
473 def _query_check(self, ifaceobj, ifaceobjcurr):
474 try:
475 vrf_table = ifaceobj.get_attr_value_first('vrf-table')
476 if vrf_table:
477 self._query_check_vrf_dev(ifaceobj, ifaceobjcurr, vrf_table)
478 else:
479 vrf = ifaceobj.get_attr_value_first('vrf')
480 if vrf:
481 self._query_check_vrf_slave(ifaceobj, ifaceobjcurr, vrf)
482 except Exception, e:
483 self.log_warn(str(e))
484
485 def _query_running(self, ifaceobjrunning):
486 try:
487 kind = self.ipcmd.link_get_kind(ifaceobjrunning.name)
488 if kind == 'vrf':
54616d3f 489 vrfdev_attrs = self.ipcmd.link_get_linkinfo_attrs(ifaceobjrunning.name)
8465de90
RP
490 if vrfdev_attrs:
491 running_table = vrfdev_attrs.get('table')
492 if running_table:
493 ifaceobjrunning.update_config('vrf-table',
494 running_table)
495 elif kind == 'vrf_slave':
54616d3f 496 vrf = self.ipcmd.link_get_master(ifaceobjrunning.name)
8465de90
RP
497 if vrf:
498 ifaceobjrunning.update_config('vrf', vrf)
499 except Exception, e:
500 self.log_warn(str(e))
501
502 _run_ops = {'pre-up' : _up,
503 'post-down' : _down,
504 'query-running' : _query_running,
505 'query-checkcurr' : _query_check}
506
507 def get_ops(self):
508 """ returns list of ops supported by this module """
509 return self._run_ops.keys()
510
511 def _init_command_handlers(self):
512 flags = self.get_flags()
513 if not self.ipcmd:
514 self.ipcmd = iproute2(**flags)
515 if not self.bondcmd:
516 self.bondcmd = bondutil(**flags)
517
518 def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
519 """ run bond configuration on the interface object passed as argument
520
521 Args:
522 **ifaceobj** (object): iface object
523
524 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
525 'query-running'
526
527 Kwargs:
528 **query_ifaceobj** (object): query check ifaceobject. This is only
529 valid when op is 'query-checkcurr'. It is an object same as
530 ifaceobj, but contains running attribute values and its config
531 status. The modules can use it to return queried running state
532 of interfaces. status is success if the running state is same
533 as user required state in ifaceobj. error otherwise.
534 """
535 op_handler = self._run_ops.get(operation)
536 if not op_handler:
537 return
538 self._init_command_handlers()
539 if operation == 'query-checkcurr':
540 op_handler(self, ifaceobj, query_ifaceobj)
541 else:
542 op_handler(self, ifaceobj)