self.vrf_fix_local_table = True
self.vrf_count = 0
self.vrf_helper = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vrf-helper')
+ self.vrf_close_socks_on_down = policymanager.policymanager_api.get_module_globals(module_name=self.__class__.__name__, attr='vrf-close-socks-on-down')
+ self.warn_on_vrf_map_write_err = True
def _iproute2_vrf_map_initialize(self, writetodisk=True):
if self._iproute2_vrf_map_initialized:
continue
self.iproute2_vrf_map[int(table)] = vrf_name
except Exception, e:
- self.logger.info('vrf: iproute2_vrf_map: unable to parse %s'
- %l)
+ self.logger.info('vrf: iproute2_vrf_map: unable to parse %s (%s)' %(l, str(e)))
pass
vrfs = self.ipcmd.link_get_vrfs()
self._iproute2_vrf_map_initialized = True
self.vrf_count = len(self.iproute2_vrf_map)
+ def _iproute2_map_warn(self, errstr):
+ if self.warn_on_vrf_map_write_err:
+ if not os.path.exists('/etc/iproute2/rt_tables.d/'):
+ self.logger.info('unable to save iproute2 vrf to table ' +
+ 'map (%s)\n' %errstr)
+ self.logger.info('cannot find /etc/iproute2/rt_tables.d.' +
+ ' pls check if your iproute2 version' +
+ ' supports rt_tables.d')
+ else:
+ self.logger.warn('unable to open iproute2 vrf to table ' +
+ 'map (%s)\n' %errstr)
+ self.warn_on_vrf_map_write_err = False
+
def _iproute2_vrf_map_sync_to_disk(self):
if (ifupdownflags.flags.DRYRUN or
not self.iproute2_vrf_map_sync_to_disk):
return
self.logger.info('vrf: syncing table map to %s'
%self.iproute2_vrf_filename)
- with open(self.iproute2_vrf_filename, 'w') as f:
- 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))
- f.flush()
+ try:
+ with open(self.iproute2_vrf_filename, 'w') as f:
+ 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))
+ f.flush()
+ except Exception, e:
+ self._iproute2_map_warn(str(e))
+ pass
def _iproute2_vrf_map_open(self, sync_vrfs=False, append=False):
self.logger.info('vrf: syncing table map to %s'
'%s' %fmode)
fcntl.fcntl(self.iproute2_vrf_map_fd, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
except Exception, e:
- self.log_warn('vrf: error opening %s (%s)'
- %(self.iproute2_vrf_filename, str(e)))
+ self._iproute2_map_warn(str(e))
return
if not append:
self.iproute2_vrf_map_sync_to_disk = True
del self.iproute2_vrf_map[int(table_id)]
except Exception, e:
- self.logger.info('vrf: iproute2 vrf map del failed for %d (%s)'
+ self.logger.info('vrf: iproute2 vrf map del failed for %s (%s)'
%(table_id, str(e)))
pass
raise
break
self._handle_existing_connections(ifaceobj, vrfname)
- self.ipcmd.link_set(ifacename, 'master', vrfname)
+ netlink.link_set_master(ifacename, vrfname)
return
def _down_dhcp_slave(self, ifaceobj, vrfname):
try:
master_exists = True
if vrf_exists or self.ipcmd.link_exists(vrfname):
- upper = self.ipcmd.link_get_upper(ifacename)
- if not upper or upper != vrfname:
+ uppers = self.ipcmd.link_get_uppers(ifacename)
+ if not uppers or vrfname not in uppers:
self._handle_existing_connections(ifaceobj, vrfname)
- self.ipcmd.link_set(ifacename, 'master', vrfname)
+ netlink.link_set_master(ifacename, vrfname)
elif ifaceobj:
vrf_master_objs = ifaceobj_getfunc(vrfname)
if not vrf_master_objs:
%vrfname)
return
if (ifupdownflags.flags.ALL or
+ ifupdownflags.flags.WITH_DEPENDS or
(ifupdownflags.flags.CLASS and
ifaceobj.classes and vrf_master_objs[0].classes and
Set(ifaceobj.classes).intersection(vrf_master_objs[0].classes))):
%(str(self.system_reserved_rt_tables.values())),
ifaceobj)
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), ifaceobj)
+ self.log_error('max vrf count %d hit...not '
+ 'creating vrf' % self.vrf_count, ifaceobj)
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, ifaceobj)
+ self.log_error('unable to get an auto table id', ifaceobj)
self.logger.info('%s: table id auto: selected table id %s\n'
%(ifaceobj.name, vrf_table))
else:
ifaceobj)
if not vrf_table.isdigit():
- self.log_error('%s: vrf-table must be an integer or \'auto\''
- %(ifaceobj.name), ifaceobj)
+ self.log_error('vrf-table must be an integer or \'auto\'', ifaceobj)
# 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.log_error('vrf table id %s out of reserved range [%d,%d]'
+ %(vrf_table,
self.vrf_table_id_start,
self.vrf_table_id_end), ifaceobj)
try:
self.ipcmd.link_create(ifaceobj.name, 'vrf',
{'table' : '%s' %vrf_table})
except Exception, e:
- self.log_error('%s: create failed (%s)\n'
- %(ifaceobj.name, str(e)), ifaceobj)
+ self.log_error('create failed (%s)\n' % str(e), ifaceobj)
if vrf_table != 'auto':
self._iproute2_vrf_table_entry_add(ifaceobj, vrf_table)
else:
if vrf_table == 'auto':
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, ifaceobj)
+ self.log_error('unable to get vrf table id', ifaceobj)
# 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' %(ifaceobj.name,
- running_table, vrf_table),
- ifaceobj)
+ self.log_error('cannot change vrf table id,running table id'
+ ' %s is different from config id %s'
+ % (running_table, vrf_table), ifaceobj)
return vrf_table
def _up_vrf_helper(self, ifaceobj, vrf_table):
vrf_table,
mode))
+ def _close_sockets(self, ifaceobj, ifindex):
+ if not self.vrf_close_socks_on_down:
+ return
+
+ try:
+ utils.exec_command('/bin/ss -aK \"dev == %s\"'
+ %ifindex)
+ except Exception, e:
+ self.logger.info('%s: closing socks using ss'
+ ' failed (%s)\n' %(ifaceobj.name, str(e)))
+ pass
+
def _down_vrf_dev(self, ifaceobj, vrf_table, ifaceobj_getfunc=None):
+ if not self.ipcmd.link_exists(ifaceobj.name):
+ return
+
if vrf_table == 'auto':
vrf_table = self._get_iproute2_vrf_table(ifaceobj.name)
self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
pass
+ ifindex = self.ipcmd.link_get_ifindex(ifaceobj.name)
+
try:
self.ipcmd.link_delete(ifaceobj.name)
except Exception, e:
self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
pass
+ self._close_sockets(ifaceobj, ifindex)
+
try:
self._iproute2_vrf_table_entry_del(vrf_table)
except Exception, e:
def _down_vrf_slave(self, ifacename, ifaceobj=None, vrfname=None):
try:
self._handle_existing_connections(ifaceobj, vrfname)
- self.ipcmd.link_set(ifacename, 'nomaster')
- netlink.link_set_updown(ifacename, "down")
+ netlink.link_set_nomaster(ifacename)
+ # Down this slave only if it is a slave ifupdown2 manages.
+ # we dont want to down slaves that maybe up'ed by
+ # somebody else. One such example is a macvlan device
+ # which ifupdown2 addressvirtual addon module auto creates
+ if ifaceobj:
+ netlink.link_set_updown(ifacename, "down")
except Exception, e:
self.logger.warn('%s: %s' %(ifacename, str(e)))
if running_table:
ifaceobjrunning.update_config('vrf-table',
running_table)
- elif kind == 'vrf_slave':
+ return
+ slave_kind = self.ipcmd.link_get_slave_kind(ifaceobjrunning.name)
+ if slave_kind == 'vrf_slave':
vrf = self.ipcmd.link_get_master(ifaceobjrunning.name)
if vrf:
ifaceobjrunning.update_config('vrf', vrf)