aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-12-22 14:27:56 +0000
committerMichael Brown <mcb30@ipxe.org>2022-12-22 14:27:56 +0000
commitb9571ca12ed80472051663e2618dfe083f995da3 (patch)
tree9e04c6e86af2a67ed5be0ad517672417058f1eaf
parent099e4d39b355a10b0bc7d23bb0e96615bf06470b (diff)
downloadipxe-b9571ca12ed80472051663e2618dfe083f995da3.zip
ipxe-b9571ca12ed80472051663e2618dfe083f995da3.tar.gz
ipxe-b9571ca12ed80472051663e2618dfe083f995da3.tar.bz2
[efi] Add efi_path_vlan() utility function
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>
-rw-r--r--src/include/ipxe/efi/efi_path.h1
-rw-r--r--src/interface/efi/efi_path.c23
2 files changed, 24 insertions, 0 deletions
diff --git a/src/include/ipxe/efi/efi_path.h b/src/include/ipxe/efi/efi_path.h
index 18810a7..9dea74b 100644
--- a/src/include/ipxe/efi/efi_path.h
+++ b/src/include/ipxe/efi/efi_path.h
@@ -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 );
diff --git a/src/interface/efi/efi_path.c b/src/interface/efi/efi_path.c
index 937d3c7..fb0f305 100644
--- a/src/interface/efi/efi_path.c
+++ b/src/interface/efi/efi_path.c
@@ -95,6 +95,29 @@ size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *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
*
* @v ... List of device paths (NULL terminated)