This especially takes care of all places where the sysfs is used, which
only works with primary interface names.

Signed-off-by: Christoph Heiss <c.he...@proxmox.com>
---
 ...-add-transparent-support-interface-a.patch | 246 +++++++++++++++++-
 1 file changed, 239 insertions(+), 7 deletions(-)

diff --git 
a/debian/patches/pve/0011-nlmanager-addons-add-transparent-support-interface-a.patch
 
b/debian/patches/pve/0011-nlmanager-addons-add-transparent-support-interface-a.patch
index fe2b197..27f0d79 100644
--- 
a/debian/patches/pve/0011-nlmanager-addons-add-transparent-support-interface-a.patch
+++ 
b/debian/patches/pve/0011-nlmanager-addons-add-transparent-support-interface-a.patch
@@ -1,4 +1,4 @@
-From ca818a46bc5519adde981df317ac635e064eae45 Mon Sep 17 00:00:00 2001
+From f1084be759217d35a624664de23fecf8ec0c7f44 Mon Sep 17 00:00:00 2001
 From: Christoph Heiss <c.he...@proxmox.com>
 Date: Fri, 11 Jul 2025 17:45:47 +0200
 Subject: [PATCH] nlmanager, addons: add transparent support interface altnames
@@ -18,21 +18,27 @@ name(s) and add the appropriate translation there too.
 
 Signed-off-by: Christoph Heiss <c.he...@proxmox.com>
 ---
- ifupdown2/addons/address.py          |  27 +++----
- ifupdown2/addons/bond.py             |   9 ++-
+ ifupdown2/addons/address.py          |  31 ++++----
+ ifupdown2/addons/addressvirtual.py   |  18 +++--
+ ifupdown2/addons/bond.py             |  25 +++++--
  ifupdown2/addons/bridge.py           |  14 ----
+ ifupdown2/addons/bridgevlan.py       |   5 ++
+ ifupdown2/addons/mstpctl.py          |   9 ++-
  ifupdown2/addons/openvswitch.py      |   1 +
  ifupdown2/addons/openvswitch_port.py |  31 +++++---
  ifupdown2/addons/vlan.py             |  15 +++-
+ ifupdown2/addons/vrf.py              |   4 ++
+ ifupdown2/addons/vxlan.py            |   3 +-
  ifupdown2/ifupdown/ifupdownmain.py   |  23 ++++--
  ifupdown2/lib/addon.py               |   9 +--
+ ifupdown2/lib/iproute2.py            |   2 +
  ifupdown2/lib/nlcache.py             | 102 +++++++++++++++++++++++++++
  ifupdown2/nlmanager/nlmanager.py     |  15 ++++
  ifupdown2/nlmanager/nlpacket.py      |  63 +++++++++++++++++
- 11 files changed, 260 insertions(+), 49 deletions(-)
+ 17 files changed, 304 insertions(+), 66 deletions(-)
 
 diff --git a/ifupdown2/addons/address.py b/ifupdown2/addons/address.py
-index 20f8866..c19b138 100644
+index 20f8866..d158c44 100644
 --- a/ifupdown2/addons/address.py
 +++ b/ifupdown2/addons/address.py
 @@ -912,6 +912,7 @@ class address(AddonWithIpBlackList, moduleBase):
@@ -133,8 +139,83 @@ index 20f8866..c19b138 100644
  
      def process_mtu(self, ifaceobj, ifaceobj_getfunc):
  
+@@ -1067,7 +1068,9 @@ class address(AddonWithIpBlackList, moduleBase):
+ 
+     def disable_ipv6(self, ifaceobj):
+         user_config = ifaceobj.get_attr_value_first("disable-ipv6")
+-        sysfs_path = f"/proc/sys/net/ipv6/conf/{ifaceobj.name}/disable_ipv6"
++
++        ifacename = self.cache.link_translate_altname(ifaceobj.name)
++        sysfs_path = f"/proc/sys/net/ipv6/conf/{ifacename}/disable_ipv6"
+ 
+         if not user_config:
+             # check if disable-ipv6 was removed from the stanza
+diff --git a/ifupdown2/addons/addressvirtual.py 
b/ifupdown2/addons/addressvirtual.py
+index d52115e..587f39f 100644
+--- a/ifupdown2/addons/addressvirtual.py
++++ b/ifupdown2/addons/addressvirtual.py
+@@ -347,6 +347,10 @@ class addressvirtual(AddonWithIpBlackList, moduleBase):
+         interfaces are brought up, the expectation is that
+         the normal path will fix up a vrf device or its slaves"""
+ 
++        # anything calling into self.sysfs must use the translated name to
++        # properly handle altnames
++        ifacename = self.cache.link_translate_altname(ifaceobj.name)
++
+         if not ifaceobj_getfunc:
+             return
+         if ((ifaceobj.link_kind & ifaceLinkKind.VRF) and
+@@ -355,7 +359,7 @@ class addressvirtual(AddonWithIpBlackList, moduleBase):
+             # that have address virtual config,
+             # enslave the slaves 'address virtual
+             # interfaces (macvlans)' to myself:
+-            running_slaves = self.sysfs.link_get_lowers(ifaceobj.name)
++            running_slaves = self.sysfs.link_get_lowers(ifacename)
+             if running_slaves:
+                 # pick up any existing slaves of a vrf device and
+                 # look for their upperdevices and enslave them to the
+@@ -364,8 +368,10 @@ class addressvirtual(AddonWithIpBlackList, moduleBase):
+                     sobjs = ifaceobj_getfunc(s)
+                     if (sobjs and
+                         (sobjs[0].link_privflags & 
ifaceLinkPrivFlags.ADDRESS_VIRTUAL_SLAVE)):
+-                        # enslave all its upper devices to
+-                        # the vrf device
++                        # enslave all its upper devices to the vrf device
++                        #
++                        # names retrieved from sysfs will be primary 
interface names,
++                        # so no need to translate here
+                         upperdevs = self.sysfs.link_get_uppers(sobjs[0].name)
+                         if not upperdevs:
+                             continue
+@@ -373,7 +379,7 @@ class addressvirtual(AddonWithIpBlackList, moduleBase):
+                             # skip vrf device which
+                             # will also show up in the
+                             # upper device list
+-                            if u == ifaceobj.name:
++                            if u == ifacename:
+                                 continue
+                             self.netlink.link_set_master(u, ifaceobj.name)
+                             self.netlink.link_up(u)
+@@ -386,7 +392,7 @@ class addressvirtual(AddonWithIpBlackList, moduleBase):
+             vrfname = ifaceobj.get_attr_value_first('vrf')
+             if not vrfname or not self.cache.link_exists(vrfname):
+                 return
+-            running_uppers = self.sysfs.link_get_uppers(ifaceobj.name)
++            running_uppers = self.sysfs.link_get_uppers(ifacename)
+             if not running_uppers:
+                 return
+             macvlan_prefix = self._get_macvlan_prefix(ifaceobj)
+@@ -426,7 +432,7 @@ class addressvirtual(AddonWithIpBlackList, moduleBase):
+ 
+         user_configured_ipv6_addrgenmode, ipv6_addrgen_user_value = 
self.get_addressvirtual_ipv6_addrgen_user_conf(ifaceobj)
+         purge_existing = False if ifupdownflags.flags.PERFMODE else True
+-        ifname = ifaceobj.name
++        ifname = self.cache.link_translate_altname(ifaceobj.name)
+ 
+         update_mtu = lower_iface_mtu = lower_iface_mtu_str = None
+         if ifupdownconfig.config.get("adjust_logical_dev_mtu", "1") != "0" 
and ifaceobj.lowerifaces and intf_config_list:
 diff --git a/ifupdown2/addons/bond.py b/ifupdown2/addons/bond.py
-index 2af5cf6..d5a7f3d 100644
+index 2af5cf6..4d178b8 100644
 --- a/ifupdown2/addons/bond.py
 +++ b/ifupdown2/addons/bond.py
 @@ -277,6 +277,7 @@ class bond(Addon, moduleBase):
@@ -161,6 +242,38 @@ index 2af5cf6..d5a7f3d 100644
  
      def _is_bond(self, ifaceobj):
          # at first link_kind is not set but once ifupdownmain
+@@ -497,7 +504,7 @@ class bond(Addon, moduleBase):
+                     self.iproute2.link_set_protodown_reason_clag_off(s)
+                     self.netlink.link_set_protodown_off(s)
+                 if s not in slaves:
+-                    self.sysfs.bond_remove_slave(ifaceobj.name, s)
++                    
self.sysfs.bond_remove_slave(self.cache.link_translate_altname(ifaceobj.name), 
s)
+                     removed_slave.append(s)
+                     if clag_bond:
+                         try:
+@@ -876,13 +883,17 @@ class bond(Addon, moduleBase):
+         return link_exists, bond_slaves
+ 
+     def create_or_set_bond_config_sysfs(self, ifaceobj, ifla_info_data):
+-        if len(ifaceobj.name) > 15:
+-            self.log_error("%s: cannot create bond: interface name exceeds 
max length of 15" % ifaceobj.name, ifaceobj)
++        # anything calling into self.sysfs must use the translated name to
++        # properly handle altnames
++        ifacename = self.cache.link_translate_altname(ifaceobj.name)
++
++        if len(ifacename) > 15:
++            self.log_error("%s: cannot create bond: interface name exceeds 
max length of 15" % ifacename, ifaceobj)
+             return
+ 
+-        if not self.cache.link_exists(ifaceobj.name):
+-            self.sysfs.bond_create(ifaceobj.name)
+-        self.sysfs.bond_set_attrs_nl(ifaceobj.name, ifla_info_data)
++        if not self.cache.link_exists(ifacename):
++            self.sysfs.bond_create(ifacename)
++        self.sysfs.bond_set_attrs_nl(ifacename, ifla_info_data)
+ 
+     def _up(self, ifaceobj, ifaceobj_getfunc=None):
+         try:
 diff --git a/ifupdown2/addons/bridge.py b/ifupdown2/addons/bridge.py
 index e0e7375..0215309 100644
 --- a/ifupdown2/addons/bridge.py
@@ -186,6 +299,69 @@ index e0e7375..0215309 100644
      def _get_bridge_port_list_user_ordered(self, ifaceobj):
          # When enslaving bridge-ports we need to return the exact user
          # configured bridge ports list (bridge will inherit the mac of the
+diff --git a/ifupdown2/addons/bridgevlan.py b/ifupdown2/addons/bridgevlan.py
+index 6b75dc3..76bbfec 100644
+--- a/ifupdown2/addons/bridgevlan.py
++++ b/ifupdown2/addons/bridgevlan.py
+@@ -77,6 +77,9 @@ class bridgevlan(Addon, moduleBase):
+                            "to format (eg. br0.100)" % ifaceobj.name, 
ifaceobj)
+             raise
+ 
++        # used below with sysfs
++        bridgename = self.cache.link_translate_altname(bridgename)
++
+         if not self.cache.link_exists(bridgename):
+             #self.logger.warning('%s: bridge %s does not exist' 
%(ifaceobj.name,
+             #                 bridgename))
+@@ -120,6 +123,8 @@ class bridgevlan(Addon, moduleBase):
+ 
+     def _query_running_bridge_igmp_querier_src(self, ifaceobj):
+         (bridgename, vlanid) = ifaceobj.name.split('.')
++
++        bridgename = self.cache.link_translate_altname(bridgename)
+         running_mcqv4src = self.sysfs.bridge_get_mcqv4src(bridgename)
+         if running_mcqv4src:
+             return running_mcqv4src.get(vlanid)
+diff --git a/ifupdown2/addons/mstpctl.py b/ifupdown2/addons/mstpctl.py
+index ff44eab..3eddf36 100644
+--- a/ifupdown2/addons/mstpctl.py
++++ b/ifupdown2/addons/mstpctl.py
+@@ -376,6 +376,7 @@ class mstpctl(Addon, moduleBase):
+ 
+     def _ports_enable_disable_ipv6(self, ports, enable='1'):
+         for p in ports:
++            p = self.cache.link_translate_altname(p)
+             try:
+                 self.write_file('/proc/sys/net/ipv6/conf/%s' %p +
+                                 '/disable_ipv6', enable)
+@@ -924,7 +925,7 @@ class mstpctl(Addon, moduleBase):
+                 # contain more than one valid values
+                 stp_on_vals = ['on', 'yes']
+                 stp_off_vals = ['off']
+-                rv = self.sysfs.bridge_get_stp(ifaceobj.name)
++                rv = 
self.sysfs.bridge_get_stp(self.cache.link_translate_altname(ifaceobj.name))
+                 if ((v in stp_on_vals and rv in stp_on_vals) or
+                     (v in stp_off_vals and rv in stp_off_vals)):
+                     ifaceobjcurr.update_config_with_status('mstpctl-stp', v, 
0)
+@@ -1151,14 +1152,16 @@ class mstpctl(Addon, moduleBase):
+         #    portconfig['mstpctl-treeportcost'] += ' %s=%s' %(p, v)
+ 
+     def _query_running_bridge(self, ifaceobjrunning):
+-        if self.sysfs.bridge_get_stp(ifaceobjrunning.name) == 'no':
++        bridgename = self.cache.get_master(ifaceobjrunning.name)
++
++        if self.sysfs.bridge_get_stp(bridgename) == 'no':
+            # This bridge does not run stp, return
+            return
+         # if userspace stp not set, return
+         if self.systcl_get_net_bridge_stp_user_space() != '1':
+             return
+         # Check if mstp really knows about this bridge
+-        if not self.mstpctlcmd.mstpbridge_exists(ifaceobjrunning.name):
++        if not self.mstpctlcmd.mstpbridge_exists(bridgename):
+             return
+         bridge_vlan_aware = False
+         if ifaceobjrunning.get_attr_value_first('bridge-vlan-aware') == 'yes':
 diff --git a/ifupdown2/addons/openvswitch.py b/ifupdown2/addons/openvswitch.py
 index 40fc36a..24483aa 100644
 --- a/ifupdown2/addons/openvswitch.py
@@ -321,6 +497,49 @@ index 4380dd8..a53b2f9 100644
              )
  
              #
+diff --git a/ifupdown2/addons/vrf.py b/ifupdown2/addons/vrf.py
+index f0ee503..2c92a12 100644
+--- a/ifupdown2/addons/vrf.py
++++ b/ifupdown2/addons/vrf.py
+@@ -452,6 +452,7 @@ class vrf(Addon, moduleBase):
+         try:
+             for ifaceobj in statemanager.get_ifaceobjs(ifname) or []:
+                 if ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_PORT:
++                    ifname = self.cache.link_translate_altname(ifname)
+                     self.write_file("/proc/sys/net/ipv6/conf/%s/disable_ipv6" 
% ifname, "0")
+                     return
+         except Exception as e:
+@@ -481,6 +482,8 @@ class vrf(Addon, moduleBase):
+ 
+     def _up_vrf_slave(self, ifacename, vrfname, ifaceobj=None,
+                       ifaceobj_getfunc=None, vrf_exists=False):
++        ifacename = self.cache.link_translate_altname(ifacename)
++
+         try:
+             master_exists = True
+             if vrf_exists or self.cache.link_exists(vrfname):
+@@ -655,6 +658,7 @@ class vrf(Addon, moduleBase):
+         #  - check if it is also a macvlan device of the
+         #    format <vrf_slave>-v<int> created by the
+         #    address virtual module
++        vrfslave = self.cache.link_translate_altname(vrfslave)
+         vrfslave_lowers = self.sysfs.link_get_lowers(vrfslave)
+         if vrfslave_lowers:
+             if vrfslave_lowers[0] in config_vrfslaves:
+diff --git a/ifupdown2/addons/vxlan.py b/ifupdown2/addons/vxlan.py
+index cc8d3b3..2a4857d 100644
+--- a/ifupdown2/addons/vxlan.py
++++ b/ifupdown2/addons/vxlan.py
+@@ -965,7 +965,8 @@ class vxlan(Vxlan, moduleBase):
+                 vxlan_physdev_ifindex = self.cache.get_ifindex(vxlan_physdev)
+             except NetlinkCacheIfnameNotFoundError:
+                 try:
+-                    vxlan_physdev_ifindex = 
int(self.sysfs.read_file_oneline("/sys/class/net/%s/ifindex" % vxlan_physdev))
++                    ifname = self.cache.link_translate_altname(vxlan_physdev) 
or vxlan_physdev
++                    vxlan_physdev_ifindex = 
int(self.sysfs.read_file_oneline("/sys/class/net/%s/ifindex" % ifname))
+                 except Exception:
+                     self.logger.error("%s: physdev %s doesn't exists" % 
(ifaceobj.name, vxlan_physdev))
+                     return
 diff --git a/ifupdown2/ifupdown/ifupdownmain.py 
b/ifupdown2/ifupdown/ifupdownmain.py
 index 92e3393..904062d 100644
 --- a/ifupdown2/ifupdown/ifupdownmain.py
@@ -441,6 +660,19 @@ index 47e42c7..77056b2 100644
  class AddonWithIpBlackList(Addon):
      try:
          ip_blacklist = [ipnetwork.IPNetwork(ip).ip for ip in 
policymanager.policymanager_api.get_module_globals(
+diff --git a/ifupdown2/lib/iproute2.py b/ifupdown2/lib/iproute2.py
+index 543082e..e22b34c 100644
+--- a/ifupdown2/lib/iproute2.py
++++ b/ifupdown2/lib/iproute2.py
+@@ -505,6 +505,8 @@ class IPRoute2(Cache, Requirements):
+         :param link_created:
+         :return:
+         """
++        ifname = self.cache.link_translate_altname(ifname)
++
+         cached_ipv6_addr_gen_mode = 
self.cache.get_link_ipv6_addrgen_mode(ifname)
+ 
+         if cached_ipv6_addr_gen_mode == addrgen:
 diff --git a/ifupdown2/lib/nlcache.py b/ifupdown2/lib/nlcache.py
 index bbd2a8b..891524e 100644
 --- a/ifupdown2/lib/nlcache.py
@@ -735,5 +967,5 @@ index ed463c2..efc4c4e 100644
  
      # Link flags
 -- 
-2.49.0
+2.50.1
 
-- 
2.50.1



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to