From 4afb9b238f6b12a0bf6f46823b9ca9713ea209fd Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Wed, 21 Dec 2022 18:47:00 +0100 Subject: [PATCH 01/16] addons: bond: allow bond creation without slaves Signed-off-by: Julien Fortin --- ifupdown2/addons/bond.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ifupdown2/addons/bond.py b/ifupdown2/addons/bond.py index f6681f8..ce9b01a 100644 --- a/ifupdown2/addons/bond.py +++ b/ifupdown2/addons/bond.py @@ -290,7 +290,9 @@ class bond(Addon, moduleBase): def _is_bond(self, ifaceobj): # at first link_kind is not set but once ifupdownmain # calls get_dependent_ifacenames link_kind is set to BOND - return ifaceobj.link_kind & ifaceLinkKind.BOND or self.get_bond_slaves(ifaceobj) + return ifaceobj.link_kind & ifaceLinkKind.BOND \ + or ifaceobj.get_attr_value_first("bond-mode") \ + or self.get_bond_slaves(ifaceobj) def get_dependent_ifacenames(self, ifaceobj, ifacenames_all=None, old_ifaceobjs=False): """ Returns list of interfaces dependent on ifaceobj """ @@ -302,7 +304,7 @@ class bond(Addon, moduleBase): ifacenames_all) ifaceobj.dependency_type = ifaceDependencyType.MASTER_SLAVE # Also save a copy for future use - ifaceobj.priv_data = list(slave_list) + ifaceobj.priv_data = list(slave_list) if slave_list else [] if ifaceobj.link_type != ifaceLinkType.LINK_NA: ifaceobj.link_type = ifaceLinkType.LINK_MASTER ifaceobj.link_kind |= ifaceLinkKind.BOND -- 2.39.2 From 421e9573b56f7cc89119fba7269cffa54edcc74a Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Mon, 30 May 2022 19:13:05 +0200 Subject: [PATCH 02/16] SONAR: fix iface.py: Import only needed names or import the module and then use its members. Signed-off-by: Julien Fortin --- ifupdown2/addons/address.py | 4 ++-- ifupdown2/addons/addressvirtual.py | 4 ++-- ifupdown2/addons/bond.py | 5 +++-- ifupdown2/addons/bridge.py | 4 ++-- ifupdown2/addons/bridgevlan.py | 4 ++-- ifupdown2/addons/dhcp.py | 5 +++-- ifupdown2/addons/ethtool.py | 4 ++-- ifupdown2/addons/link.py | 4 ++-- ifupdown2/addons/mstpctl.py | 6 ++++-- ifupdown2/addons/vlan.py | 4 ++-- ifupdown2/addons/vrf.py | 4 ++-- ifupdown2/addons/vxlan.py | 4 ++-- ifupdown2/ifupdown/ifupdownmain.py | 4 ++-- ifupdown2/ifupdown/networkinterfaces.py | 4 ++-- ifupdown2/ifupdown/scheduler.py | 7 +++++-- ifupdown2/ifupdown/utils.py | 4 ++-- ifupdown2/ifupdownaddons/modulebase.py | 4 ++-- 17 files changed, 41 insertions(+), 34 deletions(-) diff --git a/ifupdown2/addons/address.py b/ifupdown2/addons/address.py index ac88a5e..feedfb8 100644 --- a/ifupdown2/addons/address.py +++ b/ifupdown2/addons/address.py @@ -15,7 +15,7 @@ try: from ifupdown2.lib.addon import AddonWithIpBlackList from ifupdown2.nlmanager.nlmanager import Link - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceType, ifaceLinkKind, ifaceLinkPrivFlags, ifaceStatus, iface from ifupdown2.ifupdown.utils import utils from ifupdown2.ifupdownaddons.dhclient import dhclient @@ -31,7 +31,7 @@ except (ImportError, ModuleNotFoundError): from lib.addon import AddonWithIpBlackList from nlmanager.nlmanager import Link - from ifupdown.iface import * + from ifupdown.iface import ifaceType, ifaceLinkKind, ifaceLinkPrivFlags, ifaceStatus, iface from ifupdown.utils import utils from ifupdownaddons.dhclient import dhclient diff --git a/ifupdown2/addons/addressvirtual.py b/ifupdown2/addons/addressvirtual.py index 3f7394d..de28555 100644 --- a/ifupdown2/addons/addressvirtual.py +++ b/ifupdown2/addons/addressvirtual.py @@ -13,7 +13,7 @@ from collections import deque try: from ifupdown2.lib.addon import AddonWithIpBlackList - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceType, ifaceLinkKind, ifaceLinkPrivFlags, ifaceStatus from ifupdown2.ifupdown.utils import utils from ifupdown2.nlmanager.nlpacket import Link @@ -28,7 +28,7 @@ try: import ifupdown2.ifupdown.ifupdownconfig as ifupdownconfig except (ImportError, ModuleNotFoundError): from lib.addon import AddonWithIpBlackList - from ifupdown.iface import * + from ifupdown.iface import ifaceType, ifaceLinkKind, ifaceLinkPrivFlags, ifaceStatus from ifupdown.utils import utils from nlmanager.nlpacket import Link diff --git a/ifupdown2/addons/bond.py b/ifupdown2/addons/bond.py index ce9b01a..50ca928 100644 --- a/ifupdown2/addons/bond.py +++ b/ifupdown2/addons/bond.py @@ -7,13 +7,14 @@ # import os +from collections import OrderedDict try: from ifupdown2.nlmanager.ipnetwork import IPv4Address from ifupdown2.lib.addon import Addon from ifupdown2.nlmanager.nlmanager import Link - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceRole, ifaceLinkKind, ifaceLinkPrivFlags, ifaceLinkType, ifaceDependencyType, ifaceStatus from ifupdown2.ifupdown.utils import utils from ifupdown2.ifupdown.statemanager import statemanager_api as statemanager @@ -26,7 +27,7 @@ except (ImportError, ModuleNotFoundError): from lib.addon import Addon from nlmanager.nlmanager import Link - from ifupdown.iface import * + from ifupdown.iface import ifaceRole, ifaceLinkKind, ifaceLinkPrivFlags, ifaceLinkType, ifaceDependencyType, ifaceStatus from ifupdown.utils import utils from ifupdown.statemanager import statemanager_api as statemanager diff --git a/ifupdown2/addons/bridge.py b/ifupdown2/addons/bridge.py index 753638e..3ce4142 100644 --- a/ifupdown2/addons/bridge.py +++ b/ifupdown2/addons/bridge.py @@ -19,7 +19,7 @@ try: from ifupdown2.nlmanager.nlmanager import Link - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceRole, ifaceLinkKind, ifaceLinkPrivFlags, ifaceLinkType, ifaceDependencyType, ifaceStatus, iface from ifupdown2.ifupdown.utils import utils from ifupdown2.ifupdownaddons.cache import * @@ -33,7 +33,7 @@ except (ImportError, ModuleNotFoundError): from nlmanager.nlmanager import Link - from ifupdown.iface import * + from ifupdown.iface import ifaceRole, ifaceLinkKind, ifaceLinkPrivFlags, ifaceLinkType, ifaceDependencyType, ifaceStatus, iface from ifupdown.utils import utils from ifupdownaddons.cache import * diff --git a/ifupdown2/addons/bridgevlan.py b/ifupdown2/addons/bridgevlan.py index d844de4..6b75dc3 100644 --- a/ifupdown2/addons/bridgevlan.py +++ b/ifupdown2/addons/bridgevlan.py @@ -7,7 +7,7 @@ try: from ifupdown2.lib.addon import Addon - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceType, ifaceLinkKind, ifaceStatus from ifupdown2.ifupdownaddons.modulebase import moduleBase @@ -15,7 +15,7 @@ try: except (ImportError, ModuleNotFoundError): from lib.addon import Addon - from ifupdown.iface import * + from ifupdown.iface import ifaceType, ifaceLinkKind, ifaceStatus from ifupdownaddons.modulebase import moduleBase diff --git a/ifupdown2/addons/dhcp.py b/ifupdown2/addons/dhcp.py index 4d1da1a..a5bf860 100644 --- a/ifupdown2/addons/dhcp.py +++ b/ifupdown2/addons/dhcp.py @@ -7,6 +7,7 @@ import re import time import socket +import logging try: from ifupdown2.lib.addon import Addon @@ -15,7 +16,7 @@ try: import ifupdown2.ifupdown.policymanager as policymanager import ifupdown2.ifupdown.ifupdownflags as ifupdownflags - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceLinkPrivFlags, ifaceStatus from ifupdown2.ifupdown.utils import utils from ifupdown2.ifupdownaddons.dhclient import dhclient @@ -27,7 +28,7 @@ except (ImportError, ModuleNotFoundError): import ifupdown.policymanager as policymanager import ifupdown.ifupdownflags as ifupdownflags - from ifupdown.iface import * + from ifupdown.iface import ifaceLinkPrivFlags, ifaceStatus from ifupdown.utils import utils from ifupdownaddons.dhclient import dhclient diff --git a/ifupdown2/addons/ethtool.py b/ifupdown2/addons/ethtool.py index 34369d9..2134329 100644 --- a/ifupdown2/addons/ethtool.py +++ b/ifupdown2/addons/ethtool.py @@ -13,7 +13,7 @@ try: import ifupdown2.ifupdown.policymanager as policymanager import ifupdown2.ifupdown.statemanager as statemanager - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceLinkPrivFlags from ifupdown2.ifupdown.utils import utils from ifupdown2.ifupdown.exceptions import moduleNotSupported @@ -26,7 +26,7 @@ except (ImportError, ModuleNotFoundError): import ifupdown.policymanager as policymanager import ifupdown.statemanager as statemanager - from ifupdown.iface import * + from ifupdown.iface import ifaceLinkPrivFlags from ifupdown.utils import utils from ifupdown.exceptions import moduleNotSupported diff --git a/ifupdown2/addons/link.py b/ifupdown2/addons/link.py index 74a4ef0..da2a3cc 100644 --- a/ifupdown2/addons/link.py +++ b/ifupdown2/addons/link.py @@ -11,7 +11,7 @@ try: from ifupdown2.lib.addon import Addon - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceLinkKind, ifaceLinkPrivFlags, ifaceStatus from ifupdown2.ifupdown.utils import utils from ifupdown2.ifupdownaddons.modulebase import moduleBase @@ -20,7 +20,7 @@ try: import ifupdown2.ifupdown.policymanager as policymanager except (ImportError, ModuleNotFoundError): from lib.addon import Addon - from ifupdown.iface import * + from ifupdown.iface import ifaceLinkKind, ifaceLinkPrivFlags, ifaceStatus from ifupdown.utils import utils from ifupdownaddons.modulebase import moduleBase diff --git a/ifupdown2/addons/mstpctl.py b/ifupdown2/addons/mstpctl.py index 82430a5..1853a4b 100644 --- a/ifupdown2/addons/mstpctl.py +++ b/ifupdown2/addons/mstpctl.py @@ -6,10 +6,12 @@ import os +from collections import OrderedDict + try: from ifupdown2.lib.addon import Addon - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceType, ifaceLinkKind, ifaceLinkPrivFlags, ifaceStatus from ifupdown2.ifupdown.utils import utils import ifupdown2.ifupdown.ifupdownflags as ifupdownflags @@ -22,7 +24,7 @@ try: except (ImportError, ModuleNotFoundError): from lib.addon import Addon - from ifupdown.iface import * + from ifupdown.iface import ifaceType, ifaceLinkKind, ifaceLinkPrivFlags, ifaceStatus from ifupdown.utils import utils import ifupdown.ifupdownflags as ifupdownflags diff --git a/ifupdown2/addons/vlan.py b/ifupdown2/addons/vlan.py index 06e87bb..4380dd8 100644 --- a/ifupdown2/addons/vlan.py +++ b/ifupdown2/addons/vlan.py @@ -6,7 +6,7 @@ try: from ifupdown2.lib.addon import Addon - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceType, ifaceLinkKind, ifaceStatus from ifupdown2.nlmanager.nlmanager import Link from ifupdown2.ifupdownaddons.modulebase import moduleBase from ifupdown2.ifupdown.utils import utils @@ -15,7 +15,7 @@ try: import ifupdown2.ifupdown.policymanager as policymanager except (ImportError, ModuleNotFoundError): from lib.addon import Addon - from ifupdown.iface import * + from ifupdown.iface import ifaceType, ifaceLinkKind, ifaceStatus from nlmanager.nlmanager import Link from ifupdownaddons.modulebase import moduleBase from ifupdown.utils import utils diff --git a/ifupdown2/addons/vrf.py b/ifupdown2/addons/vrf.py index 637281f..f0ee503 100644 --- a/ifupdown2/addons/vrf.py +++ b/ifupdown2/addons/vrf.py @@ -17,7 +17,7 @@ try: import ifupdown2.ifupdown.ifupdownflags as ifupdownflags from ifupdown2.ifupdown.statemanager import statemanager_api as statemanager - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceRole, ifaceLinkKind, ifaceLinkPrivFlags, ifaceLinkType from ifupdown2.ifupdown.utils import utils from ifupdown2.nlmanager.nlmanager import Link @@ -32,7 +32,7 @@ except (ImportError, ModuleNotFoundError): import ifupdown.ifupdownflags as ifupdownflags from ifupdown.statemanager import statemanager_api as statemanager - from ifupdown.iface import * + from ifupdown.iface import ifaceRole, ifaceLinkKind, ifaceLinkPrivFlags, ifaceLinkType from ifupdown.utils import utils from nlmanager.nlmanager import Link diff --git a/ifupdown2/addons/vxlan.py b/ifupdown2/addons/vxlan.py index 11cc75e..54738ef 100644 --- a/ifupdown2/addons/vxlan.py +++ b/ifupdown2/addons/vxlan.py @@ -15,7 +15,7 @@ try: from ifupdown2.nlmanager.nlmanager import Link - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceLinkKind, ifaceLinkPrivFlags, ifaceStatus, iface from ifupdown2.ifupdown.utils import utils from ifupdown2.ifupdown.statemanager import statemanager_api as statemanager from ifupdown2.ifupdownaddons.cache import * @@ -31,7 +31,7 @@ except (ImportError, ModuleNotFoundError): from nlmanager.nlmanager import Link - from ifupdown.iface import * + from ifupdown.iface import ifaceLinkKind, ifaceLinkPrivFlags, ifaceStatus, iface from ifupdown.utils import utils from ifupdown.statemanager import statemanager_api as statemanager diff --git a/ifupdown2/ifupdown/ifupdownmain.py b/ifupdown2/ifupdown/ifupdownmain.py index 9b787ed..a0b19fa 100644 --- a/ifupdown2/ifupdown/ifupdownmain.py +++ b/ifupdown2/ifupdown/ifupdownmain.py @@ -29,7 +29,7 @@ try: import ifupdown2.ifupdown.ifupdownconfig as ifupdownConfig from ifupdown2.ifupdown.graph import * - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceStatusUserStrs, ifaceType, ifaceRole, ifaceLinkKind, ifaceLinkPrivFlags, ifaceLinkType, ifaceDependencyType, ifaceStatus, iface from ifupdown2.ifupdown.scheduler import * from ifupdown2.ifupdown.exceptions import * from ifupdown2.ifupdown.networkinterfaces import * @@ -48,7 +48,7 @@ except (ImportError, ModuleNotFoundError): import ifupdown.ifupdownconfig as ifupdownConfig from ifupdown.graph import * - from ifupdown.iface import * + from ifupdown.iface import ifaceStatusUserStrs, ifaceType, ifaceRole, ifaceLinkKind, ifaceLinkPrivFlags, ifaceLinkType, ifaceDependencyType, ifaceStatus, iface from ifupdown.scheduler import * from ifupdown.exceptions import * from ifupdown.networkinterfaces import * diff --git a/ifupdown2/ifupdown/networkinterfaces.py b/ifupdown2/ifupdown/networkinterfaces.py index c49e68b..ea38a3b 100644 --- a/ifupdown2/ifupdown/networkinterfaces.py +++ b/ifupdown2/ifupdown/networkinterfaces.py @@ -15,11 +15,11 @@ import os import re try: - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceType, ifaceJsonDecoder, iface from ifupdown2.ifupdown.utils import utils from ifupdown2.ifupdown.template import templateEngine except (ImportError, ModuleNotFoundError): - from ifupdown.iface import * + from ifupdown.iface import ifaceType, ifaceJsonDecoder, iface from ifupdown.utils import utils from ifupdown.template import templateEngine diff --git a/ifupdown2/ifupdown/scheduler.py b/ifupdown2/ifupdown/scheduler.py index 8b3c087..154e557 100644 --- a/ifupdown2/ifupdown/scheduler.py +++ b/ifupdown2/ifupdown/scheduler.py @@ -10,9 +10,12 @@ import os import sys +from collections import OrderedDict + + try: from ifupdown2.ifupdown.graph import * - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceType, ifaceLinkKind, ifaceStatus, ifaceState from ifupdown2.ifupdown.utils import utils from ifupdown2.ifupdown.statemanager import * @@ -20,7 +23,7 @@ try: import ifupdown2.ifupdown.ifupdownflags as ifupdownflags except (ImportError, ModuleNotFoundError): from ifupdown.graph import * - from ifupdown.iface import * + from ifupdown.iface import ifaceType, ifaceLinkKind, ifaceStatus, ifaceState from ifupdown.utils import utils from ifupdown.statemanager import * diff --git a/ifupdown2/ifupdown/utils.py b/ifupdown2/ifupdown/utils.py index a474ed8..05c7e48 100644 --- a/ifupdown2/ifupdown/utils.py +++ b/ifupdown2/ifupdown/utils.py @@ -20,12 +20,12 @@ from functools import partial from ipaddress import IPv4Address try: - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceRole, ifaceLinkKind, ifaceLinkPrivFlags import ifupdown2.ifupdown.policymanager as policymanager import ifupdown2.ifupdown.ifupdownflags as ifupdownflags except (ImportError, ModuleNotFoundError): - from ifupdown.iface import * + from ifupdown.iface import ifaceRole, ifaceLinkKind, ifaceLinkPrivFlags import ifupdown.policymanager as policymanager import ifupdown.ifupdownflags as ifupdownflags diff --git a/ifupdown2/ifupdownaddons/modulebase.py b/ifupdown2/ifupdownaddons/modulebase.py index 5f1ecfc..2ec8b7e 100644 --- a/ifupdown2/ifupdownaddons/modulebase.py +++ b/ifupdown2/ifupdownaddons/modulebase.py @@ -11,14 +11,14 @@ import traceback from functools import reduce try: - from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.iface import ifaceStatus from ifupdown2.ifupdown.utils import utils import ifupdown2.ifupdown.exceptions as exceptions import ifupdown2.ifupdown.policymanager as policymanager import ifupdown2.ifupdown.ifupdownflags as ifupdownflags except (ImportError, ModuleNotFoundError): - from ifupdown.iface import * + from ifupdown.iface import ifaceStatus from ifupdown.utils import utils import ifupdown.exceptions as exceptions -- 2.39.2 From 921757c3909cc68259aefad65165725fa1cfdec1 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Wed, 3 May 2023 16:35:28 +0200 Subject: [PATCH 03/16] addons: bond: make sure bond speed and slaves (swps) speed are matching Signed-off-by: Julien Fortin --- ifupdown2/addons/bond.py | 61 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/ifupdown2/addons/bond.py b/ifupdown2/addons/bond.py index 50ca928..d3dab14 100644 --- a/ifupdown2/addons/bond.py +++ b/ifupdown2/addons/bond.py @@ -6,7 +6,9 @@ # Julien Fortin, julien@cumulusnetworks.com # +import re import os + from collections import OrderedDict try: @@ -284,6 +286,9 @@ class bond(Addon, moduleBase): True ) + self.current_bond_speed = -1 + self.speed_pattern = re.compile(r"Speed: (\d+)") + def get_bond_slaves(self, ifaceobj): # bond-ports aliases should be translated to bond-slaves return ifaceobj.get_attr_value_first('bond-slaves') @@ -353,7 +358,58 @@ class bond(Addon, moduleBase): return True return False + def compare_bond_and_slave_speed(self, bond_ifaceobj, slave_ifname, slave_speed): + if self.current_bond_speed != slave_speed: + self.log_error( + "%s: ignoring device to due device's speed (%s) mismatching bond (%s) speed (%s)" + % (slave_ifname, slave_speed, bond_ifaceobj.name, self.current_bond_speed), + ifaceobj=bond_ifaceobj + ) + + def valid_slave_speed(self, ifaceobj, bond_slaves, slave): + if not slave.startswith("swp"): + # lazy optimization: only check "swp" interfaces + return True + + if self.current_bond_speed < 0: + self.current_bond_speed = self.get_bond_speed(bond_slaves) + + if self.current_bond_speed < 0: + # if we can't get the speed of the bond there's probably no ports enslaved + return True + + try: + self.compare_bond_and_slave_speed(ifaceobj, slave, int(self.read_file_oneline(f"/sys/class/net/{slave}/speed"))) + except: + try: + match = self.speed_pattern.search(utils.exec_commandl(["/usr/sbin/ethtool", f"{slave}"])) + if match: + self.compare_bond_and_slave_speed(ifaceobj, slave, int(match.group(1))) + except ValueError as e: + # if we can't manage to extract the speed, it's not a big deal lets continue + pass + # validate if we are unable to get a speed (logical interface?) + return True + + def get_bond_speed(self, runningslaves): + # check bond slave speed + bond_speed = -1 + for slave in runningslaves: + if not slave.startswith("swp"): + continue + try: + slave_speed = int(self.read_file_oneline(f"/sys/class/net/{slave}/speed")) + except: + slave_speed = -1 + + if bond_speed < 0: + bond_speed = slave_speed + return bond_speed + def _add_slaves(self, ifaceobj, runningslaves, ifaceobj_getfunc=None): + # reset the current_bond_speed + self.current_bond_speed = -1 + slaves = self._get_slave_list(ifaceobj) if not slaves: self.logger.debug('%s: no slaves found' %ifaceobj.name) @@ -374,6 +430,11 @@ class bond(Addon, moduleBase): %(ifaceobj.name, slave), ifaceobj, raise_error=False) continue + + # making sure the slave-to-be has the right speed + if not self.valid_slave_speed(ifaceobj, runningslaves, slave): + continue + link_up = False if self.cache.link_is_up(slave): self.netlink.link_down_force(slave) -- 2.39.2 From 81348c326631e11df56373628e8d56c17216ad45 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Wed, 3 May 2023 16:37:51 +0200 Subject: [PATCH 04/16] addons: bond: ignore exception raised during bond-slave speed check Signed-off-by: Julien Fortin --- ifupdown2/addons/bond.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ifupdown2/addons/bond.py b/ifupdown2/addons/bond.py index d3dab14..5a47b06 100644 --- a/ifupdown2/addons/bond.py +++ b/ifupdown2/addons/bond.py @@ -431,9 +431,12 @@ class bond(Addon, moduleBase): raise_error=False) continue - # making sure the slave-to-be has the right speed - if not self.valid_slave_speed(ifaceobj, runningslaves, slave): - continue + try: + # making sure the slave-to-be has the right speed + if not self.valid_slave_speed(ifaceobj, runningslaves, slave): + continue + except Exception as e: + self.logger.debug("%s: bond-slave (%s) speed validation failed: %s" % (ifaceobj.name, slave, str(e))) link_up = False if self.cache.link_is_up(slave): -- 2.39.2 From 530e3a0b79c85fff416d2263a82885c7bb6b2ed3 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Mon, 30 May 2022 22:47:58 +0200 Subject: [PATCH 05/16] SONAR: addons: bond: Merge if statements with the enclosing ones Signed-off-by: Julien Fortin --- ifupdown2/addons/bond.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/ifupdown2/addons/bond.py b/ifupdown2/addons/bond.py index 5a47b06..24f0103 100644 --- a/ifupdown2/addons/bond.py +++ b/ifupdown2/addons/bond.py @@ -688,11 +688,10 @@ class bond(Addon, moduleBase): 'probably not supported on this system' % (ifname, attr_name, user_config)) continue - elif link_exists: + elif link_exists and cached_value == nl_value: # there should be a cached value if the link already exists - if cached_value == nl_value: - # if the user value is already cached: continue - continue + # if the user value is already cached: continue + continue # else: the link doesn't exist so we create the bond with # all the user/policy defined values without extra checks @@ -836,10 +835,9 @@ class bond(Addon, moduleBase): ) # 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): - self.netlink.link_down_force(ifname) - is_link_up = False + if ifla_info_data and is_link_up and self._should_down_bond(ifla_info_data): + self.netlink.link_down_force(ifname) + is_link_up = False else: bond_slaves = [] @@ -938,9 +936,8 @@ class bond(Addon, moduleBase): def _query_check_bond_slaves(self, ifaceobjcurr, attr, user_bond_slaves, running_bond_slaves): query = 1 - if user_bond_slaves and running_bond_slaves: - if not set(user_bond_slaves).symmetric_difference(running_bond_slaves): - query = 0 + if user_bond_slaves and running_bond_slaves and not set(user_bond_slaves).symmetric_difference(running_bond_slaves): + query = 0 # we want to display the same bond-slaves list as provided # in the interfaces file but if this list contains regexes or -- 2.39.2 From 75dea8b906d4a5c30d6bce269f38360f35b08a84 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Wed, 3 May 2023 16:40:09 +0200 Subject: [PATCH 06/16] addons: bond: set protodown off on bond slave before bond is deleted Signed-off-by: Julien Fortin --- ifupdown2/addons/bond.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ifupdown2/addons/bond.py b/ifupdown2/addons/bond.py index 24f0103..57f3c79 100644 --- a/ifupdown2/addons/bond.py +++ b/ifupdown2/addons/bond.py @@ -10,6 +10,7 @@ import re import os from collections import OrderedDict +from contextlib import suppress try: from ifupdown2.nlmanager.ipnetwork import IPv4Address @@ -928,11 +929,22 @@ class bond(Addon, moduleBase): self.log_error(str(e), ifaceobj) def _down(self, ifaceobj, ifaceobj_getfunc=None): + bond_slaves = self.cache.get_slaves(ifaceobj.name) + try: self.netlink.link_del(ifaceobj.name) except Exception as e: self.log_warn('%s: %s' % (ifaceobj.name, str(e))) + # set protodown (and reason) off bond slaves + for slave in bond_slaves: + with suppress(Exception): + self.iproute2.link_set_protodown_reason_clag_off(slave) + with suppress(Exception): + self.iproute2.link_set_protodown_reason_frr_off(slave) + with suppress(Exception): + self.netlink.link_set_protodown_off(slave) + def _query_check_bond_slaves(self, ifaceobjcurr, attr, user_bond_slaves, running_bond_slaves): query = 1 -- 2.39.2 From a0ff28e527718b037b4b845f88d8ddd619b5d445 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Tue, 14 Feb 2023 13:40:32 +0100 Subject: [PATCH 07/16] sonarlink: remove unused variable Signed-off-by: Julien Fortin --- ifupdown2/addons/bond.py | 2 +- ifupdown2/addons/bridge.py | 2 +- ifupdown2/addons/vxlan.py | 1 - ifupdown2/ifupdown/iface.py | 2 +- ifupdown2/ifupdown/networkinterfaces.py | 2 +- ifupdown2/lib/nlcache.py | 2 +- ifupdown2/lib/sysfs.py | 2 +- 7 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ifupdown2/addons/bond.py b/ifupdown2/addons/bond.py index 57f3c79..74d2cab 100644 --- a/ifupdown2/addons/bond.py +++ b/ifupdown2/addons/bond.py @@ -386,7 +386,7 @@ class bond(Addon, moduleBase): match = self.speed_pattern.search(utils.exec_commandl(["/usr/sbin/ethtool", f"{slave}"])) if match: self.compare_bond_and_slave_speed(ifaceobj, slave, int(match.group(1))) - except ValueError as e: + except ValueError: # if we can't manage to extract the speed, it's not a big deal lets continue pass # validate if we are unable to get a speed (logical interface?) diff --git a/ifupdown2/addons/bridge.py b/ifupdown2/addons/bridge.py index 3ce4142..954e462 100644 --- a/ifupdown2/addons/bridge.py +++ b/ifupdown2/addons/bridge.py @@ -897,7 +897,7 @@ class bridge(Bridge, moduleBase): c3 = self.syntax_check_learning_l2_vni_evpn(ifaceobj) c4 = self.syntax_check_bridge_arp_vni_vlan(ifaceobj, ifaceobj_getfunc) c5 = self.syntax_check_bridge_vni_svi_limit(ifaceobj, ifaceobj_getfunc) - return retval and c1 and c3 and c4 and c5#and c2 + return retval and c1 and c2 and c3 and c4 and c5 def syntax_check_bridge_vni_svi_limit(self, ifaceobj, ifaceobj_getfunc): if self.bridge_vni_per_svi_limit > 0 and ifaceobj.link_kind & ifaceLinkKind.VXLAN: diff --git a/ifupdown2/addons/vxlan.py b/ifupdown2/addons/vxlan.py index 54738ef..084aec9 100644 --- a/ifupdown2/addons/vxlan.py +++ b/ifupdown2/addons/vxlan.py @@ -1028,7 +1028,6 @@ class vxlan(Vxlan, moduleBase): return parsed_maps def single_vxlan_device_vni_filter(self, ifaceobj, vxlan_mcast_grp): - vnis = [] vnisd = {} for vlan_vni_map in ifaceobj.get_attr_value("bridge-vlan-vni-map"): try: diff --git a/ifupdown2/ifupdown/iface.py b/ifupdown2/ifupdown/iface.py index 07b075f..07bd067 100644 --- a/ifupdown2/ifupdown/iface.py +++ b/ifupdown2/ifupdown/iface.py @@ -310,7 +310,7 @@ class ifaceJsonEncoderWithStatus(json.JSONEncoder): for k,v in list(o.config.items()): idx = 0 vitem_status = [] - for vitem in v: + for _ in v: s = o.get_config_attr_status(k, idx) if s == 1: status_str = ifaceStatusUserStrs.ERROR diff --git a/ifupdown2/ifupdown/networkinterfaces.py b/ifupdown2/ifupdown/networkinterfaces.py index ea38a3b..2bebe39 100644 --- a/ifupdown2/ifupdown/networkinterfaces.py +++ b/ifupdown2/ifupdown/networkinterfaces.py @@ -247,7 +247,7 @@ class networkInterfaces(): addrlist = iface_config.get('address') if addrlist: # find the index of last address element - for i in range(0, len(addrlist) - len(attrvallist) -1): + for _ in range(0, len(addrlist) - len(attrvallist) -1): attrvallist.append('') attrvallist.append(attrval) iface_config[newattrname] = attrvallist diff --git a/ifupdown2/lib/nlcache.py b/ifupdown2/lib/nlcache.py index b2a3e72..0b7cedb 100644 --- a/ifupdown2/lib/nlcache.py +++ b/ifupdown2/lib/nlcache.py @@ -2472,7 +2472,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject }) link.build_message(next(self.sequence), self.pid) return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link) - except Exception as e: + except Exception: raise Exception("%s: cannot create link %s type %s" % (ifname, ifname, kind)) def link_add_with_attributes_dry_run(self, ifname, kind, ifla): diff --git a/ifupdown2/lib/sysfs.py b/ifupdown2/lib/sysfs.py index 6478cad..dd9f361 100644 --- a/ifupdown2/lib/sysfs.py +++ b/ifupdown2/lib/sysfs.py @@ -177,7 +177,7 @@ class __Sysfs(IO, Requirements): vlan_id, ip = line.split('=') mcqv4src[vlan_id] = ip.strip() return mcqv4src - except Exception as e: + except Exception: self.logger.info("%s showmcqv4src: skipping unsupported command" % utils.brctl_cmd) self.bridge_get_mcqv4src = self.bridge_get_mcqv4src_dry_run return {} -- 2.39.2 From e5e64b25fef606c3e84dae1728ed99ef979ac43a Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Tue, 31 May 2022 15:39:21 +0200 Subject: [PATCH 08/16] SONAR: mstpctl: Merge if statement with the enclosing one Signed-off-by: Julien Fortin --- ifupdown2/addons/mstpctl.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/ifupdown2/addons/mstpctl.py b/ifupdown2/addons/mstpctl.py index 1853a4b..ff44eab 100644 --- a/ifupdown2/addons/mstpctl.py +++ b/ifupdown2/addons/mstpctl.py @@ -323,14 +323,16 @@ class mstpctl(Addon, moduleBase): ) def syntax_check(self, ifaceobj, ifaceobj_getfunc): - if self._is_bridge(ifaceobj): - if (ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_VLAN_AWARE - and ifaceobj.get_attr_value_first('mstpctl-portadminedge')): - self.logger.error('%s: unsupported use of keyword ' - '\'mstpctl-portadminedge\' when ' - 'bridge-vlan-aware is on' - % ifaceobj.name) - return False + if ( + self._is_bridge(ifaceobj) + and ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_VLAN_AWARE + and ifaceobj.get_attr_value_first('mstpctl-portadminedge') + ): + self.logger.error("%s: unsupported use of keyword " + "\'mstpctl-portadminedge\' when " + "bridge-vlan-aware is on" + % ifaceobj.name) + return False return True def _is_bridge(self, ifaceobj): -- 2.39.2 From aa656ad315767a0c18b40f045d0c68cd940c2f0a Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Fri, 12 Aug 2022 15:58:02 +0200 Subject: [PATCH 09/16] lib: nlcache: merge existing MTU into new netlink object before caching Signed-off-by: Julien Fortin --- ifupdown2/lib/nlcache.py | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/ifupdown2/lib/nlcache.py b/ifupdown2/lib/nlcache.py index 0b7cedb..d94ad7a 100644 --- a/ifupdown2/lib/nlcache.py +++ b/ifupdown2/lib/nlcache.py @@ -2278,7 +2278,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject raise Exception(error_str) - def tx_nlpacket_get_response_with_error_and_cache_on_ack(self, packet): + def tx_nlpacket_get_response_with_error_and_cache_on_ack(self, packet, ifname=None): """ TX packet and manually cache the object """ @@ -2302,6 +2302,33 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject # we can ignore all errors pass + try: + # We might be pre-caching an updated object that is "incomplete". + # i.e. say you have an existing bond in the cache, on ifreload only + # one attribute is updated. Our object 'packet' here will only have + # a couple attributes (but overriding a 'full' object in the cache). + # We need to somehow 'merge' some of the attributes that are not + # updated, otherwise later calls to the cache might return None for + # the missing attributes. MTU is a prime example. + if ifname: + # To minimize the changes each parent function can decide to + # trigger this 'merge' code by provided the optional 'ifname' arg + + # MERGING MTU: + # First check if we are not already setting MTU in this packet + try: + packet_mtu = packet.attributes[Link.IFLA_MTU].value + except Exception: + packet_mtu = None + # Then update 'packet' before caching + if not packet_mtu: + old_packet_mtu = self.cache.get_link_attribute(ifname, Link.IFLA_MTU) + if old_packet_mtu: + packet.add_attribute(Link.IFLA_MTU, old_packet_mtu) + except Exception: + # we can ignore all errors + pass + # Then we can use our normal "add_link" API call to cache the packet # and fill up our additional internal data structures. self.cache.add_link(packet) @@ -3060,7 +3087,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject Link.IFLA_INFO_DATA: ifla_info_data }) link.build_message(next(self.sequence), self.pid) - return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link) + return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link, ifname=ifname) except Exception as e: raise Exception("%s: netlink: cannot create bond with attributes: %s" % (ifname, str(e))) -- 2.39.2 From 86bd267c636da23f018842fb6373ee1da40046f1 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Tue, 20 Sep 2022 02:29:10 +0200 Subject: [PATCH 10/16] addons: address: process hwaddress before processing ip addresses Signed-off-by: Julien Fortin --- ifupdown2/addons/address.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ifupdown2/addons/address.py b/ifupdown2/addons/address.py index feedfb8..75c5d0e 100644 --- a/ifupdown2/addons/address.py +++ b/ifupdown2/addons/address.py @@ -1079,6 +1079,11 @@ class address(AddonWithIpBlackList, moduleBase): self.process_mtu(ifaceobj, ifaceobj_getfunc) self.up_ipv6_addrgen(ifaceobj) + try: + hwaddress, old_mac_addr = self.process_hwaddress(ifaceobj) + except Exception as e: + self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj) + if addr_method not in ["dhcp", "ppp"]: self.process_addresses(ifaceobj, ifaceobj_getfunc, force_reapply) else: @@ -1091,7 +1096,7 @@ class address(AddonWithIpBlackList, moduleBase): try: # Handle special things on a bridge - self._process_bridge(ifaceobj, True, *self.process_hwaddress(ifaceobj)) + self._process_bridge(ifaceobj, True, hwaddress, old_mac_addr) except Exception as e: self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj) -- 2.39.2 From 2a53e1383dba36c57d8903f87c7738e11916a250 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Fri, 31 Mar 2023 15:59:42 +0200 Subject: [PATCH 11/16] ifupdownmain: down ops on vrf-slave should set the slave admin down Signed-off-by: Julien Fortin --- ifupdown2/ifupdown/ifupdownmain.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ifupdown2/ifupdown/ifupdownmain.py b/ifupdown2/ifupdown/ifupdownmain.py index a0b19fa..a4d698b 100644 --- a/ifupdown2/ifupdown/ifupdownmain.py +++ b/ifupdown2/ifupdown/ifupdownmain.py @@ -134,8 +134,10 @@ class ifupdownMain: return False def run_down(self, ifaceobj): - if ((ifaceobj.link_kind & ifaceLinkKind.VRF) or - (ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE)): + if ifaceobj.link_kind & ifaceLinkKind.VRF: + return + elif ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE: + self.netlink.link_down(ifaceobj.name) return # Skip link sets on ifaceobjs of type 'vlan' (used for l2 attrs) # there is no real interface behind it -- 2.39.2 From a5db158bc1607fc533ea0cc4511eea760d58059c Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Fri, 16 Dec 2022 15:59:18 +0100 Subject: [PATCH 12/16] ifupdownmain: skipping admin down on deleted vlans Signed-off-by: Julien Fortin --- ifupdown2/ifupdown/ifupdownmain.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ifupdown2/ifupdown/ifupdownmain.py b/ifupdown2/ifupdown/ifupdownmain.py index a4d698b..51f5460 100644 --- a/ifupdown2/ifupdown/ifupdownmain.py +++ b/ifupdown2/ifupdown/ifupdownmain.py @@ -155,6 +155,12 @@ class ifupdownMain: if not self.link_exists(ifaceobj.name): return try: + # special case for some logical interfaces: + # - downed VLANs will be deleted via netlink no need to set them admin DOWN + if ifaceobj.link_kind & ifaceLinkKind.VLAN: + self.logger.debug("%s: skipping admin down (vlan will be deleted)" % ifaceobj.name) + return + if not ifaceobj.link_privflags & ifaceLinkPrivFlags.LOOPBACK: # set intf down (except loopback) self.netlink.link_down(ifaceobj.name) -- 2.39.2 From 928186191c79c4c3e6efa49d2d821896449ea074 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Mon, 15 Aug 2022 18:33:05 +0200 Subject: [PATCH 13/16] nlcache: merge existing MTU into new netlink object (vlan/vxlan) before caching This patch fixes the gap in the vlan and vxlan code Signed-off-by: Julien Fortin --- ifupdown2/lib/nlcache.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ifupdown2/lib/nlcache.py b/ifupdown2/lib/nlcache.py index d94ad7a..32ff44e 100644 --- a/ifupdown2/lib/nlcache.py +++ b/ifupdown2/lib/nlcache.py @@ -2955,7 +2955,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject Link.IFLA_INFO_DATA: ifla_info_data }) link.build_message(next(self.sequence), self.pid) - return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link) + return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link, ifname) except Exception as e: if "Invalid argument" in str(e) and bridge_binding is not None: raise RetryCMD(cmd=" ".join(vlan_iproute2_cmd)) @@ -3052,7 +3052,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject Link.IFLA_INFO_DATA: info_data }) link.build_message(next(self.sequence), self.pid) - return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link) + return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link, ifname) def link_add_vxlan_with_info_data_dry_run(self, ifname, info_data): self.log_info_ifname_dry_run( -- 2.39.2 From c8bda7739d609fb5211be0241f8fc982a78627c4 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Mon, 24 Oct 2022 22:21:07 +0200 Subject: [PATCH 14/16] nlcache: remove special SIGINT handling capturing sigint was causing ifquery to hang indefinitely on ctrl-c Signed-off-by: Julien Fortin --- ifupdown2/lib/nlcache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ifupdown2/lib/nlcache.py b/ifupdown2/lib/nlcache.py index 32ff44e..0b1c6d2 100644 --- a/ifupdown2/lib/nlcache.py +++ b/ifupdown2/lib/nlcache.py @@ -2020,7 +2020,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject BaseObject.__init__(self) signal.signal(signal.SIGTERM, self.signal_term_handler) - signal.signal(signal.SIGINT, self.signal_int_handler) + #signal.signal(signal.SIGINT, self.signal_int_handler) self.cache = _NetlinkCache() -- 2.39.2 From 909ff395541ae61f6ed557813703d4496f13ce60 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Thu, 4 May 2023 13:18:09 +0200 Subject: [PATCH 15/16] debian: changelog: new entry: 3.2.0 * Fix: Sonarqube issues * Fix: ifquery hangs indefinitely on ^C * Fix: Skipping admin down on deleted vlans * Fix: Merge existing MTU into new netlink object * Fix: scheduler: env variable not properly set for user commands (fixes #218) * Fix: ifquery-check: vlan-protocol for dotted interfaces * Fix: Down ops on vrf-slave should set the slave admin down * New: Allow bond creation without slaves * New: Add `--set-ring` option to ethtool * New: Openvswitch : add support for fakebridge * New: add support for systemd logging (--systemd) * New: Process hwaddress before processing ip addresses * New: Set protodown off on bond slave before bond is deleted * New: Make sure bond speed and slaves (swps) speed are matching Signed-off-by: Julien Fortin --- debian/changelog | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/debian/changelog b/debian/changelog index 3614117..93b3298 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,22 @@ +ifupdown2 (3.2.0) unstable; urgency=medium + + * Fix: Sonarqube issues + * Fix: ifquery hangs indefinitely on ^C + * Fix: Skipping admin down on deleted vlans + * Fix: Merge existing MTU into new netlink object + * Fix: scheduler: env variable not properly set for user commands (fixes #218) + * Fix: ifquery-check: vlan-protocol for dotted interfaces + * Fix: Down ops on vrf-slave should set the slave admin down + * New: Allow bond creation without slaves + * New: Add `--set-ring` option to ethtool + * New: Openvswitch : add support for fakebridge + * New: add support for systemd logging (--systemd) + * New: Process hwaddress before processing ip addresses + * New: Set protodown off on bond slave before bond is deleted + * New: Make sure bond speed and slaves (swps) speed are matching + + -- Julien Fortin Thu, 04 May 2023 23:42:00 -0700 + ifupdown2 (3.1.0-1) unstable; urgency=medium * New: ifquery-check now validates admin state -- 2.39.2 From a0522546b848435115a20eb647f87ade01761a33 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Wed, 10 May 2023 17:30:27 +0200 Subject: [PATCH 16/16] addons: address: fix merge-indentation issue Signed-off-by: Julien Fortin --- ifupdown2/addons/address.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ifupdown2/addons/address.py b/ifupdown2/addons/address.py index 75c5d0e..e71a26f 100644 --- a/ifupdown2/addons/address.py +++ b/ifupdown2/addons/address.py @@ -1079,9 +1079,9 @@ class address(AddonWithIpBlackList, moduleBase): self.process_mtu(ifaceobj, ifaceobj_getfunc) self.up_ipv6_addrgen(ifaceobj) - try: + try: hwaddress, old_mac_addr = self.process_hwaddress(ifaceobj) - except Exception as e: + except Exception as e: self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj) if addr_method not in ["dhcp", "ppp"]: -- 2.39.2