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) running_slaves = self.ipcmd.link_get_lowers(ifaceobj.name) if running_slaves: for s in running_slaves: if ifaceobj_getfunc: sobj = ifaceobj_getfunc(s) try: self._handle_existing_connections(sobj[0] if sobj else None, ifaceobj.name) except Exception, e: self.logger.info('%s: %s' %(ifaceobj.name, str(e))) pass try: self.ipcmd.addr_flush(s) netlink.link_set_updown(s, "down") except Exception, e: self.logger.info('%s: %s' %(ifaceobj.name, str(e))) pass
def should_update_bond_mode(self, ifaceobj, ifname, is_link_up, ifla_info_data): # if bond-mode was changed the bond needs to be brought # down and slaves un-slaved before bond mode is changed. cached_bond_mode = self.bondcmd.link_cache_get( [ifname, 'linkinfo', Link.IFLA_BOND_MODE]) ifla_bond_mode = ifla_info_data.get(Link.IFLA_BOND_MODE) # bond-mode was changed or is not specified if ifla_bond_mode is not None: if ifla_bond_mode != cached_bond_mode: self.logger.info( '%s: bond mode changed to %s: running ops on bond and slaves' % (ifname, ifla_bond_mode)) if is_link_up: netlink.link_set_updown(ifname, 'down') is_link_up = False for lower_dev in ifaceobj.lowerifaces: netlink.link_set_nomaster(lower_dev) self.bondcmd.cache_delete([ifname, 'linkinfo', 'slaves']) else: # bond-mode user config value is the current running(cached) value # no need to reset it again we can ignore this attribute del ifla_info_data[Link.IFLA_BOND_MODE] return is_link_up
def should_update_bond_mode(self, ifaceobj, ifname, is_link_up, ifla_info_data): # if bond-mode was changed the bond needs to be brought # down and slaves un-slaved before bond mode is changed. cached_bond_mode = self.bondcmd.link_cache_get([ifname, 'linkinfo', Link.IFLA_BOND_MODE]) ifla_bond_mode = ifla_info_data.get(Link.IFLA_BOND_MODE) # bond-mode was changed or is not specified if ifla_bond_mode is not None: if ifla_bond_mode != cached_bond_mode: self.logger.info('%s: bond mode changed to %s: running ops on bond and slaves' % (ifname, ifla_bond_mode)) if is_link_up: netlink.link_set_updown(ifname, 'down') is_link_up = False for lower_dev in ifaceobj.lowerifaces: netlink.link_set_nomaster(lower_dev) self.bondcmd.cache_delete([ifname, 'linkinfo', 'slaves']) else: # bond-mode user config value is the current running(cached) value # no need to reset it again we can ignore this attribute del ifla_info_data[Link.IFLA_BOND_MODE] return is_link_up
def _down_vrf_slave(self, ifacename, ifaceobj=None, vrfname=None): try: self._handle_existing_connections(ifaceobj, vrfname) self.ipcmd.link_set(ifacename, 'nomaster') # 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)))
def create_or_set_bond_config(self, ifaceobj): ifname = ifaceobj.name link_exists = self.ipcmd.link_exists(ifname) is_link_up = self.ipcmd.is_link_up(ifname) if link_exists else False ifla_info_data = self.get_ifla_bond_attr_from_user_config( ifaceobj, link_exists) remove_delay_from_cache = self.check_updown_delay_nl( link_exists, ifaceobj, ifla_info_data) # if link exists: down link if specific attributes are specified if link_exists: # did bond-mode changed? is_link_up = self.should_update_bond_mode(ifaceobj, ifname, is_link_up, ifla_info_data) # if specific attributes need to be set we need to down the bond first if ifla_info_data and is_link_up: if self._should_down_bond(ifla_info_data): netlink.link_set_updown(ifname, 'down') is_link_up = False if link_exists and not ifla_info_data: # if the bond already exists and no attrs need to be set # ignore the netlink call self.logger.info('%s: already exists, no change detected' % ifname) else: try: netlink.link_add_set(kind='bond', ifname=ifname, ifla_info_data=ifla_info_data) except Exception as e: # defensive code # if anything happens, we try to set up the bond with the sysfs api self.logger.debug('%s: bond setup: %s' % (ifname, str(e))) self.create_or_set_bond_config_sysfs(ifaceobj, ifla_info_data) if remove_delay_from_cache: # making sure up/down delay attributes are set to 0 before caching # this can be removed when moving to a nllistener/live cache ifla_info_data[Link.IFLA_BOND_UPDELAY] = 0 ifla_info_data[Link.IFLA_BOND_DOWNDELAY] = 0 # if link_add doesn't raise we can update the cache, the future # netlink listener will update the cache based on the kernel response for key, value in ifla_info_data.items(): self.bondcmd.cache_update([ifname, 'linkinfo', key], value) if link_exists and ifla_info_data and not is_link_up: netlink.link_set_updown(ifname, 'up')
def _up(self, ifaceobj): if self._get_batman_ifaces(ifaceobj) == None: raise Exception('could not determine batman interfacaes') # Verify existance of batman interfaces (should be present already) batman_ifaces = [] for iface in self._get_batman_ifaces(ifaceobj): if not self.ipcmd.link_exists(iface): self.logger.warn('batman iface %s not present' % iface) continue batman_ifaces.append(iface) if len(batman_ifaces) == 0: raise Exception( "None of the configured batman interfaces are available!") routing_algo = ifaceobj.get_attr_value_first('batman-routing-algo') if routing_algo: self._set_routing_algo(routing_algo) if_ignore_re = self._get_batman_ifaces_ignore_regex(ifaceobj) # Is the batman main interface already present? if self.ipcmd.link_exists(ifaceobj.name): # Verify which member interfaces are present members = self._find_member_ifaces(ifaceobj) for iface in members: if iface not in batman_ifaces: self._batctl_if(ifaceobj.name, iface, 'del') for iface in batman_ifaces: if iface not in members: self._batctl_if(ifaceobj.name, iface, 'add') # Batman interfaces no present, add member interfaces to create it else: for iface in batman_ifaces: self._batctl_if(ifaceobj.name, iface, 'add') # Check/set any B.A.T.M.A.N. adv. set within interface configuration for attr in self._batman_attrs: value_cfg = self._get_batman_attr(ifaceobj, attr) if value_cfg and value_cfg != self._read_current_batman_attr( ifaceobj, attr): self._set_batman_attr(ifaceobj, attr, value_cfg) if ifaceobj.addr_method == 'manual': netlink.link_set_updown(ifaceobj.name, "up")
def _up_vrf_slave(self, ifacename, vrfname, ifaceobj=None, ifaceobj_getfunc=None, vrf_exists=False): try: master_exists = True if vrf_exists or self.ipcmd.link_exists(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) elif ifaceobj: vrf_master_objs = ifaceobj_getfunc(vrfname) if not vrf_master_objs: # this is the case where vrf is assigned to an interface # but user has not provided a vrf interface. # people expect you to warn them but go ahead with the # rest of the config on that interface netlink.link_set_updown(ifacename, "up") self.log_error('vrf master ifaceobj %s not found' % 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))): self._up_vrf_slave_without_master(ifacename, vrfname, ifaceobj, vrf_master_objs, ifaceobj_getfunc) else: master_exists = False else: master_exists = False if master_exists: if not ifaceobj.link_privflags & ifaceLinkPrivFlags.KEEP_LINK_DOWN: netlink.link_set_updown(ifacename, "up") else: self.log_error( 'vrf %s not around, skipping vrf config' % (vrfname), ifaceobj) except Exception, e: self.log_error('%s: %s' % (ifacename, str(e)), ifaceobj)
def _up (self, ifaceobj): if self._get_batman_ifaces (ifaceobj) == None: raise Exception ('could not determine batman interfacaes') # Verify existance of batman interfaces (should be present already) batman_ifaces = [] for iface in self._get_batman_ifaces (ifaceobj): if not self.ipcmd.link_exists (iface): self.logger.warn ('batman iface %s not present' % iface) continue batman_ifaces.append (iface) if len (batman_ifaces) == 0: raise Exception ("None of the configured batman interfaces are available!") routing_algo = ifaceobj.get_attr_value_first ('batman-routing-algo') if routing_algo: self._set_routing_algo (routing_algo) if_ignore_re = self._get_batman_ifaces_ignore_regex (ifaceobj) # Is the batman main interface already present? if self.ipcmd.link_exists (ifaceobj.name): # Verify which member interfaces are present members = self._find_member_ifaces (ifaceobj) for iface in members: if iface not in batman_ifaces: self._batctl_if (ifaceobj.name, iface, 'del') for iface in batman_ifaces: if iface not in members: self._batctl_if (ifaceobj.name, iface, 'add') # Batman interfaces no present, add member interfaces to create it else: for iface in batman_ifaces: self._batctl_if (ifaceobj.name, iface, 'add') # Check/set any B.A.T.M.A.N. adv. set within interface configuration for attr in self._batman_attrs: value_cfg = self._get_batman_attr (ifaceobj, attr) if value_cfg and value_cfg != self._read_current_batman_attr (ifaceobj, attr): self._set_batman_attr (ifaceobj, attr, value_cfg) if ifaceobj.addr_method == 'manual': netlink.link_set_updown(ifaceobj.name, "up")
def create_or_set_bond_config(self, ifaceobj): ifname = ifaceobj.name link_exists = self.ipcmd.link_exists(ifname) is_link_up = self.ipcmd.is_link_up(ifname) if link_exists else False ifla_info_data = self.get_ifla_bond_attr_from_user_config(ifaceobj, link_exists) remove_delay_from_cache = self.check_updown_delay_nl(link_exists, ifaceobj, ifla_info_data) # if link exists: down link if specific attributes are specified if link_exists: # did bond-mode changed? is_link_up = self.should_update_bond_mode(ifaceobj, ifname, is_link_up, ifla_info_data) # if specific attributes need to be set we need to down the bond first if ifla_info_data and is_link_up: if self._should_down_bond(ifla_info_data): netlink.link_set_updown(ifname, 'down') is_link_up = False if link_exists and not ifla_info_data: # if the bond already exists and no attrs need to be set # ignore the netlink call self.logger.info('%s: already exists, no change detected' % ifname) else: try: netlink.link_add_set(kind='bond', ifname=ifname, ifla_info_data=ifla_info_data) except Exception as e: # defensive code # if anything happens, we try to set up the bond with the sysfs api self.logger.debug('%s: bond setup: %s' % (ifname, str(e))) self.create_or_set_bond_config_sysfs(ifaceobj, ifla_info_data) if remove_delay_from_cache: # making sure up/down delay attributes are set to 0 before caching # this can be removed when moving to a nllistener/live cache ifla_info_data[Link.IFLA_BOND_UPDELAY] = 0 ifla_info_data[Link.IFLA_BOND_DOWNDELAY] = 0 # if link_add doesn't raise we can update the cache, the future # netlink listener will update the cache based on the kernel response for key, value in ifla_info_data.items(): self.bondcmd.cache_update([ifname, 'linkinfo', key], value) if link_exists and ifla_info_data and not is_link_up: netlink.link_set_updown(ifname, 'up')
def _up_vrf_slave(self, ifacename, vrfname, ifaceobj=None, ifaceobj_getfunc=None, vrf_exists=False): try: master_exists = True if vrf_exists or self.ipcmd.link_exists(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) elif ifaceobj: vrf_master_objs = ifaceobj_getfunc(vrfname) if not vrf_master_objs: # this is the case where vrf is assigned to an interface # but user has not provided a vrf interface. # people expect you to warn them but go ahead with the # rest of the config on that interface netlink.link_set_updown(ifacename, "up") self.log_error('vrf master ifaceobj %s not found' %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))): self._up_vrf_slave_without_master(ifacename, vrfname, ifaceobj, vrf_master_objs, ifaceobj_getfunc) else: master_exists = False else: master_exists = False if master_exists: if not ifaceobj.link_privflags & ifaceLinkPrivFlags.KEEP_LINK_DOWN: netlink.link_set_updown(ifacename, "up") else: self.log_error('vrf %s not around, skipping vrf config' %(vrfname), ifaceobj) except Exception, e: self.log_error('%s: %s' %(ifacename, str(e)), ifaceobj)
def _add_slaves(self, ifaceobj, ifaceobj_getfunc=None): runningslaves = [] slaves = self._get_slave_list(ifaceobj) if not slaves: self.logger.debug('%s: no slaves found' % ifaceobj.name) return if not ifupdownflags.flags.PERFMODE: runningslaves = self.bondcmd.bond_get_slaves(ifaceobj.name) clag_bond = self._is_clag_bond(ifaceobj) for slave in Set(slaves).difference(Set(runningslaves)): if (not ifupdownflags.flags.PERFMODE and not self.ipcmd.link_exists(slave)): self.log_error('%s: skipping slave %s, does not exist' % (ifaceobj.name, slave), ifaceobj, raise_error=False) continue link_up = False if self.ipcmd.is_link_up(slave): netlink.link_set_updown(slave, "down") link_up = True # If clag bond place the slave in a protodown state; clagd # will protoup it when it is ready if clag_bond: try: netlink.link_set_protodown(slave, "on") except Exception, e: self.logger.error('%s: %s' % (ifaceobj.name, str(e))) netlink.link_set_master(slave, ifaceobj.name) if link_up or ifaceobj.link_type != ifaceLinkType.LINK_NA: try: if (ifaceobj_getfunc(slave)[0].link_privflags & ifaceLinkPrivFlags.KEEP_LINK_DOWN): netlink.link_set_updown(slave, "down") else: netlink.link_set_updown(slave, "up") except Exception, e: self.logger.debug('%s: %s' % (ifaceobj.name, str(e))) pass
def _add_slaves(self, ifaceobj, ifaceobj_getfunc=None): runningslaves = [] slaves = self._get_slave_list(ifaceobj) if not slaves: self.logger.debug('%s: no slaves found' %ifaceobj.name) return if not ifupdownflags.flags.PERFMODE: runningslaves = self.bondcmd.bond_get_slaves(ifaceobj.name) clag_bond = self._is_clag_bond(ifaceobj) for slave in Set(slaves).difference(Set(runningslaves)): if (not ifupdownflags.flags.PERFMODE and not self.ipcmd.link_exists(slave)): self.log_error('%s: skipping slave %s, does not exist' %(ifaceobj.name, slave), ifaceobj, raise_error=False) continue link_up = False if self.ipcmd.is_link_up(slave): netlink.link_set_updown(slave, "down") link_up = True # If clag bond place the slave in a protodown state; clagd # will protoup it when it is ready if clag_bond: try: netlink.link_set_protodown(slave, "on") except Exception, e: self.logger.error('%s: %s' % (ifaceobj.name, str(e))) netlink.link_set_master(slave, ifaceobj.name) if link_up or ifaceobj.link_type != ifaceLinkType.LINK_NA: try: if (ifaceobj_getfunc(slave)[0].link_privflags & ifaceLinkPrivFlags.KEEP_LINK_DOWN): netlink.link_set_updown(slave, "down") else: netlink.link_set_updown(slave, "up") except Exception, e: self.logger.debug('%s: %s' % (ifaceobj.name, str(e))) pass
continue sobj = None if ifaceobj_getfunc: sobj = ifaceobj_getfunc(s) self._down_vrf_slave(s, sobj[0] if sobj else None, ifaceobj.name) except Exception, e: self.logger.info('%s: %s' %(ifaceobj.name, str(e))) if ifaceobj.link_type == ifaceLinkType.LINK_MASTER: for s in config_slaves: try: for slave_ifaceobj in ifaceobj_getfunc(s) or []: if slave_ifaceobj.link_privflags & ifaceLinkPrivFlags.KEEP_LINK_DOWN: raise Exception("link-down yes: keeping VRF slave down") netlink.link_set_updown(s, "up") except Exception, e: self.logger.debug("%s: %s" % (s, str(e))) pass 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, 0) & vrfPrivFlags.PROCESSED): return True return False def _create_vrf_dev(self, ifaceobj, vrf_table):
def link_down(self, ifacename): netlink.link_set_updown(ifacename, "down")
def link_up(self, ifacename): netlink.link_set_updown(ifacename, "up")
for s in runningslaves: if s not in slaves: self.bondcmd.bond_remove_slave(ifaceobj.name, s) if clag_bond: try: netlink.link_set_protodown(s, "off") except Exception, e: self.logger.error('%s: %s' % (ifaceobj.name, str(e))) else: # apply link-down config changes on running slaves try: link_up = self.ipcmd.is_link_up(s) config_link_down = (ifaceobj_getfunc(s)[0].link_privflags & ifaceLinkPrivFlags.KEEP_LINK_DOWN) if (config_link_down and link_up): netlink.link_set_updown(s, "down") elif (not config_link_down and not link_up): netlink.link_set_updown(s, "up") except Exception, e: self.logger.warn('%s: %s' % (ifaceobj.name, str(e))) def _check_updown_delay_log(self, ifaceobj, attr_name, value): ifaceobj.status = ifaceStatus.ERROR self.logger.error('%s: unable to set %s %s as MII link monitoring is ' 'disabled' % (ifaceobj.name, attr_name, value)) # return False to notify syntax_check that an error has been logged return False def syntax_check_updown_delay(self, ifaceobj): result = True updelay = ifaceobj.get_attr_value_first('bond-updelay')
self.bondcmd.bond_remove_slave(ifaceobj.name, s) if clag_bond: try: netlink.link_set_protodown(s, "off") except Exception, e: self.logger.error('%s: %s' % (ifaceobj.name, str(e))) else: # apply link-down config changes on running slaves try: link_up = self.ipcmd.is_link_up(s) config_link_down = ( ifaceobj_getfunc(s)[0].link_privflags & ifaceLinkPrivFlags.KEEP_LINK_DOWN) if (config_link_down and link_up): netlink.link_set_updown(s, "down") elif (not config_link_down and not link_up): netlink.link_set_updown(s, "up") except Exception, e: self.logger.warn('%s: %s' % (ifaceobj.name, str(e))) def _check_updown_delay_log(self, ifaceobj, attr_name, value): ifaceobj.status = ifaceStatus.ERROR self.logger.error('%s: unable to set %s %s as MII link monitoring is ' 'disabled' % (ifaceobj.name, attr_name, value)) # return False to notify syntax_check that an error has been logged return False def syntax_check_updown_delay(self, ifaceobj): result = True updelay = ifaceobj.get_attr_value_first('bond-updelay')