<term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable>[<constant>P</constant><replaceable>domain</replaceable>]<constant>s</constant><replaceable>slot</replaceable>[<constant>f</constant><replaceable>function</replaceable>][<constant>n</constant><replaceable>port_name</replaceable>|<constant>d</constant><replaceable>dev_port</replaceable>]<constant>b</constant><replaceable>number</replaceable></varname></term>
<term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable>[<constant>P</constant><replaceable>domain</replaceable>]<constant>s</constant><replaceable>slot</replaceable>[<constant>f</constant><replaceable>function</replaceable>][<constant>n</constant><replaceable>port_name</replaceable>|<constant>d</constant><replaceable>dev_port</replaceable>]<constant>u</constant><replaceable>port</replaceable>…[<constant>c</constant><replaceable>config</replaceable>][<constant>i</constant><replaceable>interface</replaceable>]</varname></term>
<term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable>[<constant>P</constant><replaceable>domain</replaceable>]<constant>s</constant><replaceable>slot</replaceable>[<constant>f</constant><replaceable>function</replaceable>][<constant>n</constant><replaceable>port_name</replaceable>|<constant>d</constant><replaceable>dev_port</replaceable>]<constant>v</constant><replaceable>slot</replaceable></varname></term>
+ <term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable>[<constant>P</constant><replaceable>domain</replaceable>]<constant>s</constant><replaceable>slot</replaceable>[<constant>f</constant><replaceable>function</replaceable>][<constant>n</constant><replaceable>port_name</replaceable>|<constant>d</constant><replaceable>dev_port</replaceable>]<constant>r</constant><replaceable>slot</replaceable></varname></term>
<listitem><para>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
<entry>… <constant>v</constant><replaceable>slot</replaceable></entry>
<entry>SR-VIO slot number</entry>
</row>
+
+ <row>
+ <entry>… <constant>r</constant><replaceable>slot</replaceable></entry>
+ <entry>SR-IOV slot number</entry>
+ </row>
</tbody>
</tgroup>
</table>
<constant>v</constant> and the virtual device number, with any leading zeros removed. The bus
number is ignored.</para>
+ <para>SR-IOV virtual device representors are named based on the name of the physical device
+ interface, with a suffix of <constant>r</constant> 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.</para>
+
<para>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.</para>
</listitem>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><constant>v254</constant></term>
+
+ <listitem><para>Naming was changed for SR-IOV virtual device representors.</para>
+
+ <para>The <literal>r<replaceable>slot</replaceable></literal> suffix was added to differentiate SR-IOV
+ virtual device representors attached to a single physical device interface.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
<para>Note that <constant>latest</constant> may be used to denote the latest scheme known (to this
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,
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
int ifindex;
int iflink;
int iftype;
+ int vf_representor_id;
const char *devtype;
const char *phys_port_name;
struct hw_addr_data hw_addr;
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<VF_NUM>' 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)
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<VF_NUM>' 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)
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<VF_NUM>' 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);
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)
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);