]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
net/drivers/efi/efinet: Skip virtual VLAN devices during card enumeration
authorMichael Chang <mchang@suse.com>
Thu, 3 Oct 2024 07:23:15 +0000 (15:23 +0800)
committerDaniel Kiper <daniel.kiper@oracle.com>
Thu, 10 Oct 2024 10:38:47 +0000 (12:38 +0200)
Similarly to the issue described in commit c52ae4057 (efinet: skip
virtual IPv4 and IPv6 devices during card enumeration) the UEFI PXE
driver creates additional VLAN child devices when a VLAN ID is
configured on a network interface associated with a physical NIC. These
virtual VLAN devices must be skipped during card enumeration to ensure
that the subsequent SNP exclusive open operation targets the correct
physical card instances. Otherwise packet transfer would fail.

A device path example with VLAN nodes:

  /MAC(123456789ABC,0x1)/Vlan(20)/IPv4(0.0.0.0,0x0,DHCP,0.0.0.0,0.0.0.0,0.0.0.0)

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/net/drivers/efi/efinet.c

index 3ea25cf98940a0e8c0898ca76eb9b69ca5e39b51..58fe381ab16a88afe6158c5d32b7895bc226727f 100644 (file)
@@ -276,7 +276,8 @@ grub_efinet_findcards (void)
              || GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)
          && parent
          && GRUB_EFI_DEVICE_PATH_TYPE (parent) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
-         && GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)
+         && (GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE
+             || GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE))
        continue;
 
       net = grub_efi_open_protocol (*handle, &net_io_guid,
@@ -389,6 +390,15 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
        dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
        dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
        dup_ldp->length = sizeof (*dup_ldp);
+
+       dup_ldp = grub_efi_find_last_device_path (dup_dp);
+       if (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE)
+         {
+           dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+           dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+           dup_ldp->length = sizeof (*dup_ldp);
+         }
+
        match = grub_efi_compare_device_paths (dup_dp, cdp) == 0;
        grub_free (dup_dp);
        if (!match)