]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - addons/vrf.py
3 # Copyright 2014 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
9 from ifupdown
.iface
import *
10 import ifupdown
.policymanager
as policymanager
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
21 class vrf(moduleBase
):
22 """ ifupdown2 addon module to configure vrfs """
23 _modinfo
= { 'mhelp' : 'vrf configuration module',
26 {'help' : 'vrf device table id. key to ' +
27 'creating a vrf device',
28 'example': ['vrf-table-id 1']},
30 {'help' : 'vrf device default route ' +
31 'to avoid communication outside the vrf device',
32 'example': ['vrf-default-route yes/no']},
34 {'help' : 'vrf the interface is part of.',
35 'example': ['vrf blue']}}}
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
44 def __init__(self
, *args
, **kargs
):
45 ifupdownaddons
.modulebase
.moduleBase
.__init
__(self
, *args
, **kargs
)
48 self
.dhclientcmd
= None
49 self
.name
= self
.__class
__.__name
__
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
):
55 self
.logger
.info('vrf: removing file %s'
56 %self
.iproute2_vrf_filename
)
57 os
.remove(self
.iproute2_vrf_filename
)
59 self
.logger
.debug('vrf: removing file failed (%s)'
62 ip_rules
= self
.exec_command('/sbin/ip rule show').splitlines()
63 self
.ip_rule_cache
= [' '.join(r
.split()) for r
in ip_rules
]
65 self
.ip_rule_cache
= []
66 self
.logger
.warn('%s' %str
(e
))
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
]
72 self
.ip6_rule_cache
= []
73 self
.logger
.warn('%s' %str
(e
))
75 #self.logger.debug("vrf: ip rule cache")
76 #self.logger.info(self.ip_rule_cache)
78 #self.logger.info("vrf: ip -6 rule cache")
79 #self.logger.info(self.ip6_rule_cache)
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()
92 (table
, vrf_name
) = l
.strip().split()
93 self
.iproute2_vrf_map
[table
] = vrf_name
95 self
.logger
.info('vrf: iproute2_vrf_map: unable to parse %s'
98 #self.logger.info("vrf: dumping iproute2_vrf_map")
99 #self.logger.info(self.iproute2_vrf_map)
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
[int(t
)] = v
109 self
._del
_vrf
_rules
(v
, t
)
112 self
.iproute2_vrf_map
= iproute2_vrf_map_pruned
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')
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
):
127 last_used_vrf_table
= t
128 self
.last_used_vrf_table
= last_used_vrf_table
130 self
.iproute2_write_vrf_map
= False
131 atexit
.register(self
.iproute2_vrf_map_write
)
132 self
.vrf_fix_local_table
= True
134 self
.vrf_cgroup_create
= policymanager
.policymanager_api
.get_module_globals(module_name
=self
.__class
__.__name
__, attr
='vrf-cgroup-create')
135 if not self
.vrf_cgroup_create
:
136 self
.vrf_cgroup_create
= False
137 elif self
.vrf_cgroup_create
== 'yes':
138 self
.vrf_cgroup_create
= True
140 self
.vrf_cgroup_create
= False
142 def iproute2_vrf_map_write(self
):
143 if not self
.iproute2_write_vrf_map
:
145 self
.logger
.info('vrf: writing table map to %s'
146 %self
.iproute2_vrf_filename
)
147 with
open(self
.iproute2_vrf_filename
, 'w') as f
:
148 f
.write(self
.iproute2_vrf_filehdr
%(self
.vrf_table_id_start
,
149 self
.vrf_table_id_end
))
150 for t
, v
in self
.iproute2_vrf_map
.iteritems():
151 f
.write('%s %s\n' %(t
, v
))
153 def _is_vrf(self
, ifaceobj
):
154 if ifaceobj
.get_attr_value_first('vrf-table'):
158 def get_upper_ifacenames(self
, ifaceobj
, ifacenames_all
=None):
159 """ Returns list of interfaces dependent on ifaceobj """
161 vrf_table
= ifaceobj
.get_attr_value_first('vrf-table')
163 ifaceobj
.link_type
= ifaceLinkType
.LINK_MASTER
164 ifaceobj
.link_kind |
= ifaceLinkKind
.VRF
165 vrf_iface_name
= ifaceobj
.get_attr_value_first('vrf')
166 if not vrf_iface_name
:
168 ifaceobj
.link_type
= ifaceLinkType
.LINK_SLAVE
169 ifaceobj
.link_kind |
= ifaceLinkKind
.VRF_SLAVE
171 return [vrf_iface_name
]
173 def get_upper_ifacenames_running(self
, ifaceobj
):
176 def _get_iproute2_vrf_table(self
, vrf_dev_name
):
177 for t
, v
in self
.iproute2_vrf_map
.iteritems():
178 if v
== vrf_dev_name
:
182 def _get_avail_vrf_table_id(self
):
183 if self
.last_used_vrf_table
== None:
184 table_id_start
= self
.vrf_table_id_start
186 table_id_start
= self
.last_used_vrf_table
+ 1
187 for t
in range(table_id_start
,
188 self
.vrf_table_id_end
):
189 if not self
.iproute2_vrf_map
.get(t
):
190 self
.last_used_vrf_table
= t
194 def _iproute2_vrf_table_entry_add(self
, vrf_dev_name
, table_id
):
195 self
.iproute2_vrf_map
[int(table_id
)] = vrf_dev_name
196 self
.iproute2_write_vrf_map
= True
198 def _iproute2_vrf_table_entry_del(self
, table_id
):
200 del self
.iproute2_vrf_map
[int(table_id
)]
201 self
.iproute2_write_vrf_map
= True
203 self
.logger
.info('vrf: iproute2 vrf map del failed for %d (%s)'
207 def _is_dhcp_slave(self
, ifaceobj
):
208 if (not ifaceobj
.addr_method
or
209 (ifaceobj
.addr_method
!= 'dhcp' and
210 ifaceobj
.addr_method
!= 'dhcp6')):
214 def _handle_dhcp_slaves(self
, ifacename
, vrfname
, ifaceobj
,
216 """ If we have a vrf slave that has dhcp configured, bring up the
217 vrf master now. This is needed because vrf has special handling
218 in dhclient hook which requires the vrf master to be present """
219 if not self
._is
_dhcp
_slave
(ifaceobj
):
221 vrf_master
= ifaceobj
.upperifaces
[0]
223 self
.logger
.warn('%s: vrf master not found' %ifacename
)
225 if os
.path
.exists('/sys/class/net/%s' %vrf_master
):
226 self
.logger
.info('%s: vrf master %s exists returning'
227 %(ifacename
, vrf_master
))
229 vrf_master_objs
= ifaceobj_getfunc(vrf_master
)
230 if not vrf_master_objs
:
231 self
.logger
.warn('%s: vrf master ifaceobj not found' %ifacename
)
233 self
.logger
.info('%s: bringing up vrf master %s'
234 %(ifacename
, vrf_master
))
235 for mobj
in vrf_master_objs
:
236 vrf_table
= mobj
.get_attr_value_first('vrf-table')
238 if vrf_table
== 'auto':
239 vrf_table
= self
._get
_avail
_vrf
_table
_id
()
241 self
.log_error('%s: unable to get an auto table id'
243 self
.logger
.info('%s: table id auto: selected table id %s\n'
244 %(mobj
.name
, vrf_table
))
245 self
._up
_vrf
_dev
(mobj
, vrf_table
, False)
247 self
._down
_dhcp
_slave
(ifaceobj
)
248 self
.ipcmd
.link_set(ifacename
, 'master', vrfname
)
251 def _down_dhcp_slave(self
, ifaceobj
):
253 self
.dhclientcmd
.release(ifaceobj
.name
)
255 # ignore any dhclient release errors
258 def _up_vrf_slave(self
, ifacename
, vrfname
, ifaceobj
=None,
259 ifaceobj_getfunc
=None, vrf_exists
=False):
261 if vrf_exists
or self
.ipcmd
.link_exists(vrfname
):
262 upper
= self
.ipcmd
.link_get_upper(ifacename
)
263 if not upper
or upper
!= vrfname
:
264 if ifaceobj
and self
._is
_dhcp
_slave
(ifaceobj
):
265 self
._down
_dhcp
_slave
(ifaceobj
)
266 self
.ipcmd
.link_set(ifacename
, 'master', vrfname
)
268 self
._handle
_dhcp
_slaves
(ifacename
, vrfname
, ifaceobj
,
271 self
.log_error('%s: %s' %(ifacename
, str(e
)))
273 def _del_vrf_rules(self
, vrf_dev_name
, vrf_table
):
275 ip_rule_out_format
= '%s: from all %s %s lookup %s'
276 ip_rule_cmd
= 'ip %s rule del pref %s %s %s table %s'
278 rule
= ip_rule_out_format
%(pref
, 'oif', vrf_dev_name
, vrf_dev_name
)
279 if rule
in self
.ip_rule_cache
:
280 rule_cmd
= ip_rule_cmd
%('', pref
, 'oif', vrf_dev_name
, vrf_table
)
281 self
.exec_command(rule_cmd
)
283 rule
= ip_rule_out_format
%(pref
, 'iif', vrf_dev_name
, vrf_dev_name
)
284 if rule
in self
.ip_rule_cache
:
285 rule_cmd
= ip_rule_cmd
%('', pref
, 'iif', vrf_dev_name
, vrf_table
)
286 self
.exec_command(rule_cmd
)
288 rule
= ip_rule_out_format
%(pref
, 'oif', vrf_dev_name
, vrf_dev_name
)
289 if rule
in self
.ip6_rule_cache
:
290 rule_cmd
= ip_rule_cmd
%('-6', pref
, 'oif', vrf_dev_name
,
292 self
.exec_command(rule_cmd
)
294 rule
= ip_rule_out_format
%(pref
, 'iif', vrf_dev_name
, vrf_dev_name
)
295 if rule
in self
.ip6_rule_cache
:
296 rule_cmd
= ip_rule_cmd
%('-6', pref
, 'iif', vrf_dev_name
,
298 self
.exec_command(rule_cmd
)
300 def _add_vrf_rules(self
, vrf_dev_name
, vrf_table
):
302 ip_rule_out_format
= '%s: from all %s %s lookup %s'
303 ip_rule_cmd
= 'ip %s rule add pref %s %s %s table %s'
304 if self
.vrf_fix_local_table
:
305 self
.vrf_fix_local_table
= False
306 rule
= '0: from all lookup local'
307 if rule
in self
.ip_rule_cache
:
309 self
.exec_command('ip rule del pref 0')
310 self
.exec_command('ip rule add pref 32765 table local')
312 self
.logger
.info('%s' %str
(e
))
314 if rule
in self
.ip6_rule_cache
:
316 self
.exec_command('ip -6 rule del pref 0')
317 self
.exec_command('ip -6 rule add pref 32765 table local')
319 self
.logger
.info('%s' %str
(e
))
323 #200: from all oif blue lookup blue
324 #200: from all iif blue lookup blue
326 rule
= ip_rule_out_format
%(pref
, 'oif', vrf_dev_name
, vrf_dev_name
)
327 if rule
not in self
.ip_rule_cache
:
328 rule_cmd
= ip_rule_cmd
%('', pref
, 'oif', vrf_dev_name
, vrf_table
)
329 self
.exec_command(rule_cmd
)
331 rule
= ip_rule_out_format
%(pref
, 'iif', vrf_dev_name
, vrf_dev_name
)
332 if rule
not in self
.ip_rule_cache
:
333 rule_cmd
= ip_rule_cmd
%('', pref
, 'iif', vrf_dev_name
, vrf_table
)
334 self
.exec_command(rule_cmd
)
336 rule
= ip_rule_out_format
%(pref
, 'oif', vrf_dev_name
, vrf_dev_name
)
337 if rule
not in self
.ip6_rule_cache
:
338 rule_cmd
= ip_rule_cmd
%('-6', pref
, 'oif', vrf_dev_name
, vrf_table
)
339 self
.exec_command(rule_cmd
)
341 rule
= ip_rule_out_format
%(pref
, 'iif', vrf_dev_name
, vrf_dev_name
)
342 if rule
not in self
.ip6_rule_cache
:
343 rule_cmd
= ip_rule_cmd
%('-6', pref
, 'iif', vrf_dev_name
,
345 self
.exec_command(rule_cmd
)
347 def _add_vrf_slaves(self
, ifaceobj
, ifaceobj_getfunc
=None):
348 running_slaves
= self
.ipcmd
.link_get_lowers(ifaceobj
.name
)
349 config_slaves
= ifaceobj
.lowerifaces
350 if not config_slaves
and not running_slaves
:
353 if not config_slaves
: config_slaves
= []
354 if not running_slaves
: running_slaves
= []
355 add_slaves
= set(config_slaves
).difference(set(running_slaves
))
356 del_slaves
= set(running_slaves
).difference(set(config_slaves
))
362 sobj
= ifaceobj_getfunc(s
)
363 self
._up
_vrf
_slave
(s
, ifaceobj
.name
,
364 sobj
[0] if sobj
else None,
365 ifaceobj_getfunc
, True)
367 self
.logger
.info('%s: %s' %(ifaceobj
.name
, str(e
)))
373 sobj
= ifaceobj_getfunc(s
)
374 # if dhcp slave, release the dhcp lease
375 if sobj
and self
._is
_dhcp
_slave
(sobj
[0]):
376 self
._down
_dhcp
_slave
(sobj
[0])
377 self
._down
_vrf
_slave
(s
, ifaceobj
.name
)
379 self
.logger
.info('%s: %s' %(ifaceobj
.name
, str(e
)))
381 if ifaceobj
.link_type
== ifaceLinkType
.LINK_MASTER
:
382 for s
in config_slaves
:
384 rtnetlink_api
.rtnl_api
.link_set(s
, "up")
386 self
.logger
.debug('%s: %s: link set up (%s)'
387 %(ifaceobj
.name
, s
, str(e
)))
390 def _create_cgroup(self
, ifaceobj
):
391 if not self
.vrf_cgroup_create
:
394 if not os
.path
.exists('/sys/fs/cgroup/l3mdev/%s' %ifaceobj
.name
):
395 self
.exec_command('/usr/bin/cgcreate -g l3mdev:%s' %ifaceobj
.name
)
397 self
.log_error('%s: cgroup create failed (%s)\n'
398 %(ifaceobj
.name
, str(e
)), ifaceobj
)
400 self
.exec_command('/usr/bin/cgset -r l3mdev.master-device=%s %s'
401 %(ifaceobj
.name
, ifaceobj
.name
))
403 self
.log_warn('%s: cgset failed (%s)\n'
404 %(ifaceobj
.name
, str(e
)), ifaceobj
)
406 def _set_vrf_dev_processed_flag(self
, ifaceobj
):
407 ifaceobj
.module_flags
[self
.name
] = \
408 ifaceobj
.module_flags
.setdefault(self
.name
, 0) | \
409 vrfPrivFlags
.PROCESSED
411 def _check_vrf_dev_processed_flag(self
, ifaceobj
):
412 if (ifaceobj
.module_flags
.get(self
.name
, 0x0) & vrfPrivFlags
.PROCESSED
):
416 def _create_vrf_dev(self
, ifaceobj
, vrf_table
):
417 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
418 if vrf_table
== 'auto':
419 vrf_table
= self
._get
_avail
_vrf
_table
_id
()
421 self
.log_error('%s: unable to get an auto table id'
423 self
.logger
.info('%s: table id auto: selected table id %s\n'
424 %(ifaceobj
.name
, vrf_table
))
426 if not vrf_table
.isdigit():
427 self
.log_error('%s: vrf-table must be an integer or \'auto\''
428 %(ifaceobj
.name
), ifaceobj
)
430 # XXX: If we decide to not allow vrf id usages out of
431 # the reserved ifupdown range, then uncomment this code.
433 # if (int(vrf_table) < self.vrf_table_id_start or
434 # int(vrf_table) > self.vrf_table_id_end):
435 # self.log_error('%s: vrf table id %s out of reserved range [%d,%d]'
436 # %(ifaceobj.name, vrf_table,
437 # self.vrf_table_id_start,
438 # self.vrf_table_id_end))
440 self
.ipcmd
.link_create(ifaceobj
.name
, 'vrf',
441 {'table' : '%s' %vrf_table
})
443 self
.log_error('%s: create failed (%s)\n'
444 %(ifaceobj
.name
, str(e
)))
446 if vrf_table
== 'auto':
447 vrf_table
= self
._get
_iproute
2_vrf
_table
(ifaceobj
.name
)
449 self
.log_error('%s: unable to get vrf table id'
452 # if the device exists, check if table id is same
453 vrfdev_attrs
= self
.ipcmd
.link_get_linkinfo_attrs(ifaceobj
.name
)
455 running_table
= vrfdev_attrs
.get('table', None)
456 if vrf_table
!= running_table
:
457 self
.log_error('%s: cannot change vrf table id,running table id %s is different from config id %s' %(ifaceobj
.name
,
458 running_table
, vrf_table
))
459 if vrf_table
!= 'auto':
460 self
._iproute
2_vrf
_table
_entry
_add
(ifaceobj
.name
, vrf_table
)
464 def _add_vrf_default_route(self
, ifaceobj
, vrf_table
):
465 vrf_default_route
= ifaceobj
.get_attr_value_first('vrf-default-route')
466 if not vrf_default_route
:
467 vrf_default_route
= policymanager
.policymanager_api
.get_attr_default(
468 module_name
=self
.__class
__.__name
__,
469 attr
='vrf-default-route')
470 if not vrf_default_route
:
472 if str(vrf_default_route
).lower() == "yes":
474 self
.exec_command('ip route add table %s unreachable default'
475 ' metric %d' %(vrf_table
, 240))
482 self
.exec_command('ip -6 route add table %s unreachable '
483 'default metric %d' %(vrf_table
, 240))
489 def _up_vrf_dev(self
, ifaceobj
, vrf_table
, add_slaves
=True,
490 ifaceobj_getfunc
=None):
492 # if vrf dev is already processed return. This can happen
493 # if we had a dhcp slave. See self._handle_dhcp_slaves
494 if self
._check
_vrf
_dev
_processed
_flag
(ifaceobj
):
497 vrf_table
= self
._create
_vrf
_dev
(ifaceobj
, vrf_table
)
499 self
._add
_vrf
_rules
(ifaceobj
.name
, vrf_table
)
500 self
._create
_cgroup
(ifaceobj
)
502 self
._add
_vrf
_slaves
(ifaceobj
, ifaceobj_getfunc
)
503 self
._add
_vrf
_default
_route
(ifaceobj
, vrf_table
)
504 self
._set
_vrf
_dev
_processed
_flag
(ifaceobj
)
506 self
.log_error('%s: %s' %(ifaceobj
.name
, str(e
)))
508 def _up(self
, ifaceobj
, ifaceobj_getfunc
=None):
510 vrf_table
= ifaceobj
.get_attr_value_first('vrf-table')
512 # This is a vrf device
513 if self
.vrf_count
== self
.vrf_max_count
:
514 self
.log_error('%s: max vrf count %d hit...not '
515 'creating vrf' %(ifaceobj
.name
,
517 self
._up
_vrf
_dev
(ifaceobj
, vrf_table
, True, ifaceobj_getfunc
)
519 vrf
= ifaceobj
.get_attr_value_first('vrf')
521 # This is a vrf slave
522 self
._up
_vrf
_slave
(ifaceobj
.name
, vrf
, ifaceobj
,
525 self
.log_error(str(e
))
527 def _delete_cgroup(self
, ifaceobj
):
529 if os
.path
.exists('/sys/fs/cgroup/l3mdev/%s' %ifaceobj
.name
):
530 self
.exec_command('/usr/bin/cgdelete -g l3mdev:%s' %ifaceobj
.name
)
532 self
.log_info('%s: cgroup delete failed (%s)\n'
533 %(ifaceobj
.name
, str(e
)), ifaceobj
)
535 def _down_vrf_dev(self
, ifaceobj
, vrf_table
, ifaceobj_getfunc
=None):
536 if vrf_table
== 'auto':
537 vrf_table
= self
._get
_iproute
2_vrf
_table
(ifaceobj
.name
)
539 running_slaves
= self
.ipcmd
.link_get_lowers(ifaceobj
.name
)
541 for s
in running_slaves
:
543 sobj
= ifaceobj_getfunc(s
)
544 # if dhcp slave, release the dhcp lease
545 if sobj
and self
._is
_dhcp
_slave
(sobj
[0]):
546 self
._down
_dhcp
_slave
(sobj
[0])
547 self
.ipcmd
.link_delete(ifaceobj
.name
)
549 self
.logger
.info('%s: %s' %(ifaceobj
.name
, str(e
)))
553 self
._iproute
2_vrf
_table
_entry
_del
(vrf_table
)
554 self
._delete
_cgroup
(ifaceobj
)
556 self
.logger
.info('%s: %s' %(ifaceobj
.name
, str(e
)))
560 self
._del
_vrf
_rules
(ifaceobj
.name
, vrf_table
)
562 self
.logger
.info('%s: %s' %(ifaceobj
.name
, str(e
)))
565 def _down_vrf_slave(self
, ifacename
, vrf
):
567 self
.ipcmd
.link_set(ifacename
, 'nomaster')
569 self
.logger
.warn('%s: %s' %(ifacename
, str(e
)))
571 def _down(self
, ifaceobj
, ifaceobj_getfunc
=None):
573 vrf_table
= ifaceobj
.get_attr_value_first('vrf-table')
575 self
._down
_vrf
_dev
(ifaceobj
, vrf_table
, ifaceobj_getfunc
)
577 vrf
= ifaceobj
.get_attr_value_first('vrf')
579 self
._down
_vrf
_slave
(ifaceobj
.name
, vrf
)
581 self
.log_warn(str(e
))
583 def _query_check_vrf_slave(self
, ifaceobj
, ifaceobjcurr
, vrf
):
585 master
= self
.ipcmd
.link_get_master(ifaceobj
.name
)
586 if not master
or master
!= vrf
:
587 ifaceobjcurr
.update_config_with_status('vrf', master
, 1)
589 ifaceobjcurr
.update_config_with_status('vrf', master
, 0)
591 self
.log_warn(str(e
))
593 def _query_check_vrf_dev(self
, ifaceobj
, ifaceobjcurr
, vrf_table
):
595 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
596 self
.logger
.info('%s: vrf: does not exist' %(ifaceobj
.name
))
598 if vrf_table
== 'auto':
599 config_table
= self
._get
_iproute
2_vrf
_table
(ifaceobj
.name
)
601 config_table
= vrf_table
602 vrfdev_attrs
= self
.ipcmd
.link_get_linkinfo_attrs(ifaceobj
.name
)
604 ifaceobjcurr
.update_config_with_status('vrf-table', 'None', 1)
606 running_table
= vrfdev_attrs
.get('table')
607 if not running_table
:
608 ifaceobjcurr
.update_config_with_status('vrf-table', 'None', 1)
610 if config_table
!= running_table
:
611 ifaceobjcurr
.update_config_with_status('vrf-table',
614 ifaceobjcurr
.update_config_with_status('vrf-table',
617 self
.log_warn(str(e
))
619 def _query_check(self
, ifaceobj
, ifaceobjcurr
):
621 vrf_table
= ifaceobj
.get_attr_value_first('vrf-table')
623 self
._query
_check
_vrf
_dev
(ifaceobj
, ifaceobjcurr
, vrf_table
)
625 vrf
= ifaceobj
.get_attr_value_first('vrf')
627 self
._query
_check
_vrf
_slave
(ifaceobj
, ifaceobjcurr
, vrf
)
629 self
.log_warn(str(e
))
631 def _query_running(self
, ifaceobjrunning
, ifaceobj_getfunc
=None):
633 kind
= self
.ipcmd
.link_get_kind(ifaceobjrunning
.name
)
635 vrfdev_attrs
= self
.ipcmd
.link_get_linkinfo_attrs(ifaceobjrunning
.name
)
637 running_table
= vrfdev_attrs
.get('table')
639 ifaceobjrunning
.update_config('vrf-table',
641 elif kind
== 'vrf_slave':
642 vrf
= self
.ipcmd
.link_get_master(ifaceobjrunning
.name
)
644 ifaceobjrunning
.update_config('vrf', vrf
)
646 self
.log_warn(str(e
))
648 _run_ops
= {'pre-up' : _up
,
650 'query-running' : _query_running
,
651 'query-checkcurr' : _query_check
}
654 """ returns list of ops supported by this module """
655 return self
._run
_ops
.keys()
657 def _init_command_handlers(self
):
658 flags
= self
.get_flags()
660 self
.ipcmd
= iproute2(**flags
)
662 self
.bondcmd
= bondutil(**flags
)
663 if not self
.dhclientcmd
:
664 self
.dhclientcmd
= dhclient(**flags
)
666 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None,
667 ifaceobj_getfunc
=None, **extra_args
):
668 """ run bond configuration on the interface object passed as argument
671 **ifaceobj** (object): iface object
673 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
677 **query_ifaceobj** (object): query check ifaceobject. This is only
678 valid when op is 'query-checkcurr'. It is an object same as
679 ifaceobj, but contains running attribute values and its config
680 status. The modules can use it to return queried running state
681 of interfaces. status is success if the running state is same
682 as user required state in ifaceobj. error otherwise.
684 op_handler
= self
._run
_ops
.get(operation
)
687 self
._init
_command
_handlers
()
688 if operation
== 'query-checkcurr':
689 op_handler(self
, ifaceobj
, query_ifaceobj
)
691 op_handler(self
, ifaceobj
, ifaceobj_getfunc
=ifaceobj_getfunc
)