diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml index a2c82fb916..2be0295bf1 100644 --- a/man/systemd.net-naming-scheme.xml +++ b/man/systemd.net-naming-scheme.xml @@ -159,6 +159,7 @@ ID_NET_NAME_SLOT=prefix[Pdomain]sslot[ffunction][nport_name|ddev_port]bnumber ID_NET_NAME_SLOT=prefix[Pdomain]sslot[ffunction][nport_name|ddev_port]uport…[cconfig][iinterface] ID_NET_NAME_SLOT=prefix[Pdomain]sslot[ffunction][nport_name|ddev_port]vslot + ID_NET_NAME_SLOT=prefix[Pdomain]sslot[ffunction][nport_name|ddev_port]rslot This property describes the slot position. Different schemes are used depending on the bus type, as described in the table below. In case of USB, BCMA, and SR-VIO devices, the full @@ -206,6 +207,11 @@ … vslot SR-VIO slot number + + + … rslot + SR-IOV slot number + @@ -226,6 +232,11 @@ v and the virtual device number, with any leading zeros removed. The bus number is ignored. + SR-IOV virtual device representors are named based on the name of the physical device + interface, with a suffix of r and the number of the virtual device that + is linked to the particular representor, with any leading zeros removed. The physical port + name and the bus number are ignored. + In some configurations a parent PCI bridge of a given network controller may be associated with a slot. In such case we don't generate this device property to avoid possible naming conflicts. @@ -457,6 +468,17 @@ + + v254 + + Naming was changed for SR-IOV virtual device representors. + + The rslot suffix was added to differentiate SR-IOV + virtual device representors attached to a single physical device interface. + + + + Note that latest may be used to denote the latest scheme known (to this diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h index bb893870e9..707c0d26f3 100644 --- a/src/shared/netif-naming-scheme.h +++ b/src/shared/netif-naming-scheme.h @@ -39,6 +39,7 @@ typedef enum NamingSchemeFlags { NAMING_BRIDGE_MULTIFUNCTION_SLOT = 1 << 14, /* Use PCI hotplug slot information associated with bridge, but only if PCI device is multifunction */ NAMING_DEVICETREE_ALIASES = 1 << 15, /* Generate names from devicetree aliases */ NAMING_USB_HOST = 1 << 16, /* Generate names for usb host */ + NAMING_SR_IOV_R = 1 << 17, /* Use "r" suffix for SR-IOV VF representors */ /* And now the masks that combine the features above */ NAMING_V238 = 0, @@ -53,6 +54,7 @@ typedef enum NamingSchemeFlags { NAMING_V251 = NAMING_V250 | NAMING_BRIDGE_MULTIFUNCTION_SLOT, NAMING_V252 = NAMING_V251 | NAMING_DEVICETREE_ALIASES, NAMING_V253 = NAMING_V252 | NAMING_USB_HOST, + NAMING_V254 = NAMING_V253 | NAMING_SR_IOV_R, EXTRA_NET_NAMING_SCHEMES diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 998478ec4e..000839cac9 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -80,6 +80,7 @@ typedef struct LinkInfo { int ifindex; int iflink; int iftype; + int vf_representor_id; const char *devtype; const char *phys_port_name; struct hw_addr_data hw_addr; @@ -208,7 +209,10 @@ static int dev_pci_onboard(sd_device *dev, const LinkInfo *info, NetNames *names s = names->pci_onboard; l = sizeof(names->pci_onboard); l = strpcpyf(&s, l, "o%lu", idx); - if (!isempty(info->phys_port_name)) + if (naming_scheme_has(NAMING_SR_IOV_R) && info->vf_representor_id >= 0) + /* For VF representor append 'r' and not phys_port_name */ + l = strpcpyf(&s, l, "r%d", info->vf_representor_id); + else if (!isempty(info->phys_port_name)) /* kernel provided front panel port name for multiple port PCI device */ l = strpcpyf(&s, l, "n%s", info->phys_port_name); else if (dev_port > 0) @@ -391,7 +395,10 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) { l = strpcpyf(&s, l, "p%us%u", bus, slot); if (func > 0 || is_pci_multifunction(names->pcidev) > 0) l = strpcpyf(&s, l, "f%u", func); - if (!isempty(info->phys_port_name)) + if (naming_scheme_has(NAMING_SR_IOV_R) && info->vf_representor_id >= 0) + /* For VF representor append 'r' and not phys_port_name */ + l = strpcpyf(&s, l, "r%d", info->vf_representor_id); + else if (!isempty(info->phys_port_name)) /* kernel provided front panel port name for multi-port PCI device */ l = strpcpyf(&s, l, "n%s", info->phys_port_name); else if (dev_port > 0) @@ -485,7 +492,10 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) { l = strpcpyf(&s, l, "s%"PRIu32, hotplug_slot); if (func > 0 || is_pci_multifunction(names->pcidev) > 0) l = strpcpyf(&s, l, "f%u", func); - if (!isempty(info->phys_port_name)) + if (naming_scheme_has(NAMING_SR_IOV_R) && info->vf_representor_id >= 0) + /* For VF representor append 'r' and not phys_port_name */ + l = strpcpyf(&s, l, "r%d", info->vf_representor_id); + else if (!isempty(info->phys_port_name)) l = strpcpyf(&s, l, "n%s", info->phys_port_name); else if (dev_port > 0) l = strpcpyf(&s, l, "d%lu", dev_port); @@ -1082,7 +1092,10 @@ static int get_link_info(sd_device *dev, LinkInfo *info) { if (r < 0 && r != -ENOENT) return r; - (void) sd_device_get_sysattr_value(dev, "phys_port_name", &info->phys_port_name); + r = sd_device_get_sysattr_value(dev, "phys_port_name", &info->phys_port_name); + if (r >= 0) + /* Check if phys_port_name indicates virtual device representor */ + (void) sscanf(info->phys_port_name, "pf%*uvf%d", &info->vf_representor_id); r = sd_device_get_sysattr_value(dev, "address", &s); if (r < 0 && r != -ENOENT) @@ -1100,7 +1113,9 @@ static int builtin_net_id(UdevEvent *event, int argc, char *argv[], bool test) { sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev); const char *prefix; NetNames names = {}; - LinkInfo info = {}; + LinkInfo info = { + .vf_representor_id = -1, + }; int r; r = get_link_info(dev, &info);