mirror of
https://github.com/CumulusNetworks/ifupdown2.git
synced 2024-05-06 15:54:50 +00:00
Merge branch 'dev' into release/cl-stable
This commit is contained in:
157
addons/vrf.py
157
addons/vrf.py
@@ -13,6 +13,7 @@ from ifupdown.iface import *
|
||||
import ifupdown.policymanager as policymanager
|
||||
import ifupdownaddons
|
||||
import ifupdown.rtnetlink_api as rtnetlink_api
|
||||
import ifupdown.ifupdownflags as ifupdownflags
|
||||
from ifupdownaddons.modulebase import moduleBase
|
||||
from ifupdownaddons.bondutil import bondutil
|
||||
from ifupdownaddons.iproute2 import iproute2
|
||||
@@ -50,7 +51,7 @@ class vrf(moduleBase):
|
||||
self.bondcmd = None
|
||||
self.dhclientcmd = None
|
||||
self.name = self.__class__.__name__
|
||||
if self.PERFMODE:
|
||||
if ifupdownflags.flags.PERFMODE:
|
||||
# if perf mode is set, remove vrf map file.
|
||||
# start afresh. PERFMODE is set at boot
|
||||
if os.path.exists(self.iproute2_vrf_filename):
|
||||
@@ -97,6 +98,7 @@ class vrf(moduleBase):
|
||||
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='vrf-cgroup-create')
|
||||
|
||||
if not self.vrf_cgroup_create:
|
||||
self.vrf_cgroup_create = False
|
||||
elif self.vrf_cgroup_create == 'yes':
|
||||
@@ -104,6 +106,7 @@ class vrf(moduleBase):
|
||||
else:
|
||||
self.vrf_cgroup_create = False
|
||||
self.vrf_mgmt_devname = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vrf-mgmt-devname')
|
||||
self.vrf_helper = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vrf-helper')
|
||||
|
||||
def _iproute2_vrf_map_initialize(self):
|
||||
if self._iproute2_vrf_map_initialized:
|
||||
@@ -243,14 +246,24 @@ class vrf(moduleBase):
|
||||
return str(t)
|
||||
return None
|
||||
|
||||
def _iproute2_is_vrf_tableid_inuse(self, vrf_dev_name, table_id):
|
||||
old_vrf_name = self.iproute2_vrf_map.get(int(table_id))
|
||||
if old_vrf_name and old_vrf_name != vrf_dev_name:
|
||||
self.log_error('table id %s already assigned to vrf dev %s'
|
||||
%(table_id, old_vrf_name))
|
||||
|
||||
def _iproute2_vrf_table_entry_add(self, vrf_dev_name, table_id):
|
||||
old_vrf_name = self.iproute2_vrf_map.get(int(table_id))
|
||||
if not old_vrf_name or (old_vrf_name != vrf_dev_name):
|
||||
if not old_vrf_name:
|
||||
self.iproute2_vrf_map[int(table_id)] = vrf_dev_name
|
||||
if self.iproute2_vrf_map_fd:
|
||||
self.iproute2_vrf_map_fd.write('%s %s\n'
|
||||
%(table_id, vrf_dev_name))
|
||||
self.iproute2_vrf_map_fd.flush()
|
||||
return
|
||||
if old_vrf_name != vrf_dev_name:
|
||||
self.log_error('table id %d already assigned to vrf dev %s'
|
||||
%(table_id, old_vrf_name))
|
||||
|
||||
def _iproute2_vrf_table_entry_del(self, table_id):
|
||||
try:
|
||||
@@ -307,27 +320,35 @@ class vrf(moduleBase):
|
||||
%mobj.name)
|
||||
self.logger.info('%s: table id auto: selected table id %s\n'
|
||||
%(mobj.name, vrf_table))
|
||||
self._up_vrf_dev(mobj, vrf_table, False)
|
||||
try:
|
||||
self._up_vrf_dev(mobj, vrf_table, False)
|
||||
except Exception:
|
||||
raise
|
||||
break
|
||||
self._handle_existing_connections(ifaceobj, vrfname)
|
||||
self.ipcmd.link_set(ifacename, 'master', vrfname)
|
||||
return
|
||||
|
||||
def _down_dhcp_slave(self, ifaceobj):
|
||||
def _down_dhcp_slave(self, ifaceobj, vrfname):
|
||||
try:
|
||||
self.dhclientcmd.release(ifaceobj.name)
|
||||
dhclient_cmd_prefix = None
|
||||
if (vrfname and self.vrf_exec_cmd_prefix and
|
||||
self.ipcmd.link_exists(vrfname)):
|
||||
dhclient_cmd_prefix = '%s %s' %(self.vrf_exec_cmd_prefix,
|
||||
vrfname)
|
||||
self.dhclientcmd.release(ifaceobj.name, dhclient_cmd_prefix)
|
||||
except:
|
||||
# ignore any dhclient release errors
|
||||
pass
|
||||
|
||||
def _handle_existing_connections(self, ifaceobj, vrfname):
|
||||
if not ifaceobj or self.PERFMODE:
|
||||
if not ifaceobj or ifupdownflags.flags.PERFMODE:
|
||||
return
|
||||
if (self.vrf_mgmt_devname and
|
||||
self.vrf_mgmt_devname == vrfname):
|
||||
self._kill_ssh_connections(ifaceobj.name)
|
||||
if self._is_dhcp_slave(ifaceobj):
|
||||
self._down_dhcp_slave(ifaceobj)
|
||||
self._down_dhcp_slave(ifaceobj, vrfname)
|
||||
|
||||
def _up_vrf_slave(self, ifacename, vrfname, ifaceobj=None,
|
||||
ifaceobj_getfunc=None, vrf_exists=False):
|
||||
@@ -351,24 +372,26 @@ class vrf(moduleBase):
|
||||
|
||||
rule = ip_rule_out_format %(pref, 'oif', vrf_dev_name, vrf_dev_name)
|
||||
if rule in self.ip_rule_cache:
|
||||
rule_cmd = ip_rule_cmd %('', pref, 'oif', vrf_dev_name, vrf_table)
|
||||
rule_cmd = ip_rule_cmd %('', pref, 'oif', vrf_dev_name,
|
||||
vrf_dev_name)
|
||||
self.exec_command(rule_cmd)
|
||||
|
||||
rule = ip_rule_out_format %(pref, 'iif', vrf_dev_name, vrf_dev_name)
|
||||
if rule in self.ip_rule_cache:
|
||||
rule_cmd = ip_rule_cmd %('', pref, 'iif', vrf_dev_name, vrf_table)
|
||||
rule_cmd = ip_rule_cmd %('', pref, 'iif', vrf_dev_name,
|
||||
vrf_dev_name)
|
||||
self.exec_command(rule_cmd)
|
||||
|
||||
rule = ip_rule_out_format %(pref, 'oif', vrf_dev_name, vrf_dev_name)
|
||||
if rule in self.ip6_rule_cache:
|
||||
rule_cmd = ip_rule_cmd %('-6', pref, 'oif', vrf_dev_name,
|
||||
vrf_table)
|
||||
vrf_dev_name)
|
||||
self.exec_command(rule_cmd)
|
||||
|
||||
rule = ip_rule_out_format %(pref, 'iif', vrf_dev_name, vrf_dev_name)
|
||||
if rule in self.ip6_rule_cache:
|
||||
rule_cmd = ip_rule_cmd %('-6', pref, 'iif', vrf_dev_name,
|
||||
vrf_table)
|
||||
vrf_dev_name)
|
||||
self.exec_command(rule_cmd)
|
||||
|
||||
def _add_vrf_rules(self, vrf_dev_name, vrf_table):
|
||||
@@ -399,23 +422,26 @@ class vrf(moduleBase):
|
||||
|
||||
rule = ip_rule_out_format %(pref, 'oif', vrf_dev_name, vrf_dev_name)
|
||||
if rule not in self.ip_rule_cache:
|
||||
rule_cmd = ip_rule_cmd %('', pref, 'oif', vrf_dev_name, vrf_table)
|
||||
rule_cmd = ip_rule_cmd %('', pref, 'oif', vrf_dev_name,
|
||||
vrf_dev_name)
|
||||
self.exec_command(rule_cmd)
|
||||
|
||||
rule = ip_rule_out_format %(pref, 'iif', vrf_dev_name, vrf_dev_name)
|
||||
if rule not in self.ip_rule_cache:
|
||||
rule_cmd = ip_rule_cmd %('', pref, 'iif', vrf_dev_name, vrf_table)
|
||||
rule_cmd = ip_rule_cmd %('', pref, 'iif', vrf_dev_name,
|
||||
vrf_dev_name)
|
||||
self.exec_command(rule_cmd)
|
||||
|
||||
rule = ip_rule_out_format %(pref, 'oif', vrf_dev_name, vrf_dev_name)
|
||||
if rule not in self.ip6_rule_cache:
|
||||
rule_cmd = ip_rule_cmd %('-6', pref, 'oif', vrf_dev_name, vrf_table)
|
||||
rule_cmd = ip_rule_cmd %('-6', pref, 'oif', vrf_dev_name,
|
||||
vrf_dev_name)
|
||||
self.exec_command(rule_cmd)
|
||||
|
||||
rule = ip_rule_out_format %(pref, 'iif', vrf_dev_name, vrf_dev_name)
|
||||
if rule not in self.ip6_rule_cache:
|
||||
rule_cmd = ip_rule_cmd %('-6', pref, 'iif', vrf_dev_name,
|
||||
vrf_table)
|
||||
vrf_dev_name)
|
||||
self.exec_command(rule_cmd)
|
||||
|
||||
def _add_vrf_slaves(self, ifaceobj, ifaceobj_getfunc=None):
|
||||
@@ -460,29 +486,13 @@ class vrf(moduleBase):
|
||||
%(ifaceobj.name, s, str(e)))
|
||||
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('/usr/bin/cgcreate -g l3mdev:%s' %ifaceobj.name)
|
||||
except Exception, e:
|
||||
self.log_error('%s: cgroup create failed (%s)\n'
|
||||
%(ifaceobj.name, str(e)), ifaceobj)
|
||||
try:
|
||||
self.exec_command('/usr/bin/cgset -r l3mdev.master-device=%s %s'
|
||||
%(ifaceobj.name, ifaceobj.name))
|
||||
except Exception, e:
|
||||
self.log_warn('%s: cgset failed (%s)\n'
|
||||
%(ifaceobj.name, str(e)), ifaceobj)
|
||||
|
||||
def _set_vrf_dev_processed_flag(self, ifaceobj):
|
||||
ifaceobj.module_flags[self.name] = \
|
||||
ifaceobj.module_flags.setdefault(self.name, 0) | \
|
||||
vrfPrivFlags.PROCESSED
|
||||
|
||||
def _check_vrf_dev_processed_flag(self, ifaceobj):
|
||||
if (ifaceobj.module_flags.get(self.name, 0x0) & vrfPrivFlags.PROCESSED):
|
||||
if (ifaceobj.module_flags.get(self.name, 0) & vrfPrivFlags.PROCESSED):
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -495,6 +505,8 @@ class vrf(moduleBase):
|
||||
%ifaceobj.name)
|
||||
self.logger.info('%s: table id auto: selected table id %s\n'
|
||||
%(ifaceobj.name, vrf_table))
|
||||
else:
|
||||
self._iproute2_is_vrf_tableid_inuse(ifaceobj.name, vrf_table)
|
||||
|
||||
if not vrf_table.isdigit():
|
||||
self.log_error('%s: vrf-table must be an integer or \'auto\''
|
||||
@@ -515,6 +527,8 @@ class vrf(moduleBase):
|
||||
except Exception, e:
|
||||
self.log_error('%s: create failed (%s)\n'
|
||||
%(ifaceobj.name, str(e)))
|
||||
if vrf_table != 'auto':
|
||||
self._iproute2_vrf_table_entry_add(ifaceobj.name, vrf_table)
|
||||
else:
|
||||
if vrf_table == 'auto':
|
||||
vrf_table = self._get_iproute2_vrf_table(ifaceobj.name)
|
||||
@@ -529,49 +543,12 @@ class vrf(moduleBase):
|
||||
if vrf_table != running_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))
|
||||
if vrf_table != 'auto':
|
||||
self._iproute2_vrf_table_entry_add(ifaceobj.name, vrf_table)
|
||||
|
||||
return vrf_table
|
||||
|
||||
def _add_del_vrf_default_route(self, ifaceobj, vrf_table, add=True):
|
||||
vrf_default_route = ifaceobj.get_attr_value_first('vrf-default-route')
|
||||
if not vrf_default_route:
|
||||
vrf_default_route = policymanager.policymanager_api.get_attr_default(
|
||||
module_name=self.__class__.__name__,
|
||||
attr='vrf-default-route')
|
||||
if not vrf_default_route:
|
||||
return
|
||||
if str(vrf_default_route).lower() == "yes":
|
||||
try:
|
||||
if add:
|
||||
self.exec_command('ip route add table %s unreachable '
|
||||
'default metric %d' %(vrf_table, 240))
|
||||
else:
|
||||
self.exec_command('ip route del table %s unreachable '
|
||||
'default metric %d' %(vrf_table, 240))
|
||||
except OSError, e:
|
||||
if add and e.errno != 17:
|
||||
raise
|
||||
else:
|
||||
self.logger.info('%s: error deleting default route (%s)'
|
||||
%(ifaceobj.name, str(e)))
|
||||
pass
|
||||
|
||||
try:
|
||||
if add:
|
||||
self.exec_command('ip -6 route add table %s unreachable '
|
||||
'default metric %d' %(vrf_table, 240))
|
||||
else:
|
||||
self.exec_command('ip -6 route del table %s unreachable '
|
||||
'default metric %d' %(vrf_table, 240))
|
||||
except OSError, e:
|
||||
if add and e.errno != 17:
|
||||
raise
|
||||
else:
|
||||
self.logger.info('%s: error deleting default route (%s)'
|
||||
%(ifaceobj.name, str(e)))
|
||||
pass
|
||||
def _up_vrf_helper(self, ifaceobj, vrf_table):
|
||||
if self.vrf_helper:
|
||||
self.exec_command('%s create %s %s' %(self.vrf_helper,
|
||||
ifaceobj.name, vrf_table))
|
||||
|
||||
def _up_vrf_dev(self, ifaceobj, vrf_table, add_slaves=True,
|
||||
ifaceobj_getfunc=None):
|
||||
@@ -582,13 +559,16 @@ class vrf(moduleBase):
|
||||
if self._check_vrf_dev_processed_flag(ifaceobj):
|
||||
return True
|
||||
|
||||
vrf_table = self._create_vrf_dev(ifaceobj, vrf_table)
|
||||
try:
|
||||
vrf_table = self._create_vrf_dev(ifaceobj, vrf_table)
|
||||
except Exception, e:
|
||||
self.log_error('%s: %s' %(ifaceobj.name, str(e)))
|
||||
|
||||
try:
|
||||
self._add_vrf_rules(ifaceobj.name, vrf_table)
|
||||
self._create_cgroup(ifaceobj)
|
||||
self._up_vrf_helper(ifaceobj, vrf_table)
|
||||
if add_slaves:
|
||||
self._add_vrf_slaves(ifaceobj, ifaceobj_getfunc)
|
||||
self._add_del_vrf_default_route(ifaceobj, vrf_table)
|
||||
self._set_vrf_dev_processed_flag(ifaceobj)
|
||||
rtnetlink_api.rtnl_api.link_set(ifaceobj.name, "up")
|
||||
except Exception, e:
|
||||
@@ -681,19 +661,17 @@ class vrf(moduleBase):
|
||||
# check if we were a slave before
|
||||
master = self.ipcmd.link_get_master(ifaceobj.name)
|
||||
if master:
|
||||
self._iproute2_vrf_map_initialize()
|
||||
if self._is_vrf_dev(master):
|
||||
self._down_vrf_slave(ifaceobj.name, ifaceobj,
|
||||
master)
|
||||
except Exception, e:
|
||||
self.log_error(str(e))
|
||||
|
||||
def _delete_cgroup(self, ifaceobj):
|
||||
try:
|
||||
if os.path.exists('/sys/fs/cgroup/l3mdev/%s' %ifaceobj.name):
|
||||
self.exec_command('/usr/bin/cgdelete -g l3mdev:%s' %ifaceobj.name)
|
||||
except Exception, e:
|
||||
self.log_info('%s: cgroup delete failed (%s)\n'
|
||||
%(ifaceobj.name, str(e)), ifaceobj)
|
||||
def _down_vrf_helper(self, ifaceobj, vrf_table):
|
||||
if self.vrf_helper:
|
||||
self.exec_command('%s delete %s %s' %(self.vrf_helper,
|
||||
ifaceobj.name, vrf_table))
|
||||
|
||||
def _down_vrf_dev(self, ifaceobj, vrf_table, ifaceobj_getfunc=None):
|
||||
|
||||
@@ -701,7 +679,7 @@ class vrf(moduleBase):
|
||||
vrf_table = self._get_iproute2_vrf_table(ifaceobj.name)
|
||||
|
||||
try:
|
||||
self.exec_command('/usr/cumulus/bin/cl-vrf service disable %s' %ifaceobj.name)
|
||||
self.exec_command('/usr/bin/vrf service disable %s' %ifaceobj.name)
|
||||
except Exception, e:
|
||||
self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
|
||||
pass
|
||||
@@ -718,6 +696,8 @@ class vrf(moduleBase):
|
||||
self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
|
||||
pass
|
||||
|
||||
self._down_vrf_helper(ifaceobj, vrf_table)
|
||||
|
||||
try:
|
||||
self._del_vrf_rules(ifaceobj.name, vrf_table)
|
||||
except Exception, e:
|
||||
@@ -732,8 +712,6 @@ class vrf(moduleBase):
|
||||
|
||||
try:
|
||||
self._iproute2_vrf_table_entry_del(vrf_table)
|
||||
self._add_del_vrf_default_route(ifaceobj, vrf_table, False)
|
||||
self._delete_cgroup(ifaceobj)
|
||||
except Exception, e:
|
||||
self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
|
||||
pass
|
||||
@@ -838,13 +816,12 @@ class vrf(moduleBase):
|
||||
return self._run_ops.keys()
|
||||
|
||||
def _init_command_handlers(self):
|
||||
flags = self.get_flags()
|
||||
if not self.ipcmd:
|
||||
self.ipcmd = iproute2(**flags)
|
||||
self.ipcmd = iproute2()
|
||||
if not self.bondcmd:
|
||||
self.bondcmd = bondutil(**flags)
|
||||
self.bondcmd = bondutil()
|
||||
if not self.dhclientcmd:
|
||||
self.dhclientcmd = dhclient(**flags)
|
||||
self.dhclientcmd = dhclient()
|
||||
|
||||
def run(self, ifaceobj, operation, query_ifaceobj=None,
|
||||
ifaceobj_getfunc=None, **extra_args):
|
||||
|
Reference in New Issue
Block a user