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