]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Add efi_path_vlan() utility function
authorMichael Brown <mcb30@ipxe.org>
Thu, 22 Dec 2022 14:27:56 +0000 (14:27 +0000)
committerMichael Brown <mcb30@ipxe.org>
Thu, 22 Dec 2022 14:27:56 +0000 (14:27 +0000)
EFI provides no API for determining the VLAN tag (if any) for a
specified device handle.  There is the EFI_VLAN_CONFIG_PROTOCOL, but
that exists only on the trunk device handle (not on the VLAN device
handle), and provides no way to match VLAN tags against the trunk
device's child device handles.

The EDK2 codebase seems to rely solely on the device path to determine
the VLAN tag for a specified device handle: both NetLibGetVlanId() and
BmGetNetworkDescription() will parse the device path to search for a
VLAN_DEVICE_PATH component.

Add efi_path_vlan() which uses the same device path parsing logic to
determine the VLAN tag.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/efi/efi_path.h
src/interface/efi/efi_path.c

index 18810a751977220b1c9c84e32333d772f42441e0..9dea74b5a3c07db71665e3a7d3f42917259816d6 100644 (file)
@@ -26,6 +26,7 @@ efi_path_next ( EFI_DEVICE_PATH_PROTOCOL *path );
 extern EFI_DEVICE_PATH_PROTOCOL *
 efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path );
 extern size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path );
+extern unsigned int efi_path_vlan ( EFI_DEVICE_PATH_PROTOCOL *path );
 extern EFI_DEVICE_PATH_PROTOCOL * efi_paths ( EFI_DEVICE_PATH_PROTOCOL *first,
                                              ... );
 extern EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev );
index 937d3c7046db810b3434ed078c21dfe7b47e7ca3..fb0f3059d308fe65385769ebff9bcaabd88ff009 100644 (file)
@@ -94,6 +94,29 @@ size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path ) {
        return ( ( ( void * ) end ) - ( ( void * ) path ) );
 }
 
+/**
+ * Get VLAN tag from device path
+ *
+ * @v path             Device path
+ * @ret tag            VLAN tag, or 0 if not a VLAN
+ */
+unsigned int efi_path_vlan ( EFI_DEVICE_PATH_PROTOCOL *path ) {
+       EFI_DEVICE_PATH_PROTOCOL *next;
+       VLAN_DEVICE_PATH *vlan;
+
+       /* Search for VLAN device path */
+       for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
+               if ( ( path->Type == MESSAGING_DEVICE_PATH ) &&
+                    ( path->SubType == MSG_VLAN_DP ) ) {
+                       vlan = container_of ( path, VLAN_DEVICE_PATH, Header );
+                       return vlan->VlanId;
+               }
+       }
+
+       /* No VLAN device path found */
+       return 0;
+}
+
 /**
  * Concatenate EFI device paths
  *