1
0
mirror of https://github.com/CumulusNetworks/ifupdown2.git synced 2024-05-06 15:54:50 +00:00

vrf: finish support for vrf-table auto

Ticket: CM-9105
Reviewed By: dsa, nikhil, julien
Testing Done:

This commit contains:
- few logic fixes in vrf-table auto handling code
- adds a new policy manager api to read module global
attributes like the below:
 "module_globals": {"vrf_table-id-start" : 1001,
                    "vrf_table-id-end" : 5000,
                    "vrf-max-count" : 64 },
                    "vrf-cgroup-create" : "yes" },

- Accepts following new vrf attributes from policy files

{
    "vrf": {
        "module_globals": {"vrf_table-id-start" : 1001,
                           "vrf_table-id-end" : 5000,
                           "vrf-max-count" : 64 },
                           "vrf-cgroup-create" : "yes" },
        "defaults": { "vrf-default-route": "yes" }
    }
}
This commit is contained in:
Roopa Prabhu
2016-03-10 20:24:33 -08:00
parent 2876ca35c1
commit 6f2890fcf4
2 changed files with 91 additions and 14 deletions

View File

@@ -33,9 +33,9 @@ class vrf(moduleBase):
iproute2_vrf_filename = '/etc/iproute2/rt_tables.d/ifupdown2_vrf_map.conf'
iproute2_vrf_filehdr = '# This file is autogenerated by ifupdown2.\n' + \
'# It contains the vrf name to table mapping.\n' + \
'# Reserved table range 150-200\n'
vrf_table_reserved_start = 150
vrf_table_reserved_end = 200
'# Reserved table range %s %s\n'
VRF_TABLE_START = 1001
VRF_TABLE_END = 5000
def __init__(self, *args, **kargs):
ifupdownaddons.modulebase.moduleBase.__init__(self, *args, **kargs)
@@ -94,16 +94,32 @@ class vrf(moduleBase):
pass
self.iproute2_vrf_map = iproute2_vrf_map_pruned
last_used_vrf_table = self.vrf_table_reserved_start
for t in range(self.vrf_table_reserved_start,
self.vrf_table_reserved_end):
last_used_vrf_table = t
self.vrf_table_id_start = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vrf-table-id-start')
if not self.vrf_table_id_start:
self.vrf_table_id_start = self.VRF_TABLE_START
self.vrf_table_id_end = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vrf-table-id-end')
if not self.vrf_table_id_end:
self.vrf_table_id_end = self.VRF_TABLE_END
self.vrf_max_count = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vf-max-count')
last_used_vrf_table = None
for t in range(self.vrf_table_id_start,
self.vrf_table_id_end):
if not self.iproute2_vrf_map.get(t):
break
last_used_vrf_table = t
self.last_used_vrf_table = last_used_vrf_table
self.iproute2_write_vrf_map = False
atexit.register(self.iproute2_vrf_map_write)
self.vrf_fix_local_table = True
self.vrf_count = 0
self.vrf_cgroup_create = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vf-cgroup-create')
if not self.vrf_cgroup_create:
self.vrf_cgroup_create = False
elif self.vrf_cgroup_create == 'yes':
self.vrf_cgroup_create = True
else:
self.vrf_cgroup_create = False
def iproute2_vrf_map_write(self):
if not self.iproute2_write_vrf_map:
@@ -111,7 +127,8 @@ class vrf(moduleBase):
self.logger.info('vrf: writing table map to %s'
%self.iproute2_vrf_filename)
with open(self.iproute2_vrf_filename, 'w') as f:
f.write(self.iproute2_vrf_filehdr)
f.write(self.iproute2_vrf_filehdr %(self.vrf_table_id_start,
self.vrf_table_id_end))
for t, v in self.iproute2_vrf_map.iteritems():
f.write('%s %s\n' %(t, v))
@@ -143,11 +160,15 @@ class vrf(moduleBase):
return None
def _get_avail_vrf_table_id(self):
for t in range(self.last_used_vrf_table + 1,
self.vrf_table_reserved_end):
if self.last_used_vrf_table == None:
table_id_start = self.vrf_table_id_start
else:
table_id_start = self.last_used_vrf_table + 1
for t in range(table_id_start,
self.vrf_table_id_end):
if not self.iproute2_vrf_map.get(t):
self.last_used_vrf_table = t
return t
return str(t)
return None
def _iproute2_vrf_table_entry_add(self, vrf_dev_name, table_id):
@@ -268,6 +289,8 @@ class vrf(moduleBase):
pass
def _create_cgroup(self, ifaceobj):
if not self.vrf_cgroup_create:
return
try:
if not os.path.exists('/sys/fs/cgroup/l3mdev/%s' %ifaceobj.name):
self.exec_command('cgcreate -g l3mdev:%s' %ifaceobj.name)
@@ -278,10 +301,24 @@ class vrf(moduleBase):
%(ifaceobj.name, str(e)), ifaceobj)
def _up_vrf_dev(self, ifaceobj, vrf_table):
if vrf_table == 'auto':
vrf_table = _get_avail_vrf_table_id(ifaceobj.name)
if not self.ipcmd.link_exists(ifaceobj.name):
if vrf_table == 'auto':
vrf_table = self._get_avail_vrf_table_id()
if not vrf_table:
self.log_error('%s: unable to get an auto table id'
%ifaceobj.name)
self.logger.info('%s: table id auto: selected table id %s\n'
%(ifaceobj.name, vrf_table))
# XXX: If we decide to not allow vrf id usages out of
# the reserved ifupdown range, then uncomment this code.
#else:
# if (int(vrf_table) < self.vrf_table_id_start or
# int(vrf_table) > self.vrf_table_id_end):
# self.log_error('%s: vrf table id %s out of reserved range [%d,%d]'
# %(ifaceobj.name, vrf_table,
# self.vrf_table_id_start,
# self.vrf_table_id_end))
try:
self.ipcmd.link_create(ifaceobj.name, 'vrf',
{'table' : '%s' %vrf_table})
@@ -289,12 +326,18 @@ class vrf(moduleBase):
self.log_error('%s: create failed (%s)\n'
%(ifaceobj.name, str(e)))
else:
vrf_table = self._get_iproute2_vrf_table(ifaceobj.name)
if not vrf_table:
self.log_error('%s: unable to get vrf table id'
%ifaceobj.name)
# if the device exists, check if table id is same
vrfdev_attrs = self.ipcmd.link_get_linkinfo_attrs(ifaceobj.name)
if vrfdev_attrs:
running_table = vrfdev_attrs.get('table', None)
if vrf_table != running_table:
self.log_error('%s: cannot change vrf table id,running table id %s is different from config id %s' %(running_table, vrf_table))
self.log_error('%s: cannot change vrf table id,running table id %s is different from config id %s' %(ifaceobj.name,
running_table, vrf_table))
try:
self._iproute2_vrf_table_entry_add(ifaceobj.name, vrf_table)
@@ -330,6 +373,10 @@ class vrf(moduleBase):
try:
vrf_table = ifaceobj.get_attr_value_first('vrf-table')
if vrf_table:
if self.vrf_count == self.vrf_max_count:
self.log_error('%s: max vrf count %d hit...not '
'creating vrf' %(ifaceobj.name,
self.vrf_count))
self._up_vrf_dev(ifaceobj, vrf_table)
self._up_vrf_default_route(ifaceobj, vrf_table)
else: