One of the solutions we discussed was the ability to (on Sysfs-based environments) validate leader/subordinate (upper/lower) distinctions for devices based on whether the virtual functions are created by the driver once it configures the device. Typically subordinate devices will have either a 'master' or 'upper_<upper_dev_name>' symlink in '/sys/class/net/<lower_devName>/device/'. A leader will have a 'lower_<lower_dev_name>' symlink to indicate that it is the 'upper'.
The problem we have with just relying on the upper/lower relationship being setup is that there is a race present if cloud-init walks /sys/class/net before drivers finish initial configuration and setup of the upper/lower relationships for the network VFs. When cloud-init beats driver setup, those upper_|lower_ symlinks aren't surfaced yet by the kernel.
So, ultimately we still have to rely on driver names to inform us of the unlikely scenarios where a network device or switch may have duplicate MACs for upper and lower functions, but those devices have not yet been fully configured.
A gap can exist as much as 40 seconds between driver detection for a device and the final upper_|lower_ configuration as seen in /sys for this Hyper-V system where duplicate MACs are expected:
One of the solutions we discussed was the ability to (on Sysfs-based environments) validate leader/subordinate (upper/lower) distinctions for devices based on whether the virtual functions are created by the driver once it configures the device. Typically subordinate devices will have either a 'master' or 'upper_ <upper_ dev_name> ' symlink in '/sys/class/ net/<lower_ devName> /device/ '. A leader will have a 'lower_ <lower_ dev_name> ' symlink to indicate that it is the 'upper'.
The problem we have with just relying on the upper/lower relationship being setup is that there is a race present if cloud-init walks /sys/class/net before drivers finish initial configuration and setup of the upper/lower relationships for the network VFs. When cloud-init beats driver setup, those upper_|lower_ symlinks aren't surfaced yet by the kernel.
So, ultimately we still have to rely on driver names to inform us of the unlikely scenarios where a network device or switch may have duplicate MACs for upper and lower functions, but those devices have not yet been fully configured.
A gap can exist as much as 40 seconds between driver detection for a device and the final upper_|lower_ configuration as seen in /sys for this Hyper-V system where duplicate MACs are expected:
ubuntu@ hyper-v- timestamp: ~$ for dev in eth0 enP62764s1; do echo ---- $dev; ls -l --full-time /sys/class/ net/$dev/ device/ driver; ls -l --full-time /sys/class/ net/$dev/ | egrep 'upper| lower|master' ; done net/eth0/ device/ driver -> ../../. ./../.. /../bus/ vmbus/drivers/ hv_netvsc ./1d6f00a2- f52c-4ea5- 9bf1-5cbb5824b1 d3/pcif52c: 00/f52c: 00:02.0/ net/enP62764s1 net/enP62764s1/ device/ driver -> ../../. ./../.. /../../ ../bus/ pci/drivers/ mlx5_core ./../.. /000d3a1e- a3af-000d- 3a1e-a3af000d3a 1e/net/ eth0 ./../.. /000d3a1e- a3af-000d- 3a1e-a3af000d3a 1e/net/ eth0
---- eth0
lrwxrwxrwx 1 root root 0 2023-01-31 21:25:18.651923500 +0000 /sys/class/
lrwxrwxrwx 1 root root 0 2023-01-31 21:25:27.864907346 +0000 lower_enP62764s1 -> ../../.
---- enP62764s1
lrwxrwxrwx 1 root root 0 2023-01-31 21:25:19.227923500 +0000 /sys/class/
lrwxrwxrwx 1 root root 0 2023-01-31 21:25:20.923923500 +0000 master -> ../../.
lrwxrwxrwx 1 root root 0 2023-01-31 21:26:05.957294183 +0000 upper_eth0 -> ../../.