From 3808b1a9bd47cf783d4b8775fbc788a9ce5afdd4 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Thu, 3 Oct 2024 15:23:15 +0800 Subject: [PATCH] net/drivers/efi/efinet: Skip virtual VLAN devices during card enumeration 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 Reviewed-by: Daniel Kiper --- grub-core/net/drivers/efi/efinet.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c index 3ea25cf98..58fe381ab 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c @@ -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)