]>
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])
548 self
.logger
.info('%s: %s' %(ifaceobj
.name
, str(e
)))
552 self
._del
_vrf
_rules
(ifaceobj
.name
, vrf_table
)
554 self
.logger
.info('%s: %s' %(ifaceobj
.name
, str(e
)))
558 self
.ipcmd
.link_delete(ifaceobj
.name
)
560 self
.logger
.info('%s: %s' %(ifaceobj
.name
, str(e
)))
564 self
._iproute
2_vrf
_table
_entry
_del
(vrf_table
)
565 self
._delete
_cgroup
(ifaceobj
)
567 self
.logger
.info('%s: %s' %(ifaceobj
.name
, str(e
)))
571 def _down_vrf_slave(self
, ifacename
, vrf
):
573 self
.ipcmd
.link_set(ifacename
, 'nomaster')
575 self
.logger
.warn('%s: %s' %(ifacename
, str(e
)))
577 def _down(self
, ifaceobj
, ifaceobj_getfunc
=None):
579 vrf_table
= ifaceobj
.get_attr_value_first('vrf-table')
581 self
._down
_vrf
_dev
(ifaceobj
, vrf_table
, ifaceobj_getfunc
)
583 vrf
= ifaceobj
.get_attr_value_first('vrf')
585 self
._down
_vrf
_slave
(ifaceobj
.name
, vrf
)
587 self
.log_warn(str(e
))
589 def _query_check_vrf_slave(self
, ifaceobj
, ifaceobjcurr
, vrf
):
591 master
= self
.ipcmd
.link_get_master(ifaceobj
.name
)
592 if not master
or master
!= vrf
:
593 ifaceobjcurr
.update_config_with_status('vrf', master
, 1)
595 ifaceobjcurr
.update_config_with_status('vrf', master
, 0)
597 self
.log_warn(str(e
))
599 def _query_check_vrf_dev(self
, ifaceobj
, ifaceobjcurr
, vrf_table
):
601 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
602 self
.logger
.info('%s: vrf: does not exist' %(ifaceobj
.name
))
604 if vrf_table
== 'auto':
605 config_table
= self
._get
_iproute
2_vrf
_table
(ifaceobj
.name
)
607 config_table
= vrf_table
608 vrfdev_attrs
= self
.ipcmd
.link_get_linkinfo_attrs(ifaceobj
.name
)
610 ifaceobjcurr
.update_config_with_status('vrf-table', 'None', 1)
612 running_table
= vrfdev_attrs
.get('table')
613 if not running_table
:
614 ifaceobjcurr
.update_config_with_status('vrf-table', 'None', 1)
616 if config_table
!= running_table
:
617 ifaceobjcurr
.update_config_with_status('vrf-table',
620 ifaceobjcurr
.update_config_with_status('vrf-table',
623 self
.log_warn(str(e
))
625 def _query_check(self
, ifaceobj
, ifaceobjcurr
):
627 vrf_table
= ifaceobj
.get_attr_value_first('vrf-table')
629 self
._query
_check
_vrf
_dev
(ifaceobj
, ifaceobjcurr
, vrf_table
)
631 vrf
= ifaceobj
.get_attr_value_first('vrf')
633 self
._query
_check
_vrf
_slave
(ifaceobj
, ifaceobjcurr
, vrf
)
635 self
.log_warn(str(e
))
637 def _query_running(self
, ifaceobjrunning
, ifaceobj_getfunc
=None):
639 kind
= self
.ipcmd
.link_get_kind(ifaceobjrunning
.name
)
641 vrfdev_attrs
= self
.ipcmd
.link_get_linkinfo_attrs(ifaceobjrunning
.name
)
643 running_table
= vrfdev_attrs
.get('table')
645 ifaceobjrunning
.update_config('vrf-table',
647 elif kind
== 'vrf_slave':
648 vrf
= self
.ipcmd
.link_get_master(ifaceobjrunning
.name
)
650 ifaceobjrunning
.update_config('vrf', vrf
)
652 self
.log_warn(str(e
))
654 _run_ops
= {'pre-up' : _up
,
656 'query-running' : _query_running
,
657 'query-checkcurr' : _query_check
}
660 """ returns list of ops supported by this module """
661 return self
._run
_ops
.keys()
663 def _init_command_handlers(self
):
664 flags
= self
.get_flags()
666 self
.ipcmd
= iproute2(**flags
)
668 self
.bondcmd
= bondutil(**flags
)
669 if not self
.dhclientcmd
:
670 self
.dhclientcmd
= dhclient(**flags
)
672 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None,
673 ifaceobj_getfunc
=None, **extra_args
):
674 """ run bond configuration on the interface object passed as argument
677 **ifaceobj** (object): iface object
679 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
683 **query_ifaceobj** (object): query check ifaceobject. This is only
684 valid when op is 'query-checkcurr'. It is an object same as
685 ifaceobj, but contains running attribute values and its config
686 status. The modules can use it to return queried running state
687 of interfaces. status is success if the running state is same
688 as user required state in ifaceobj. error otherwise.
690 op_handler
= self
._run
_ops
.get(operation
)
693 self
._init
_command
_handlers
()
694 if operation
== 'query-checkcurr':
695 op_handler(self
, ifaceobj
, query_ifaceobj
)
697 op_handler(self
, ifaceobj
, ifaceobj_getfunc
=ifaceobj_getfunc
)