8d419f
From 07a2159c8dc575745c967499b068209e8926ea79 Mon Sep 17 00:00:00 2001
8d419f
From: Michal Sekletar <msekleta@redhat.com>
8d419f
Date: Wed, 23 Mar 2022 17:34:12 +0100
8d419f
Subject: [PATCH] udev/net_id: avoid slot based names only for single function
8d419f
 devices
8d419f
8d419f
If we have two or more devices that share the same slot but they are
8d419f
also multifunction then it is OK to use the slot information even if it
8d419f
is the same for all of them. Name conflict will be avoided because we
8d419f
will append function number and form names like, ens1f1, ens1f2...
8d419f
8d419f
(cherry picked from commit 66425daf2c68793adf24a48a26d58add8662e83f)
8d419f
8d419f
Resolves: #2073003
8d419f
---
8d419f
 man/systemd.net-naming-scheme.xml |  7 ++++++-
8d419f
 src/shared/netif-naming-scheme.h  | 31 ++++++++++++++++---------------
8d419f
 src/udev/udev-builtin-net_id.c    | 11 +++++++++--
8d419f
 3 files changed, 31 insertions(+), 18 deletions(-)
8d419f
8d419f
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
8d419f
index 942ef572ff..73d08b681d 100644
8d419f
--- a/man/systemd.net-naming-scheme.xml
8d419f
+++ b/man/systemd.net-naming-scheme.xml
8d419f
@@ -406,7 +406,12 @@
8d419f
         <varlistentry>
8d419f
           <term><constant>rhel-9.0</constant></term>
8d419f
 
8d419f
-          <listitem><para>Same as naming scheme <constant>v250</constant>.</para>
8d419f
+          <listitem><para>Since version <constant>v247</constant> we no longer set
8d419f
+          <varname>ID_NET_NAME_SLOT</varname> if we detect that a PCI device associated with a slot is a PCI
8d419f
+          bridge as that would create naming conflict when there are more child devices on that bridge. Now,
8d419f
+          this is relaxed and we will use slot information to generate the name based on it but only if
8d419f
+          the PCI device has multiple functions. This is safe because distinct function number is a part of
8d419f
+          the device name for multifunction devices.</para>
8d419f
           </listitem>
8d419f
         </varlistentry>
8d419f
 
8d419f
diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h
8d419f
index f765db6ef2..5c86cb4545 100644
8d419f
--- a/src/shared/netif-naming-scheme.h
8d419f
+++ b/src/shared/netif-naming-scheme.h
8d419f
@@ -22,20 +22,21 @@
8d419f
  * OS versions, but not fully stabilize them. */
8d419f
 typedef enum NamingSchemeFlags {
8d419f
         /* First, the individual features */
8d419f
-        NAMING_SR_IOV_V            = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a */
8d419f
-        NAMING_NPAR_ARI            = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6ea */
8d419f
-        NAMING_INFINIBAND          = 1 << 2, /* Use "ib" prefix for infiniband, see 938d30aa98df */
8d419f
-        NAMING_ZERO_ACPI_INDEX     = 1 << 3, /* Use zero acpi_index field, see d81186ef4f6a */
8d419f
-        NAMING_ALLOW_RERENAMES     = 1 << 4, /* Allow re-renaming of devices, see #9006 */
8d419f
-        NAMING_STABLE_VIRTUAL_MACS = 1 << 5, /* Use device name to generate MAC, see 6d3646406560 */
8d419f
-        NAMING_NETDEVSIM           = 1 << 6, /* Generate names for netdevsim devices, see eaa9d507d855 */
8d419f
-        NAMING_LABEL_NOPREFIX      = 1 << 7, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */
8d419f
-        NAMING_NSPAWN_LONG_HASH    = 1 << 8, /* Shorten nspawn interfaces by including 24bit hash, instead of simple truncation  */
8d419f
-        NAMING_BRIDGE_NO_SLOT      = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */
8d419f
-        NAMING_SLOT_FUNCTION_ID    = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */
8d419f
-        NAMING_16BIT_INDEX         = 1 << 11, /* Allow full 16-bit for the onboard index */
8d419f
-        NAMING_REPLACE_STRICTLY    = 1 << 12, /* Use udev_replace_ifname() for NAME= rule */
8d419f
-        NAMING_XEN_VIF             = 1 << 13, /* GEnerate names for Xen netfront devices */
8d419f
+        NAMING_SR_IOV_V                  = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a */
8d419f
+        NAMING_NPAR_ARI                  = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6ea */
8d419f
+        NAMING_INFINIBAND                = 1 << 2, /* Use "ib" prefix for infiniband, see 938d30aa98df */
8d419f
+        NAMING_ZERO_ACPI_INDEX           = 1 << 3, /* Use zero acpi_index field, see d81186ef4f6a */
8d419f
+        NAMING_ALLOW_RERENAMES           = 1 << 4, /* Allow re-renaming of devices, see #9006 */
8d419f
+        NAMING_STABLE_VIRTUAL_MACS       = 1 << 5, /* Use device name to generate MAC, see 6d3646406560 */
8d419f
+        NAMING_NETDEVSIM                 = 1 << 6, /* Generate names for netdevsim devices, see eaa9d507d855 */
8d419f
+        NAMING_LABEL_NOPREFIX            = 1 << 7, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */
8d419f
+        NAMING_NSPAWN_LONG_HASH          = 1 << 8, /* Shorten nspawn interfaces by including 24bit hash, instead of simple truncation  */
8d419f
+        NAMING_BRIDGE_NO_SLOT            = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */
8d419f
+        NAMING_SLOT_FUNCTION_ID          = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */
8d419f
+        NAMING_16BIT_INDEX               = 1 << 11, /* Allow full 16-bit for the onboard index */
8d419f
+        NAMING_REPLACE_STRICTLY          = 1 << 12, /* Use udev_replace_ifname() for NAME= rule */
8d419f
+        NAMING_XEN_VIF                   = 1 << 13, /* Generate names for Xen netfront devices */
8d419f
+        NAMING_BRIDGE_MULTIFUNCTION_SLOT = 1 << 14, /* Use PCI hotplug slot information associated with bridge, but only if PCI device is multifunction */
8d419f
 
8d419f
         /* And now the masks that combine the features above */
8d419f
         NAMING_V238 = 0,
8d419f
@@ -47,7 +48,7 @@ typedef enum NamingSchemeFlags {
8d419f
         NAMING_V247 = NAMING_V245 | NAMING_BRIDGE_NO_SLOT,
8d419f
         NAMING_V249 = NAMING_V247 | NAMING_SLOT_FUNCTION_ID | NAMING_16BIT_INDEX | NAMING_REPLACE_STRICTLY,
8d419f
         NAMING_V250 = NAMING_V249 | NAMING_XEN_VIF,
8d419f
-        NAMING_RHEL_9_0 = NAMING_V250,
8d419f
+        NAMING_RHEL_9_0 = NAMING_V250 | NAMING_BRIDGE_MULTIFUNCTION_SLOT,
8d419f
 
8d419f
         EXTRA_NET_NAMING_SCHEMES
8d419f
 
8d419f
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
8d419f
index 65e003eb15..673ed7a7ca 100644
8d419f
--- a/src/udev/udev-builtin-net_id.c
8d419f
+++ b/src/udev/udev-builtin-net_id.c
8d419f
@@ -451,8 +451,15 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
8d419f
                                  * devices that will try to claim the same index and that would create name
8d419f
                                  * collision. */
8d419f
                                 if (naming_scheme_has(NAMING_BRIDGE_NO_SLOT) && is_pci_bridge(hotplug_slot_dev)) {
8d419f
-                                        log_device_debug(dev, "Not using slot information because the PCI device is a bridge.");
8d419f
-                                        return 0;
8d419f
+                                        if (naming_scheme_has(NAMING_BRIDGE_MULTIFUNCTION_SLOT) && !is_pci_multifunction(names->pcidev)) {
8d419f
+                                                log_device_debug(dev, "Not using slot information because the PCI device associated with the hotplug slot is a bridge and the PCI device has single function.");
8d419f
+                                                return 0;
8d419f
+                                        }
8d419f
+
8d419f
+                                        if (!naming_scheme_has(NAMING_BRIDGE_MULTIFUNCTION_SLOT)) {
8d419f
+                                                log_device_debug(dev, "Not using slot information because the PCI device is a bridge.");
8d419f
+                                                return 0;
8d419f
+                                        }
8d419f
                                 }
8d419f
 
8d419f
                                 break;