]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[iscsi] Allow iSCSI device to be described using an EFI device path
authorMichael Brown <mcb30@ipxe.org>
Tue, 20 Oct 2020 13:48:29 +0000 (14:48 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 20 Oct 2020 14:05:37 +0000 (15:05 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/efi/efi_path.h
src/interface/efi/efi_path.c
src/net/tcp/iscsi.c

index 3921fcee2648ebc3f9e6be137ea5ad6b6f8eeb6c..3701976017bdaa867ab314898ee836a1f5b6ec9d 100644 (file)
@@ -15,6 +15,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 struct net_device;
 struct uri;
+struct iscsi_session;
 struct aoe_device;
 struct usb_function;
 
@@ -25,6 +26,8 @@ extern EFI_DEVICE_PATH_PROTOCOL * efi_paths ( EFI_DEVICE_PATH_PROTOCOL *first,
                                              ... );
 extern EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev );
 extern EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri );
+extern EFI_DEVICE_PATH_PROTOCOL *
+efi_iscsi_path ( struct iscsi_session *iscsi );
 extern EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path ( struct aoe_device *aoedev );
 extern EFI_DEVICE_PATH_PROTOCOL * efi_usb_path ( struct usb_function *func );
 
index 8636c965b8caf28e42c087f1765f082d1067c9e8..3c14a2ee6c1b15794dc4cd9db529eefbf724c38d 100644 (file)
@@ -23,7 +23,9 @@
 #include <byteswap.h>
 #include <ipxe/netdevice.h>
 #include <ipxe/vlan.h>
+#include <ipxe/tcpip.h>
 #include <ipxe/uri.h>
+#include <ipxe/iscsi.h>
 #include <ipxe/aoe.h>
 #include <ipxe/usb.h>
 #include <ipxe/efi/efi.h>
@@ -221,6 +223,74 @@ EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri ) {
        return path;
 }
 
+/**
+ * Construct EFI device path for iSCSI device
+ *
+ * @v iscsi            iSCSI session
+ * @ret path           EFI device path, or NULL on error
+ */
+EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path ( struct iscsi_session *iscsi ) {
+       struct sockaddr_tcpip *st_target;
+       struct net_device *netdev;
+       EFI_DEVICE_PATH_PROTOCOL *netpath;
+       EFI_DEVICE_PATH_PROTOCOL *path;
+       EFI_DEVICE_PATH_PROTOCOL *end;
+       ISCSI_DEVICE_PATH *iscsipath;
+       char *name;
+       size_t prefix_len;
+       size_t name_len;
+       size_t iscsi_len;
+       size_t len;
+
+       /* Get network device associated with target address */
+       st_target = ( ( struct sockaddr_tcpip * ) &iscsi->target_sockaddr );
+       netdev = tcpip_netdev ( st_target );
+       if ( ! netdev )
+               goto err_netdev;
+
+       /* Get network device path */
+       netpath = efi_netdev_path ( netdev );
+       if ( ! netpath )
+               goto err_netpath;
+
+       /* Calculate device path length */
+       prefix_len = efi_path_len ( netpath );
+       name_len = ( strlen ( iscsi->target_iqn ) + 1 /* NUL */ );
+       iscsi_len = ( sizeof ( *iscsipath ) + name_len );
+       len = ( prefix_len + iscsi_len + sizeof ( *end ) );
+
+       /* Allocate device path */
+       path = zalloc ( len );
+       if ( ! path )
+               goto err_alloc;
+
+       /* Construct device path */
+       memcpy ( path, netpath, prefix_len );
+       iscsipath = ( ( ( void * ) path ) + prefix_len );
+       iscsipath->Header.Type = MESSAGING_DEVICE_PATH;
+       iscsipath->Header.SubType = MSG_ISCSI_DP;
+       iscsipath->Header.Length[0] = iscsi_len;
+       iscsipath->LoginOption = ISCSI_LOGIN_OPTION_AUTHMETHOD_NON;
+       memcpy ( &iscsipath->Lun, &iscsi->lun, sizeof ( iscsipath->Lun ) );
+       name = ( ( ( void * ) iscsipath ) + sizeof ( *iscsipath ) );
+       memcpy ( name, iscsi->target_iqn, name_len );
+       end = ( ( ( void * ) name ) + name_len );
+       end->Type = END_DEVICE_PATH_TYPE;
+       end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+       end->Length[0] = sizeof ( *end );
+
+       /* Free temporary paths */
+       free ( netpath );
+
+       return path;
+
+ err_alloc:
+       free ( netpath );
+ err_netpath:
+ err_netdev:
+       return NULL;
+}
+
 /**
  * Construct EFI device path for AoE device
  *
index 3a44b90f030fb1c78c81c0034b5165ea1716cd5c..e36d5619dcaf85a496cd0797f30f0e321a9d4c2c 100644 (file)
@@ -46,6 +46,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/base16.h>
 #include <ipxe/base64.h>
 #include <ipxe/ibft.h>
+#include <ipxe/efi/efi_path.h>
 #include <ipxe/iscsi.h>
 
 /** @file
@@ -1863,6 +1864,7 @@ static struct interface_operation iscsi_control_op[] = {
        INTF_OP ( xfer_window, struct iscsi_session *, iscsi_scsi_window ),
        INTF_OP ( intf_close, struct iscsi_session *, iscsi_close ),
        INTF_OP ( acpi_describe, struct iscsi_session *, iscsi_describe ),
+       EFI_INTF_OP ( efi_describe, struct iscsi_session *, efi_iscsi_path ),
 };
 
 /** iSCSI SCSI command-issuing interface descriptor */