diff options
author | Michael Brown <mcb30@ipxe.org> | 2020-10-20 14:48:29 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2020-10-20 15:05:37 +0100 |
commit | e6f9054d13bd9bc95720ca3e8cf6c4dcf4eae018 (patch) | |
tree | 31502aa34471a294cc0707faa6aaee2a69074635 /src/interface | |
parent | 334f0074b1f50d522a701f79faf28dadbdc28362 (diff) | |
download | ipxe-e6f9054d13bd9bc95720ca3e8cf6c4dcf4eae018.zip ipxe-e6f9054d13bd9bc95720ca3e8cf6c4dcf4eae018.tar.gz ipxe-e6f9054d13bd9bc95720ca3e8cf6c4dcf4eae018.tar.bz2 |
[iscsi] Allow iSCSI device to be described using an EFI device path
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/interface')
-rw-r--r-- | src/interface/efi/efi_path.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/interface/efi/efi_path.c b/src/interface/efi/efi_path.c index 8636c96..3c14a2e 100644 --- a/src/interface/efi/efi_path.c +++ b/src/interface/efi/efi_path.c @@ -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> @@ -222,6 +224,74 @@ EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri ) { } /** + * 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 * * @v aoedev AoE device |