iPXE
ibft.c File Reference

iSCSI boot firmware table More...

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/pci.h>
#include <ipxe/acpi.h>
#include <ipxe/in.h>
#include <ipxe/netdevice.h>
#include <ipxe/ethernet.h>
#include <ipxe/vlan.h>
#include <ipxe/tcpip.h>
#include <ipxe/dhcp.h>
#include <ipxe/iscsi.h>
#include <ipxe/ibft.h>

Go to the source code of this file.

Data Structures

struct  ibft_strings
 iSCSI string buffer More...

Functions

 FILE_LICENCE (BSD2)
 FILE_SECBOOT (PERMITTED)
static size_t ibft_align (size_t len)
 Align structure within iBFT.
static void ibft_set_ipaddr (struct ibft_ipaddr *ipaddr, struct in_addr in)
 Fill in an IP address field within iBFT.
static void ibft_set_ipaddr_setting (struct settings *settings, struct ibft_ipaddr *ipaddr, const struct setting *setting, unsigned int count)
 Fill in an IP address within iBFT from configuration setting.
static const char * ibft_ipaddr (struct ibft_ipaddr *ipaddr)
 Read IP address from iBFT (for debugging)
static char * ibft_alloc_string (struct ibft_strings *strings, struct ibft_string *string, size_t len)
 Allocate a string within iBFT.
static int ibft_set_string (struct ibft_strings *strings, struct ibft_string *string, const char *data)
 Fill in a string field within iBFT.
static int ibft_set_string_setting (struct settings *settings, struct ibft_strings *strings, struct ibft_string *string, const struct setting *setting)
 Fill in a string field within iBFT from configuration setting.
static const char * ibft_string (struct ibft_strings *strings, struct ibft_string *string)
 Read string from iBFT (for debugging)
static int ibft_netdev_is_required (struct net_device *netdev)
 Check if network device is required for the iBFT.
static int ibft_fill_nic (struct ibft_nic *nic, struct ibft_strings *strings, struct net_device *netdev)
 Fill in NIC portion of iBFT.
static int ibft_fill_initiator (struct ibft_initiator *initiator, struct ibft_strings *strings, const char *initiator_iqn)
 Fill in Initiator portion of iBFT.
static int ibft_fill_target_nic_association (struct ibft_target *target, struct iscsi_session *iscsi)
 Fill in Target NIC association.
static int ibft_fill_target_chap (struct ibft_target *target, struct ibft_strings *strings, struct iscsi_session *iscsi)
 Fill in Target CHAP portion of iBFT.
static int ibft_fill_target_reverse_chap (struct ibft_target *target, struct ibft_strings *strings, struct iscsi_session *iscsi)
 Fill in Target Reverse CHAP portion of iBFT.
static int ibft_fill_target (struct ibft_target *target, struct ibft_strings *strings, struct iscsi_session *iscsi)
 Fill in Target portion of iBFT.
static int ibft_complete (struct acpi_descriptor *desc)
 Check if iBFT descriptor is complete.
static int ibft_install (int(*install)(struct acpi_header *acpi))
 Install iBFT.

Variables

struct acpi_model ibft_model __acpi_model
 iBFT model

Detailed Description

iSCSI boot firmware table

The information in this file is originally derived from the document "iSCSI Boot Firmware Table (iBFT)" as published by IBM at:

ftp://ftp.software.ibm.com/systems/support/system_x_pdf/ibm_iscsi_boot_firmware_table_v1.02.pdf

That file is no longer available, but a more recent version is available:

ftp://ftp.software.ibm.com/systems/support/bladecenter/iscsi_boot_firmware_table_v1.03.pdf

Definition in file ibft.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( BSD2 )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ ibft_align()

size_t ibft_align ( size_t len)
inlinestatic

Align structure within iBFT.

Parameters
lenUnaligned length (or offset)
Return values
lenAligned length (or offset)

Definition at line 84 of file ibft.c.

84 {
85
86 return ( ( len + IBFT_ALIGN - 1 ) & ~( IBFT_ALIGN - 1 ) );
87}
ring len
Length.
Definition dwmac.h:226
#define IBFT_ALIGN
Alignment of structures within iBFT.
Definition ibft.h:54

References IBFT_ALIGN, and len.

Referenced by ibft_install().

◆ ibft_set_ipaddr()

void ibft_set_ipaddr ( struct ibft_ipaddr * ipaddr,
struct in_addr in )
static

Fill in an IP address field within iBFT.

Parameters
ipaddrIP address field
inIPv4 address

Definition at line 95 of file ibft.c.

95 {
96 memset ( ipaddr, 0, sizeof ( *ipaddr ) );
97 if ( in.s_addr ) {
98 ipaddr->in = in;
99 ipaddr->ones = 0xffff;
100 }
101}
__be32 in[4]
Definition CIB_PRM.h:7
void * memset(void *dest, int character, size_t len) __nonnull
struct in_addr in
The IPv4 address, or zero if not present.
Definition ibft.h:77
uint16_t ones
Must be 0xffff if IPv4 address is present, otherwise zero.
Definition ibft.h:75

References ibft_ipaddr::in, in, memset(), and ibft_ipaddr::ones.

Referenced by ibft_fill_target(), and ibft_set_ipaddr_setting().

◆ ibft_set_ipaddr_setting()

void ibft_set_ipaddr_setting ( struct settings * settings,
struct ibft_ipaddr * ipaddr,
const struct setting * setting,
unsigned int count )
static

Fill in an IP address within iBFT from configuration setting.

Parameters
settingsParent settings block, or NULL
ipaddrIP address field
settingConfiguration setting
countMaximum number of IP addresses

Definition at line 111 of file ibft.c.

114 {
115 struct in_addr in[count];
116 unsigned int i;
117
119 for ( i = 0 ; i < count ; i++ ) {
120 ibft_set_ipaddr ( &ipaddr[i], in[i] );
121 }
122}
static unsigned int count
Number of entries.
Definition dwmac.h:220
static void ibft_set_ipaddr(struct ibft_ipaddr *ipaddr, struct in_addr in)
Fill in an IP address field within iBFT.
Definition ibft.c:95
int fetch_ipv4_array_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp, unsigned int count)
Fetch value of IPv4 address setting.
Definition settings.c:891
IP address structure.
Definition in.h:42
A setting.
Definition settings.h:24
A settings block.
Definition settings.h:133

References count, fetch_ipv4_array_setting(), ibft_set_ipaddr(), and in.

Referenced by ibft_fill_nic().

◆ ibft_ipaddr()

const char * ibft_ipaddr ( struct ibft_ipaddr * ipaddr)
static

Read IP address from iBFT (for debugging)

Parameters
stringsiBFT string block descriptor
stringString field
Return values
ipaddrIP address string

Definition at line 131 of file ibft.c.

131 {
132 return inet_ntoa ( ipaddr->in );
133}
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition ipv4.c:814

References ibft_ipaddr::in, and inet_ntoa().

◆ ibft_alloc_string()

char * ibft_alloc_string ( struct ibft_strings * strings,
struct ibft_string * string,
size_t len )
static

Allocate a string within iBFT.

Parameters
stringsiBFT string block descriptor
stringString field to fill in
lenLength of string to allocate (excluding NUL)
Return values
destString destination, or NULL

Definition at line 143 of file ibft.c.

144 {
145 size_t new_len;
146 char *new_data;
147 char *dest;
148
149 /* Extend string data buffer */
150 new_len = ( strings->len + len + 1 /* NUL */ );
151 new_data = realloc ( strings->data, new_len );
152 if ( ! new_data )
153 return NULL;
154 strings->data = new_data;
155
156 /* Fill in string field */
157 string->offset = cpu_to_le16 ( strings->start + strings->len );
158 string->len = cpu_to_le16 ( len );
159
160 /* Zero string */
161 dest = ( strings->data + strings->len );
162 memset ( dest, 0, ( len + 1 /* NUL */ ) );
163
164 /* Update allocated length */
165 strings->len = new_len;
166
167 return dest;
168}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
#define cpu_to_le16(value)
Definition byteswap.h:107
void * realloc(void *old_ptr, size_t new_size)
Reallocate memory.
Definition malloc.c:607
size_t len
Total length.
Definition ibft.c:75
size_t start
Starting offset of strings.
Definition ibft.c:73
char * data
Strings data.
Definition ibft.c:71

References cpu_to_le16, ibft_strings::data, dest, ibft_strings::len, len, memset(), NULL, realloc(), and ibft_strings::start.

Referenced by ibft_set_string(), and ibft_set_string_setting().

◆ ibft_set_string()

int ibft_set_string ( struct ibft_strings * strings,
struct ibft_string * string,
const char * data )
static

Fill in a string field within iBFT.

Parameters
stringsiBFT string block descriptor
stringString field
dataString to fill in, or NULL
Return values
rcReturn status code

Definition at line 178 of file ibft.c.

179 {
180 char *dest;
181
182 if ( ! data )
183 return 0;
184
185 dest = ibft_alloc_string ( strings, string, strlen ( data ) );
186 if ( ! dest )
187 return -ENOBUFS;
188 strcpy ( dest, data );
189
190 return 0;
191}
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define ENOBUFS
No buffer space available.
Definition errno.h:499
static char * ibft_alloc_string(struct ibft_strings *strings, struct ibft_string *string, size_t len)
Allocate a string within iBFT.
Definition ibft.c:143
char * strcpy(char *dest, const char *src)
Copy string.
Definition string.c:347
size_t strlen(const char *src)
Get length of string.
Definition string.c:244

References data, dest, ENOBUFS, ibft_alloc_string(), strcpy(), and strlen().

Referenced by ibft_fill_initiator(), ibft_fill_target(), ibft_fill_target_chap(), and ibft_fill_target_reverse_chap().

◆ ibft_set_string_setting()

int ibft_set_string_setting ( struct settings * settings,
struct ibft_strings * strings,
struct ibft_string * string,
const struct setting * setting )
static

Fill in a string field within iBFT from configuration setting.

Parameters
settingsParent settings block, or NULL
stringsiBFT string block descriptor
stringString field
settingConfiguration setting
Return values
rcReturn status code

Definition at line 202 of file ibft.c.

205 {
206 struct settings *origin;
207 struct setting fetched;
208 int len;
209 char *dest;
210
211 len = fetch_setting ( settings, setting, &origin, &fetched, NULL, 0 );
212 if ( len < 0 ) {
213 string->offset = 0;
214 string->len = 0;
215 return 0;
216 }
217
218 dest = ibft_alloc_string ( strings, string, len );
219 if ( ! dest )
220 return -ENOBUFS;
221 fetch_string_setting ( origin, &fetched, dest, ( len + 1 ));
222
223 return 0;
224}
uint64_t origin
Origin.
Definition hyperv.h:9
int fetch_setting(struct settings *settings, const struct setting *setting, struct settings **origin, struct setting *fetched, void *data, size_t len)
Fetch setting.
Definition settings.c:667
int fetch_string_setting(struct settings *settings, const struct setting *setting, char *data, size_t len)
Fetch value of string setting.
Definition settings.c:842

References dest, ENOBUFS, fetch_setting(), fetch_string_setting(), ibft_alloc_string(), len, NULL, and origin.

Referenced by ibft_fill_nic().

◆ ibft_string()

const char * ibft_string ( struct ibft_strings * strings,
struct ibft_string * string )
static

Read string from iBFT (for debugging)

Parameters
stringsiBFT string block descriptor
stringString field
Return values
dataString content (or "<empty>")

Definition at line 233 of file ibft.c.

234 {
235 size_t offset = le16_to_cpu ( string->offset );
236
237 return ( offset ? ( strings->data + offset - strings->start ) : NULL );
238}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
#define le16_to_cpu(value)
Definition byteswap.h:113
uint32_t string
Definition multiboot.h:2

References ibft_strings::data, le16_to_cpu, NULL, offset, ibft_strings::start, and string.

◆ ibft_netdev_is_required()

int ibft_netdev_is_required ( struct net_device * netdev)
static

Check if network device is required for the iBFT.

Parameters
netdevNetwork device
Return values
is_requiredNetwork device is required

Definition at line 246 of file ibft.c.

246 {
247 struct iscsi_session *iscsi;
248 struct sockaddr_tcpip *st_target;
249
250 list_for_each_entry ( iscsi, &ibft_model.descs, desc.list ) {
251 st_target = ( struct sockaddr_tcpip * ) &iscsi->target_sockaddr;
252 if ( tcpip_netdev ( st_target ) == netdev )
253 return 1;
254 }
255
256 return 0;
257}
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
static struct net_device * netdev
Definition gdbudp.c:53
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
An iSCSI session.
Definition iscsi.h:545
struct sockaddr target_sockaddr
Target socket address (for boot firmware table)
Definition iscsi.h:662
TCP/IP socket address.
Definition tcpip.h:76
struct net_device * tcpip_netdev(struct sockaddr_tcpip *st_dest)
Determine transmitting network device.
Definition tcpip.c:115

References desc, list_for_each_entry, netdev, iscsi_session::target_sockaddr, and tcpip_netdev().

Referenced by ibft_fill_target_nic_association(), and ibft_install().

◆ ibft_fill_nic()

int ibft_fill_nic ( struct ibft_nic * nic,
struct ibft_strings * strings,
struct net_device * netdev )
static

Fill in NIC portion of iBFT.

Parameters
nicNIC portion of iBFT
stringsiBFT string block descriptor
netdevNetwork device
Return values
rcReturn status code

Definition at line 267 of file ibft.c.

269 {
270 struct ll_protocol *ll_protocol = netdev->ll_protocol;
271 struct in_addr netmask_addr = { 0 };
272 unsigned int netmask_count = 0;
274 struct settings *origin;
275 int rc;
276
277 /* Fill in common header */
278 nic->header.structure_id = IBFT_STRUCTURE_ID_NIC;
279 nic->header.version = 1;
280 nic->header.length = cpu_to_le16 ( sizeof ( *nic ) );
281 nic->header.flags = ( IBFT_FL_NIC_BLOCK_VALID |
283 DBG ( "iBFT NIC %d is %s\n", nic->header.index, netdev->name );
284
285 /* Determine origin of IP address */
287 nic->origin = ( ( origin == parent ) ?
289 DBG ( "iBFT NIC %d origin = %d\n", nic->header.index, nic->origin );
290
291 /* Extract values from configuration settings */
292 ibft_set_ipaddr_setting ( parent, &nic->ip_address, &ip_setting, 1 );
293 DBG ( "iBFT NIC %d IP = %s\n",
294 nic->header.index, ibft_ipaddr ( &nic->ip_address ) );
296 DBG ( "iBFT NIC %d gateway = %s\n",
297 nic->header.index, ibft_ipaddr ( &nic->gateway ) );
299 ( sizeof ( nic->dns ) /
300 sizeof ( nic->dns[0] ) ) );
301 ibft_set_ipaddr_setting ( parent, &nic->dhcp, &dhcp_server_setting, 1 );
302 DBG ( "iBFT NIC %d DNS = %s",
303 nic->header.index, ibft_ipaddr ( &nic->dns[0] ) );
304 DBG ( ", %s\n", ibft_ipaddr ( &nic->dns[1] ) );
305 if ( ( rc = ibft_set_string_setting ( NULL, strings, &nic->hostname,
306 &hostname_setting ) ) != 0 )
307 return rc;
308 DBG ( "iBFT NIC %d hostname = %s\n",
309 nic->header.index, ibft_string ( strings, &nic->hostname ) );
310
311 /* Derive subnet mask prefix from subnet mask */
312 fetch_ipv4_setting ( parent, &netmask_setting, &netmask_addr );
313 while ( netmask_addr.s_addr ) {
314 if ( netmask_addr.s_addr & 0x1 )
315 netmask_count++;
316 netmask_addr.s_addr >>= 1;
317 }
318 nic->subnet_mask_prefix = netmask_count;
319 DBG ( "iBFT NIC %d subnet = /%d\n",
320 nic->header.index, nic->subnet_mask_prefix );
321
322 /* Extract values from net-device configuration */
323 nic->vlan = cpu_to_le16 ( vlan_tag ( netdev ) );
324 DBG ( "iBFT NIC %d VLAN = %02x\n",
325 nic->header.index, le16_to_cpu ( nic->vlan ) );
326 if ( ( rc = ll_protocol->eth_addr ( netdev->ll_addr,
327 nic->mac_address ) ) != 0 ) {
328 DBG ( "Could not determine %s MAC: %s\n",
329 netdev->name, strerror ( rc ) );
330 return rc;
331 }
332 DBG ( "iBFT NIC %d MAC = %s\n",
333 nic->header.index, eth_ntoa ( nic->mac_address ) );
334 nic->pci_bus_dev_func = cpu_to_le16 ( netdev->dev->desc.location );
335 DBG ( "iBFT NIC %d PCI = %04x\n",
336 nic->header.index, le16_to_cpu ( nic->pci_bus_dev_func ) );
337
338 return 0;
339}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
const struct setting ip_setting
const struct setting dns_setting
const struct setting netmask_setting
const struct setting gateway_setting
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition ethernet.c:176
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
static int ibft_set_string_setting(struct settings *settings, struct ibft_strings *strings, struct ibft_string *string, const struct setting *setting)
Fill in a string field within iBFT from configuration setting.
Definition ibft.c:202
static void ibft_set_ipaddr_setting(struct settings *settings, struct ibft_ipaddr *ipaddr, const struct setting *setting, unsigned int count)
Fill in an IP address within iBFT from configuration setting.
Definition ibft.c:111
#define IBFT_FL_NIC_FIRMWARE_BOOT_SELECTED
NIC firmware boot selected.
Definition ibft.h:207
#define IBFT_STRUCTURE_ID_NIC
Structure ID for NIC section.
Definition ibft.h:201
#define IBFT_NIC_ORIGIN_DHCP
Definition ibft.h:216
#define IBFT_FL_NIC_BLOCK_VALID
NIC block valid.
Definition ibft.h:204
#define IBFT_NIC_ORIGIN_MANUAL
Definition ibft.h:214
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition netdevice.h:587
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
Definition settings.c:913
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
An IP address within the iBFT.
Definition ibft.h:71
A string within the iBFT.
Definition ibft.h:63
uint32_t s_addr
Definition in.h:43
A link-layer protocol.
Definition netdevice.h:115
int(* eth_addr)(const void *ll_addr, void *eth_addr)
Generate Ethernet-compatible compressed link-layer address.
Definition netdevice.h:182
Definition nic.h:49
int flags
Definition nic.h:51
struct settings * parent
Parent settings block.
Definition settings.h:139
static unsigned int vlan_tag(struct net_device *netdev)
Get the VLAN tag.
Definition vlan.h:74

References cpu_to_le16, DBG, dns_setting, ll_protocol::eth_addr, eth_ntoa(), fetch_ipv4_setting(), fetch_setting(), nic::flags, gateway_setting, IBFT_FL_NIC_BLOCK_VALID, IBFT_FL_NIC_FIRMWARE_BOOT_SELECTED, IBFT_NIC_ORIGIN_DHCP, IBFT_NIC_ORIGIN_MANUAL, ibft_set_ipaddr_setting(), ibft_set_string_setting(), IBFT_STRUCTURE_ID_NIC, ip_setting, le16_to_cpu, netdev, netdev_settings(), netmask_setting, NULL, origin, settings::parent, rc, in_addr::s_addr, strerror(), and vlan_tag().

Referenced by ibft_install().

◆ ibft_fill_initiator()

int ibft_fill_initiator ( struct ibft_initiator * initiator,
struct ibft_strings * strings,
const char * initiator_iqn )
static

Fill in Initiator portion of iBFT.

Parameters
initiatorInitiator portion of iBFT
stringsiBFT string block descriptor
initiator_iqnInitiator IQN
Return values
rcReturn status code

Definition at line 349 of file ibft.c.

351 {
352 int rc;
353
354 /* Fill in common header */
356 initiator->header.version = 1;
357 initiator->header.length = cpu_to_le16 ( sizeof ( *initiator ) );
360
361 /* Fill in initiator name */
362 if ( ( rc = ibft_set_string ( strings, &initiator->initiator_name,
363 initiator_iqn ) ) != 0 )
364 return rc;
365 DBG ( "iBFT initiator name = %s\n",
366 ibft_string ( strings, &initiator->initiator_name ) );
367
368 return 0;
369}
static int ibft_set_string(struct ibft_strings *strings, struct ibft_string *string, const char *data)
Fill in a string field within iBFT.
Definition ibft.c:178
#define IBFT_FL_INITIATOR_FIRMWARE_BOOT_SELECTED
Initiator firmware boot selected.
Definition ibft.h:166
#define IBFT_STRUCTURE_ID_INITIATOR
Structure ID for Initiator section.
Definition ibft.h:160
#define IBFT_FL_INITIATOR_BLOCK_VALID
Initiator block valid.
Definition ibft.h:163
uint16_t length
Length, including this header.
Definition ibft.h:94
uint8_t flags
Flags.
Definition ibft.h:101
uint8_t version
Version (always 1)
Definition ibft.h:92
uint8_t structure_id
Structure ID.
Definition ibft.h:90
struct ibft_header header
Common header.
Definition ibft.h:148
struct ibft_string initiator_name
Initiator name.
Definition ibft.h:156

References cpu_to_le16, DBG, ibft_header::flags, ibft_initiator::header, IBFT_FL_INITIATOR_BLOCK_VALID, IBFT_FL_INITIATOR_FIRMWARE_BOOT_SELECTED, ibft_set_string(), IBFT_STRUCTURE_ID_INITIATOR, ibft_initiator::initiator_name, ibft_header::length, rc, ibft_header::structure_id, and ibft_header::version.

Referenced by ibft_install().

◆ ibft_fill_target_nic_association()

int ibft_fill_target_nic_association ( struct ibft_target * target,
struct iscsi_session * iscsi )
static

Fill in Target NIC association.

Parameters
targetTarget portion of iBFT
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 378 of file ibft.c.

379 {
380 struct sockaddr_tcpip *st_target =
381 ( struct sockaddr_tcpip * ) &iscsi->target_sockaddr;
382 struct net_device *associated;
383 struct net_device *netdev;
384
385 /* Find network device used to reach target */
386 associated = tcpip_netdev ( st_target );
387 if ( ! associated ) {
388 DBG ( "iBFT target %d has no net device\n",
389 target->header.index );
390 return -EHOSTUNREACH;
391 }
392
393 /* Calculate association */
395 if ( netdev == associated ) {
396 DBG ( "iBFT target %d uses NIC %d (%s)\n",
397 target->header.index, target->nic_association,
398 netdev->name );
399 return 0;
400 }
402 continue;
403 target->nic_association++;
404 }
405
406 DBG ( "iBFT target %d has impossible NIC %s\n",
407 target->header.index, netdev->name );
408 return -EINVAL;
409}
#define EINVAL
Invalid argument.
Definition errno.h:429
#define EHOSTUNREACH
Host is unreachable.
Definition errno.h:404
static int ibft_netdev_is_required(struct net_device *netdev)
Check if network device is required for the iBFT.
Definition ibft.c:246
#define for_each_netdev(netdev)
Iterate over all network devices.
Definition netdevice.h:547
uint8_t index
Index.
Definition ibft.h:99
struct ibft_header header
Common header.
Definition ibft.h:226
uint8_t nic_association
NIC association.
Definition ibft.h:239
A network device.
Definition netdevice.h:353

References DBG, EHOSTUNREACH, EINVAL, for_each_netdev, ibft_target::header, ibft_netdev_is_required(), ibft_header::index, netdev, ibft_target::nic_association, iscsi_session::target_sockaddr, and tcpip_netdev().

Referenced by ibft_fill_target().

◆ ibft_fill_target_chap()

int ibft_fill_target_chap ( struct ibft_target * target,
struct ibft_strings * strings,
struct iscsi_session * iscsi )
static

Fill in Target CHAP portion of iBFT.

Parameters
targetTarget portion of iBFT
stringsiBFT string block descriptor
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 419 of file ibft.c.

421 {
422 int rc;
423
424 if ( ! ( iscsi->status & ISCSI_STATUS_AUTH_FORWARD_REQUIRED ) )
425 return 0;
426
427 assert ( iscsi->initiator_username );
428 assert ( iscsi->initiator_password );
429
431 if ( ( rc = ibft_set_string ( strings, &target->chap_name,
432 iscsi->initiator_username ) ) != 0 )
433 return rc;
434 DBG ( "iBFT target %d username = %s\n", target->header.index,
435 ibft_string ( strings, &target->chap_name ) );
436 if ( ( rc = ibft_set_string ( strings, &target->chap_secret,
437 iscsi->initiator_password ) ) != 0 )
438 return rc;
439 DBG ( "iBFT target %d password = <redacted>\n", target->header.index );
440
441 return 0;
442}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define IBFT_CHAP_ONE_WAY
One-way CHAP.
Definition ibft.h:269
#define ISCSI_STATUS_AUTH_FORWARD_REQUIRED
Target has requested forward (initiator) authentication.
Definition iscsi.h:706
uint8_t chap_type
CHAP type.
Definition ibft.h:237
struct ibft_string chap_secret
CHAP secret.
Definition ibft.h:245
struct ibft_string chap_name
CHAP name.
Definition ibft.h:243
char * initiator_password
Initiator password (if any)
Definition iscsi.h:575
char * initiator_username
Initiator username (if any)
Definition iscsi.h:573
int status
Session status.
Definition iscsi.h:570

References assert, ibft_target::chap_name, ibft_target::chap_secret, ibft_target::chap_type, DBG, ibft_target::header, IBFT_CHAP_ONE_WAY, ibft_set_string(), ibft_header::index, iscsi_session::initiator_password, iscsi_session::initiator_username, ISCSI_STATUS_AUTH_FORWARD_REQUIRED, rc, and iscsi_session::status.

Referenced by ibft_fill_target().

◆ ibft_fill_target_reverse_chap()

int ibft_fill_target_reverse_chap ( struct ibft_target * target,
struct ibft_strings * strings,
struct iscsi_session * iscsi )
static

Fill in Target Reverse CHAP portion of iBFT.

Parameters
targetTarget portion of iBFT
stringsiBFT string block descriptor
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 452 of file ibft.c.

454 {
455 int rc;
456
457 if ( ! ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_REQUIRED ) )
458 return 0;
459
460 assert ( iscsi->initiator_username );
461 assert ( iscsi->initiator_password );
462 assert ( iscsi->target_username );
463 assert ( iscsi->target_password );
464
465 target->chap_type = IBFT_CHAP_MUTUAL;
466 if ( ( rc = ibft_set_string ( strings, &target->reverse_chap_name,
467 iscsi->target_username ) ) != 0 )
468 return rc;
469 DBG ( "iBFT target %d reverse username = %s\n", target->header.index,
470 ibft_string ( strings, &target->chap_name ) );
471 if ( ( rc = ibft_set_string ( strings, &target->reverse_chap_secret,
472 iscsi->target_password ) ) != 0 )
473 return rc;
474 DBG ( "iBFT target %d reverse password = <redacted>\n",
475 target->header.index );
476
477 return 0;
478}
#define IBFT_CHAP_MUTUAL
Mutual CHAP.
Definition ibft.h:270
#define ISCSI_STATUS_AUTH_REVERSE_REQUIRED
Initiator requires target (reverse) authentication.
Definition iscsi.h:709
struct ibft_string reverse_chap_name
Reverse CHAP name.
Definition ibft.h:247
struct ibft_string reverse_chap_secret
Reverse CHAP secret.
Definition ibft.h:249
char * target_password
Target password (if any)
Definition iscsi.h:579
char * target_username
Target username (if any)
Definition iscsi.h:577

References assert, ibft_target::chap_name, ibft_target::chap_type, DBG, ibft_target::header, IBFT_CHAP_MUTUAL, ibft_set_string(), ibft_header::index, iscsi_session::initiator_password, iscsi_session::initiator_username, ISCSI_STATUS_AUTH_REVERSE_REQUIRED, rc, ibft_target::reverse_chap_name, ibft_target::reverse_chap_secret, iscsi_session::status, iscsi_session::target_password, and iscsi_session::target_username.

Referenced by ibft_fill_target().

◆ ibft_fill_target()

int ibft_fill_target ( struct ibft_target * target,
struct ibft_strings * strings,
struct iscsi_session * iscsi )
static

Fill in Target portion of iBFT.

Parameters
targetTarget portion of iBFT
stringsiBFT string block descriptor
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 488 of file ibft.c.

490 {
491 struct sockaddr_tcpip *st_target =
492 ( struct sockaddr_tcpip * ) &iscsi->target_sockaddr;
493 struct sockaddr_in *sin_target =
494 ( struct sockaddr_in * ) &iscsi->target_sockaddr;
495 int rc;
496
497 /* Fill in common header */
499 target->header.version = 1;
500 target->header.length = cpu_to_le16 ( sizeof ( *target ) );
503
504 /* Fill in Target values */
505 ibft_set_ipaddr ( &target->ip_address, sin_target->sin_addr );
506 DBG ( "iBFT target %d IP = %s\n",
507 target->header.index, ibft_ipaddr ( &target->ip_address ) );
508 target->socket = cpu_to_le16 ( ntohs ( st_target->st_port ) );
509 DBG ( "iBFT target %d port = %d\n",
510 target->header.index, target->socket );
511 memcpy ( &target->boot_lun, &iscsi->lun, sizeof ( target->boot_lun ) );
512 DBG ( "iBFT target %d boot LUN = " SCSI_LUN_FORMAT "\n",
513 target->header.index, SCSI_LUN_DATA ( target->boot_lun ) );
514 if ( ( rc = ibft_set_string ( strings, &target->target_name,
515 iscsi->target_iqn ) ) != 0 )
516 return rc;
517 DBG ( "iBFT target %d name = %s\n", target->header.index,
518 ibft_string ( strings, &target->target_name ) );
519 if ( ( rc = ibft_fill_target_nic_association ( target, iscsi ) ) != 0 )
520 return rc;
521 if ( ( rc = ibft_fill_target_chap ( target, strings, iscsi ) ) != 0 )
522 return rc;
523 if ( ( rc = ibft_fill_target_reverse_chap ( target, strings,
524 iscsi ) ) != 0 )
525 return rc;
526
527 return 0;
528}
static int ibft_fill_target_chap(struct ibft_target *target, struct ibft_strings *strings, struct iscsi_session *iscsi)
Fill in Target CHAP portion of iBFT.
Definition ibft.c:419
static int ibft_fill_target_reverse_chap(struct ibft_target *target, struct ibft_strings *strings, struct iscsi_session *iscsi)
Fill in Target Reverse CHAP portion of iBFT.
Definition ibft.c:452
static int ibft_fill_target_nic_association(struct ibft_target *target, struct iscsi_session *iscsi)
Fill in Target NIC association.
Definition ibft.c:378
#define IBFT_FL_TARGET_FIRMWARE_BOOT_SELECTED
Target firmware boot selected.
Definition ibft.h:259
#define IBFT_STRUCTURE_ID_TARGET
Structure ID for Target section.
Definition ibft.h:253
#define IBFT_FL_TARGET_BLOCK_VALID
Target block valid.
Definition ibft.h:256
#define ntohs(value)
Definition byteswap.h:137
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define SCSI_LUN_FORMAT
printf() format for dumping a scsi_lun
Definition scsi.h:241
#define SCSI_LUN_DATA(lun)
printf() parameters for dumping a scsi_lun
Definition scsi.h:244
struct ibft_ipaddr ip_address
IP address.
Definition ibft.h:228
struct ibft_string target_name
Target name.
Definition ibft.h:241
struct scsi_lun boot_lun
Boot LUN.
Definition ibft.h:232
uint16_t socket
TCP port.
Definition ibft.h:230
char * target_iqn
Target IQN.
Definition iscsi.h:563
struct scsi_lun lun
SCSI LUN (for boot firmware table)
Definition iscsi.h:664
IPv4 socket address.
Definition in.h:85
struct in_addr sin_addr
IPv4 address.
Definition in.h:101

References ibft_target::boot_lun, cpu_to_le16, DBG, ibft_header::flags, ibft_target::header, ibft_fill_target_chap(), ibft_fill_target_nic_association(), ibft_fill_target_reverse_chap(), IBFT_FL_TARGET_BLOCK_VALID, IBFT_FL_TARGET_FIRMWARE_BOOT_SELECTED, ibft_set_ipaddr(), ibft_set_string(), IBFT_STRUCTURE_ID_TARGET, ibft_header::index, ibft_target::ip_address, ibft_header::length, iscsi_session::lun, memcpy(), ntohs, rc, SCSI_LUN_DATA, SCSI_LUN_FORMAT, sockaddr_in::sin_addr, ibft_target::socket, sockaddr_tcpip::st_port, ibft_header::structure_id, iscsi_session::target_iqn, ibft_target::target_name, iscsi_session::target_sockaddr, and ibft_header::version.

Referenced by ibft_install().

◆ ibft_complete()

int ibft_complete ( struct acpi_descriptor * desc)
static

Check if iBFT descriptor is complete.

Parameters
descACPI descriptor
Return values
rcReturn status code

Definition at line 536 of file ibft.c.

536 {
537 struct iscsi_session *iscsi =
538 container_of ( desc, struct iscsi_session, desc );
539
540 /* Fail if we do not yet have the target address */
541 if ( ! iscsi->target_sockaddr.sa_family )
542 return -EAGAIN;
543
544 return 0;
545}
#define EAGAIN
Resource temporarily unavailable.
Definition errno.h:319
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
sa_family_t sa_family
Socket address family.
Definition socket.h:102

References container_of, desc, EAGAIN, sockaddr::sa_family, and iscsi_session::target_sockaddr.

◆ ibft_install()

int ibft_install ( int(* install )(struct acpi_header *acpi))
static

Install iBFT.

Parameters
installInstallation method
Return values
rcReturn status code

Definition at line 553 of file ibft.c.

553 {
554 struct net_device *netdev;
555 struct iscsi_session *iscsi;
556 struct ibft_table *table;
557 struct ibft_initiator *initiator;
558 struct ibft_nic *nic;
559 struct ibft_target *target;
560 struct ibft_strings strings;
561 struct acpi_header *acpi;
562 void *data;
563 unsigned int targets = 0;
564 unsigned int pairs = 0;
565 size_t offset = 0;
566 size_t table_len;
567 size_t control_len;
568 size_t initiator_offset;
569 size_t nic_offset;
570 size_t target_offset;
571 size_t strings_offset;
572 size_t len;
573 unsigned int i;
574 int rc;
575
576 /* Calculate table sizes and offsets */
577 list_for_each_entry ( iscsi, &ibft_model.descs, desc.list )
578 targets++;
579 pairs = ( sizeof ( table->control.pair ) /
580 sizeof ( table->control.pair[0] ) );
581 if ( pairs < targets )
582 pairs = targets;
583 offset = offsetof ( typeof ( *table ), control.pair );
584 offset += ( pairs * sizeof ( table->control.pair[0] ) );
585 table_len = offset;
586 control_len = ( table_len - offsetof ( typeof ( *table ), control ) );
588 initiator_offset = offset;
589 offset += ibft_align ( sizeof ( *initiator ) );
590 nic_offset = offset;
591 offset += ( pairs * ibft_align ( sizeof ( *nic ) ) );
592 target_offset = offset;
593 offset += ( pairs * ibft_align ( sizeof ( *target ) ) );
594 strings_offset = offset;
595 strings.data = NULL;
596 strings.start = strings_offset;
597 strings.len = 0;
598 len = offset;
599
600 /* Do nothing if no targets exist */
601 if ( ! targets ) {
602 rc = 0;
603 goto no_targets;
604 }
605
606 /* Allocate table */
607 data = zalloc ( len );
608 if ( ! data ) {
609 rc = -ENOMEM;
610 goto err_alloc;
611 }
612
613 /* Fill in Control block */
614 table = data;
616 table->control.header.version = 1;
617 table->control.header.length = cpu_to_le16 ( control_len );
618
619 /* Fill in Initiator block */
620 initiator = ( data + initiator_offset );
621 table->control.initiator = cpu_to_le16 ( initiator_offset );
622 iscsi = list_first_entry ( &ibft_model.descs, struct iscsi_session,
623 desc.list );
624 if ( ( rc = ibft_fill_initiator ( initiator, &strings,
625 iscsi->initiator_iqn ) ) != 0 )
626 goto err_initiator;
627
628 /* Fill in NIC blocks */
629 i = 0;
632 continue;
633 assert ( i < pairs );
634 table->control.pair[i].nic = nic_offset;
635 nic = ( data + nic_offset );
636 nic->header.index = i;
637 if ( ( rc = ibft_fill_nic ( nic, &strings, netdev ) ) != 0 )
638 goto err_nic;
639 i++;
640 nic_offset += ibft_align ( sizeof ( *nic ) );
641 }
642
643 /* Fill in Target blocks */
644 i = 0;
645 list_for_each_entry ( iscsi, &ibft_model.descs, desc.list ) {
646 assert ( i < pairs );
647 table->control.pair[i].target = target_offset;
648 target = ( data + target_offset );
649 target->header.index = i;
650 if ( ( rc = ibft_fill_target ( target, &strings, iscsi ) ) != 0)
651 goto err_target;
652 i++;
653 target_offset += ibft_align ( sizeof ( *target ) );
654 }
655
656 /* Reallocate table to include space for strings */
657 len += strings.len;
658 acpi = realloc ( data, len );
659 if ( ! acpi )
660 goto err_realloc;
661 data = NULL;
662
663 /* Fill in ACPI header */
664 acpi->signature = cpu_to_le32 ( IBFT_SIG );
665 acpi->length = cpu_to_le32 ( len );
666 acpi->revision = 1;
667
668 /* Append strings */
669 memcpy ( ( ( ( void * ) acpi ) + strings_offset ), strings.data,
670 strings.len );
671
672 /* Install ACPI table */
673 if ( ( rc = install ( acpi ) ) != 0 ) {
674 DBG ( "iBFT could not install: %s\n", strerror ( rc ) );
675 goto err_install;
676 }
677
678 err_install:
679 free ( acpi );
680 err_realloc:
681 err_target:
682 err_nic:
683 err_initiator:
684 free ( data );
685 err_alloc:
686 no_targets:
687 free ( strings.data );
688 return rc;
689}
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition efi_block.c:67
uint32_t start
Starting offset.
Definition netvsc.h:1
#define ENOMEM
Not enough space.
Definition errno.h:535
static int ibft_fill_nic(struct ibft_nic *nic, struct ibft_strings *strings, struct net_device *netdev)
Fill in NIC portion of iBFT.
Definition ibft.c:267
static int ibft_fill_target(struct ibft_target *target, struct ibft_strings *strings, struct iscsi_session *iscsi)
Fill in Target portion of iBFT.
Definition ibft.c:488
static size_t ibft_align(size_t len)
Align structure within iBFT.
Definition ibft.c:84
static int ibft_fill_initiator(struct ibft_initiator *initiator, struct ibft_strings *strings, const char *initiator_iqn)
Fill in Initiator portion of iBFT.
Definition ibft.c:349
#define IBFT_SIG
iSCSI Boot Firmware Table signature
Definition ibft.h:51
#define IBFT_STRUCTURE_ID_CONTROL
Structure ID for Control section.
Definition ibft.h:134
#define cpu_to_le32(value)
Definition byteswap.h:108
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition list.h:334
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
uint32_t control
Control.
Definition myson.h:3
if(natsemi->flags &NATSEMI_64BIT) return 1
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25
An ACPI description header.
Definition acpi.h:180
struct ibft_header header
Common header.
Definition ibft.h:124
struct ibft_offset_pair pair[2]
Offsets to NIC and Target structures.
Definition ibft.h:130
ibft_off_t initiator
Offset to Initiator structure.
Definition ibft.h:128
iBFT Initiator structure
Definition ibft.h:146
iBFT NIC structure
Definition ibft.h:172
ibft_off_t nic
Offset to NIC structure.
Definition ibft.h:113
ibft_off_t target
Offset to Target structure.
Definition ibft.h:115
iSCSI string buffer
Definition ibft.c:69
iSCSI Boot Firmware Table (iBFT)
Definition ibft.h:275
struct ibft_control control
Control structure.
Definition ibft.h:281
iBFT Target structure
Definition ibft.h:224
char * initiator_iqn
Initiator IQN.
Definition iscsi.h:557

References acpi, assert, control, ibft_table::control, cpu_to_le16, cpu_to_le32, data, ibft_strings::data, DBG, desc, ENOMEM, for_each_netdev, free, ibft_control::header, ibft_target::header, ibft_align(), ibft_fill_initiator(), ibft_fill_nic(), ibft_fill_target(), ibft_netdev_is_required(), IBFT_SIG, IBFT_STRUCTURE_ID_CONTROL, ibft_header::index, ibft_control::initiator, iscsi_session::initiator_iqn, ibft_strings::len, len, ibft_header::length, list_first_entry, list_for_each_entry, memcpy(), netdev, ibft_offset_pair::nic, NULL, offset, offsetof, ibft_control::pair, rc, realloc(), ibft_strings::start, strerror(), ibft_header::structure_id, ibft_offset_pair::target, typeof(), ibft_header::version, and zalloc().

Variable Documentation

◆ __acpi_model

struct acpi_model ibft_model __acpi_model
Initial value:
= {
.descs = LIST_HEAD_INIT ( ibft_model.descs ),
.complete = ibft_complete,
.install = ibft_install,
}
static int ibft_install(int(*install)(struct acpi_header *acpi))
Install iBFT.
Definition ibft.c:553
static int ibft_complete(struct acpi_descriptor *desc)
Check if iBFT descriptor is complete.
Definition ibft.c:536
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31

iBFT model

aBFT model

Definition at line 692 of file ibft.c.

692 {
693 .descs = LIST_HEAD_INIT ( ibft_model.descs ),
694 .complete = ibft_complete,
695 .install = ibft_install,
696};