diff --git a/debian/changelog b/debian/changelog index 88c60cb..89d9037 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ ifupdown2 (3.2.1) unstable; urgency=medium * New: Attribute: "disable-ipv6" to control ipv6 on an interface * New: Policy: "default_loopback_scope" control loopback ip scope + * Fix: keep link down after mac change if 'link-down yes' is specified -- Julien Fortin Thu, 04 May 2023 23:42:00 -0700 diff --git a/ifupdown2/addons/address.py b/ifupdown2/addons/address.py index d94bb3f..8e6e20b 100644 --- a/ifupdown2/addons/address.py +++ b/ifupdown2/addons/address.py @@ -1249,7 +1249,12 @@ class address(AddonWithIpBlackList, moduleBase): self.netlink.link_down(l) slave_down = True try: - self.netlink.link_set_address(ifaceobj.name, hwaddress, hwaddress_int) + self.netlink.link_set_address( + ifaceobj.name, + hwaddress, + hwaddress_int, + keep_link_down=ifaceobj.link_privflags & ifaceLinkPrivFlags.KEEP_LINK_DOWN + ) old_mac_addr = running_hwaddress finally: if slave_down: diff --git a/ifupdown2/lib/iproute2.py b/ifupdown2/lib/iproute2.py index cc2b859..543082e 100644 --- a/ifupdown2/lib/iproute2.py +++ b/ifupdown2/lib/iproute2.py @@ -217,14 +217,15 @@ class IPRoute2(Cache, Requirements): ### - def link_set_address(self, ifname, address): + def link_set_address(self, ifname, address, keep_link_down=False): if utils.mac_str_to_int(address) != self.cache.get_link_address_raw(ifname): self.link_down(ifname) self.__execute_or_batch( utils.ip_cmd, "link set dev %s address %s" % (ifname, address) ) - self.link_up(ifname) + if not keep_link_down: + self.link_up(ifname) def link_set_address_dry_run(self, ifname, address): self.link_down(ifname) diff --git a/ifupdown2/lib/nlcache.py b/ifupdown2/lib/nlcache.py index 0b1c6d2..bbd2a8b 100644 --- a/ifupdown2/lib/nlcache.py +++ b/ifupdown2/lib/nlcache.py @@ -2706,7 +2706,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject def link_set_address_dry_run(self, ifname, hw_address, hw_address_int): self.log_info_ifname_dry_run(ifname, "netlink: ip link set dev %s address %s" % (ifname, hw_address)) - def link_set_address(self, ifname, hw_address, hw_address_int): + def link_set_address(self, ifname, hw_address, hw_address_int, keep_link_down=False): is_link_up = self.cache.link_is_up(ifname) # check if the link is already up or not if the link is # up we need to down it then make sure we up it again @@ -2734,8 +2734,10 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject except Exception as e: raise NetlinkError(e, "cannot set dev %s address %s" % (ifname, hw_address), ifname=ifname) finally: - if is_link_up: + if is_link_up and not keep_link_down: self.link_up_force(ifname) + else: + self.logger.info(f"{ifname}: keeping link down") ###