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