iPXE
efi_path.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19 
20 FILE_LICENCE ( GPL2_OR_LATER );
21 
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <byteswap.h>
27 #include <ipxe/netdevice.h>
28 #include <ipxe/vlan.h>
29 #include <ipxe/uuid.h>
30 #include <ipxe/tcpip.h>
31 #include <ipxe/uri.h>
32 #include <ipxe/iscsi.h>
33 #include <ipxe/aoe.h>
34 #include <ipxe/fcp.h>
35 #include <ipxe/ib_srp.h>
36 #include <ipxe/usb.h>
37 #include <ipxe/settings.h>
38 #include <ipxe/dhcp.h>
39 #include <ipxe/efi/efi.h>
40 #include <ipxe/efi/efi_driver.h>
41 #include <ipxe/efi/efi_path.h>
42 
43 /** @file
44  *
45  * EFI device paths
46  *
47  */
48 
49 /** An EFI device path settings block */
51  /** Settings interface */
53  /** Device path */
55 };
56 
57 /** An EFI device path setting */
59  /** Setting */
60  const struct setting *setting;
61  /**
62  * Fetch setting
63  *
64  * @v pathset Path setting
65  * @v path Device path
66  * @v data Buffer to fill with setting data
67  * @v len Length of buffer
68  * @ret len Length of setting data, or negative error
69  */
70  int ( * fetch ) ( struct efi_path_setting *pathset,
72  void *data, size_t len );
73  /** Path type */
75  /** Path subtype */
77  /** Offset within device path */
79  /** Length (if fixed) */
81 };
82 
83 /**
84  * Find next element in device path
85  *
86  * @v path Device path, or NULL
87  * @v next Next element in device path, or NULL if at end
88  */
90 
91  /* Check for non-existent device path */
92  if ( ! path )
93  return NULL;
94 
95  /* Check for end of device path */
96  if ( path->Type == END_DEVICE_PATH_TYPE )
97  return NULL;
98 
99  /* Move to next component of the device path */
100  path = ( ( ( void * ) path ) +
101  /* There's this amazing new-fangled thing known as
102  * a UINT16, but who wants to use one of those? */
103  ( ( path->Length[1] << 8 ) | path->Length[0] ) );
104 
105  return path;
106 }
107 
108 /**
109  * Find previous element of device path
110  *
111  * @v path Device path, or NULL for no path
112  * @v curr Current element in device path, or NULL for end of path
113  * @ret prev Previous element in device path, or NULL
114  */
116  EFI_DEVICE_PATH_PROTOCOL *curr ) {
118 
119  /* Find immediately preceding element */
120  while ( ( tmp = efi_path_next ( path ) ) != curr ) {
121  path = tmp;
122  }
123 
124  return path;
125 }
126 
127 /**
128  * Find end of device path
129  *
130  * @v path Device path, or NULL
131  * @ret path_end End of device path, or NULL
132  */
134 
135  return efi_path_prev ( path, NULL );
136 }
137 
138 /**
139  * Find length of device path (excluding terminator)
140  *
141  * @v path Device path, or NULL
142  * @ret path_len Length of device path
143  */
146 
147  return ( ( ( void * ) end ) - ( ( void * ) path ) );
148 }
149 
150 /**
151  * Get MAC address from device path
152  *
153  * @v path Device path
154  * @ret mac MAC address, or NULL if not found
155  */
159 
160  /* Search for MAC address path */
161  for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
162  if ( ( path->Type == MESSAGING_DEVICE_PATH ) &&
163  ( path->SubType == MSG_MAC_ADDR_DP ) ) {
165  Header );
166  return &mac->MacAddress;
167  }
168  }
169 
170  /* No MAC address found */
171  return NULL;
172 }
173 
174 /**
175  * Get VLAN tag from device path
176  *
177  * @v path Device path
178  * @ret tag VLAN tag, or 0 if not a VLAN
179  */
180 unsigned int efi_path_vlan ( EFI_DEVICE_PATH_PROTOCOL *path ) {
182  VLAN_DEVICE_PATH *vlan;
183 
184  /* Search for VLAN device path */
185  for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
186  if ( ( path->Type == MESSAGING_DEVICE_PATH ) &&
187  ( path->SubType == MSG_VLAN_DP ) ) {
188  vlan = container_of ( path, VLAN_DEVICE_PATH, Header );
189  return vlan->VlanId;
190  }
191  }
192 
193  /* No VLAN device path found */
194  return 0;
195 }
196 
197 /**
198  * Get partition GUID from device path
199  *
200  * @v path Device path
201  * @v guid Partition GUID to fill in
202  * @ret rc Return status code
203  */
207  int rc;
208 
209  /* Search for most specific partition device path */
210  rc = -ENOENT;
211  for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
212 
213  /* Skip non-harddrive device paths */
214  if ( path->Type != MEDIA_DEVICE_PATH )
215  continue;
216  if ( path->SubType != MEDIA_HARDDRIVE_DP )
217  continue;
218 
219  /* Skip non-GUID signatures */
220  hd = container_of ( path, HARDDRIVE_DEVICE_PATH, Header );
221  if ( hd->SignatureType != SIGNATURE_TYPE_GUID )
222  continue;
223 
224  /* Extract GUID */
225  memcpy ( guid, hd->Signature, sizeof ( *guid ) );
226  uuid_mangle ( guid );
227 
228  /* Record success, but continue searching in case
229  * there exists a more specific GUID (e.g. a partition
230  * GUID rather than a disk GUID).
231  */
232  rc = 0;
233  }
234 
235  return rc;
236 }
237 
238 /**
239  * Parse URI from device path
240  *
241  * @v path Device path
242  * @ret uri URI, or NULL if not a URI
243  */
246  URI_DEVICE_PATH *uripath;
247  char *uristring;
248  struct uri *uri;
249  size_t len;
250 
251  /* Search for URI device path */
252  for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
253  if ( ( path->Type == MESSAGING_DEVICE_PATH ) &&
254  ( path->SubType == MSG_URI_DP ) ) {
255 
256  /* Calculate path length */
257  uripath = container_of ( path, URI_DEVICE_PATH,
258  Header );
259  len = ( ( ( path->Length[1] << 8 ) | path->Length[0] )
260  - offsetof ( typeof ( *uripath ), Uri ) );
261 
262  /* Parse URI */
263  uristring = zalloc ( len + 1 /* NUL */ );
264  if ( ! uristring )
265  return NULL;
266  memcpy ( uristring, uripath->Uri, len );
267  uri = parse_uri ( uristring );
268  free ( uristring );
269 
270  return uri;
271  }
272  }
273 
274  /* No URI path found */
275  return NULL;
276 }
277 
278 /**
279  * Concatenate EFI device paths
280  *
281  * @v ... List of device paths (NULL terminated)
282  * @ret path Concatenated device path, or NULL on error
283  *
284  * The caller is responsible for eventually calling free() on the
285  * allocated device path.
286  */
292  va_list args;
293  size_t len;
294 
295  /* Calculate device path length */
296  va_start ( args, first );
297  len = 0;
298  src = first;
299  while ( src ) {
300  len += efi_path_len ( src );
301  src = va_arg ( args, EFI_DEVICE_PATH_PROTOCOL * );
302  }
303  va_end ( args );
304 
305  /* Allocate device path */
306  path = zalloc ( len + sizeof ( *end ) );
307  if ( ! path )
308  return NULL;
309 
310  /* Populate device path */
311  va_start ( args, first );
312  dst = path;
313  src = first;
314  while ( src ) {
315  len = efi_path_len ( src );
316  memcpy ( dst, src, len );
317  dst = ( ( ( void * ) dst ) + len );
318  src = va_arg ( args, EFI_DEVICE_PATH_PROTOCOL * );
319  }
320  va_end ( args );
321  end = dst;
323 
324  return path;
325 }
326 
327 /**
328  * Construct EFI device path for network device
329  *
330  * @v netdev Network device
331  * @ret path EFI device path, or NULL on error
332  *
333  * The caller is responsible for eventually calling free() on the
334  * allocated device path.
335  */
337  struct efi_device *efidev;
339  MAC_ADDR_DEVICE_PATH *macpath;
340  VLAN_DEVICE_PATH *vlanpath;
342  unsigned int tag;
343  size_t prefix_len;
344  size_t len;
345 
346  /* Find parent EFI device */
347  efidev = efidev_parent ( netdev->dev );
348  if ( ! efidev )
349  return NULL;
350 
351  /* Calculate device path length */
352  prefix_len = efi_path_len ( efidev->path );
353  len = ( prefix_len + sizeof ( *macpath ) + sizeof ( *vlanpath ) +
354  sizeof ( *end ) );
355 
356  /* Allocate device path */
357  path = zalloc ( len );
358  if ( ! path )
359  return NULL;
360 
361  /* Construct device path */
362  memcpy ( path, efidev->path, prefix_len );
363  macpath = ( ( ( void * ) path ) + prefix_len );
364  macpath->Header.Type = MESSAGING_DEVICE_PATH;
365  macpath->Header.SubType = MSG_MAC_ADDR_DP;
366  macpath->Header.Length[0] = sizeof ( *macpath );
368  sizeof ( macpath->MacAddress ) );
369  memcpy ( &macpath->MacAddress, netdev->ll_addr,
371  macpath->IfType = ntohs ( netdev->ll_protocol->ll_proto );
372  if ( ( tag = vlan_tag ( netdev ) ) ) {
373  vlanpath = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
374  vlanpath->Header.Type = MESSAGING_DEVICE_PATH;
375  vlanpath->Header.SubType = MSG_VLAN_DP;
376  vlanpath->Header.Length[0] = sizeof ( *vlanpath );
377  vlanpath->VlanId = tag;
378  end = ( ( ( void * ) vlanpath ) + sizeof ( *vlanpath ) );
379  } else {
380  end = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
381  }
383 
384  return path;
385 }
386 
387 /**
388  * Construct EFI device path for URI
389  *
390  * @v uri URI
391  * @ret path EFI device path, or NULL on error
392  *
393  * The caller is responsible for eventually calling free() on the
394  * allocated device path.
395  */
399  URI_DEVICE_PATH *uripath;
400  size_t uri_len;
401  size_t uripath_len;
402  size_t len;
403 
404  /* Calculate device path length */
405  uri_len = ( format_uri ( uri, NULL, 0 ) + 1 /* NUL */ );
406  uripath_len = ( sizeof ( *uripath ) + uri_len );
407  len = ( uripath_len + sizeof ( *end ) );
408 
409  /* Allocate device path */
410  path = zalloc ( len );
411  if ( ! path )
412  return NULL;
413 
414  /* Construct device path */
415  uripath = ( ( void * ) path );
416  uripath->Header.Type = MESSAGING_DEVICE_PATH;
417  uripath->Header.SubType = MSG_URI_DP;
418  uripath->Header.Length[0] = ( uripath_len & 0xff );
419  uripath->Header.Length[1] = ( uripath_len >> 8 );
420  format_uri ( uri, uripath->Uri, uri_len );
421  end = ( ( ( void * ) path ) + uripath_len );
423 
424  return path;
425 }
426 
427 /**
428  * Construct EFI device path for iSCSI device
429  *
430  * @v iscsi iSCSI session
431  * @ret path EFI device path, or NULL on error
432  */
434  struct sockaddr_tcpip *st_target;
435  struct net_device *netdev;
436  EFI_DEVICE_PATH_PROTOCOL *netpath;
439  ISCSI_DEVICE_PATH *iscsipath;
440  char *name;
441  size_t prefix_len;
442  size_t name_len;
443  size_t iscsi_len;
444  size_t len;
445 
446  /* Get network device associated with target address */
447  st_target = ( ( struct sockaddr_tcpip * ) &iscsi->target_sockaddr );
448  netdev = tcpip_netdev ( st_target );
449  if ( ! netdev )
450  goto err_netdev;
451 
452  /* Get network device path */
453  netpath = efi_netdev_path ( netdev );
454  if ( ! netpath )
455  goto err_netpath;
456 
457  /* Calculate device path length */
458  prefix_len = efi_path_len ( netpath );
459  name_len = ( strlen ( iscsi->target_iqn ) + 1 /* NUL */ );
460  iscsi_len = ( sizeof ( *iscsipath ) + name_len );
461  len = ( prefix_len + iscsi_len + sizeof ( *end ) );
462 
463  /* Allocate device path */
464  path = zalloc ( len );
465  if ( ! path )
466  goto err_alloc;
467 
468  /* Construct device path */
469  memcpy ( path, netpath, prefix_len );
470  iscsipath = ( ( ( void * ) path ) + prefix_len );
471  iscsipath->Header.Type = MESSAGING_DEVICE_PATH;
472  iscsipath->Header.SubType = MSG_ISCSI_DP;
473  iscsipath->Header.Length[0] = iscsi_len;
475  memcpy ( &iscsipath->Lun, &iscsi->lun, sizeof ( iscsipath->Lun ) );
476  name = ( ( ( void * ) iscsipath ) + sizeof ( *iscsipath ) );
477  memcpy ( name, iscsi->target_iqn, name_len );
478  end = ( ( ( void * ) name ) + name_len );
480 
481  /* Free temporary paths */
482  free ( netpath );
483 
484  return path;
485 
486  err_alloc:
487  free ( netpath );
488  err_netpath:
489  err_netdev:
490  return NULL;
491 }
492 
493 /**
494  * Construct EFI device path for AoE device
495  *
496  * @v aoedev AoE device
497  * @ret path EFI device path, or NULL on error
498  */
500  struct {
501  SATA_DEVICE_PATH sata;
503  } satapath;
504  EFI_DEVICE_PATH_PROTOCOL *netpath;
506 
507  /* Get network device path */
508  netpath = efi_netdev_path ( aoedev->netdev );
509  if ( ! netpath )
510  goto err_netdev;
511 
512  /* Construct SATA path */
513  memset ( &satapath, 0, sizeof ( satapath ) );
514  satapath.sata.Header.Type = MESSAGING_DEVICE_PATH;
515  satapath.sata.Header.SubType = MSG_SATA_DP;
516  satapath.sata.Header.Length[0] = sizeof ( satapath.sata );
517  satapath.sata.HBAPortNumber = aoedev->major;
518  satapath.sata.PortMultiplierPortNumber = aoedev->minor;
519  efi_path_terminate ( &satapath.end );
520 
521  /* Construct overall device path */
522  path = efi_paths ( netpath, &satapath, NULL );
523  if ( ! path )
524  goto err_paths;
525 
526  /* Free temporary paths */
527  free ( netpath );
528 
529  return path;
530 
531  err_paths:
532  free ( netpath );
533  err_netdev:
534  return NULL;
535 }
536 
537 /**
538  * Construct EFI device path for Fibre Channel device
539  *
540  * @v desc FCP device description
541  * @ret path EFI device path, or NULL on error
542  */
544  struct {
547  } __attribute__ (( packed )) *path;
548 
549  /* Allocate device path */
550  path = zalloc ( sizeof ( *path ) );
551  if ( ! path )
552  return NULL;
553 
554  /* Construct device path */
555  path->fc.Header.Type = MESSAGING_DEVICE_PATH;
556  path->fc.Header.SubType = MSG_FIBRECHANNELEX_DP;
557  path->fc.Header.Length[0] = sizeof ( path->fc );
558  memcpy ( path->fc.WWN, &desc->wwn, sizeof ( path->fc.WWN ) );
559  memcpy ( path->fc.Lun, &desc->lun, sizeof ( path->fc.Lun ) );
560  efi_path_terminate ( &path->end );
561 
562  return &path->fc.Header;
563 }
564 
565 /**
566  * Construct EFI device path for Infiniband SRP device
567  *
568  * @v ib_srp Infiniband SRP device
569  * @ret path EFI device path, or NULL on error
570  */
572  const struct ipxe_ib_sbft *sbft = &ib_srp->sbft;
573  union ib_srp_target_port_id *id =
575  srp );
576  struct efi_device *efidev;
578  INFINIBAND_DEVICE_PATH *ibpath;
580  size_t prefix_len;
581  size_t len;
582 
583  /* Find parent EFI device */
584  efidev = efidev_parent ( ib_srp->ibdev->dev );
585  if ( ! efidev )
586  return NULL;
587 
588  /* Calculate device path length */
589  prefix_len = efi_path_len ( efidev->path );
590  len = ( prefix_len + sizeof ( *ibpath ) + sizeof ( *end ) );
591 
592  /* Allocate device path */
593  path = zalloc ( len );
594  if ( ! path )
595  return NULL;
596 
597  /* Construct device path */
598  memcpy ( path, efidev->path, prefix_len );
599  ibpath = ( ( ( void * ) path ) + prefix_len );
601  ibpath->Header.SubType = MSG_INFINIBAND_DP;
602  ibpath->Header.Length[0] = sizeof ( *ibpath );
604  memcpy ( ibpath->PortGid, &sbft->ib.dgid, sizeof ( ibpath->PortGid ) );
605  memcpy ( &ibpath->ServiceId, &sbft->ib.service_id,
606  sizeof ( ibpath->ServiceId ) );
607  memcpy ( &ibpath->TargetPortId, &id->ib.ioc_guid,
608  sizeof ( ibpath->TargetPortId ) );
609  memcpy ( &ibpath->DeviceId, &id->ib.id_ext,
610  sizeof ( ibpath->DeviceId ) );
611  end = ( ( ( void * ) ibpath ) + sizeof ( *ibpath ) );
613 
614  return path;
615 }
616 
617 /**
618  * Construct EFI device path for USB function
619  *
620  * @v func USB function
621  * @ret path EFI device path, or NULL on error
622  *
623  * The caller is responsible for eventually calling free() on the
624  * allocated device path.
625  */
627  struct usb_device *usb = func->usb;
628  struct efi_device *efidev;
631  USB_DEVICE_PATH *usbpath;
632  unsigned int count;
633  size_t prefix_len;
634  size_t len;
635 
636  /* Sanity check */
637  assert ( func->desc.count >= 1 );
638 
639  /* Find parent EFI device */
640  efidev = efidev_parent ( &func->dev );
641  if ( ! efidev )
642  return NULL;
643 
644  /* Calculate device path length */
645  count = ( usb_depth ( usb ) + 1 );
646  prefix_len = efi_path_len ( efidev->path );
647  len = ( prefix_len + ( count * sizeof ( *usbpath ) ) +
648  sizeof ( *end ) );
649 
650  /* Allocate device path */
651  path = zalloc ( len );
652  if ( ! path )
653  return NULL;
654 
655  /* Construct device path */
656  memcpy ( path, efidev->path, prefix_len );
657  end = ( ( ( void * ) path ) + len - sizeof ( *end ) );
659  usbpath = ( ( ( void * ) end ) - sizeof ( *usbpath ) );
660  usbpath->InterfaceNumber = func->interface[0];
661  for ( ; usb ; usbpath--, usb = usb->port->hub->usb ) {
662  usbpath->Header.Type = MESSAGING_DEVICE_PATH;
663  usbpath->Header.SubType = MSG_USB_DP;
664  usbpath->Header.Length[0] = sizeof ( *usbpath );
665  usbpath->ParentPortNumber = ( usb->port->address - 1 );
666  }
667 
668  return path;
669 }
670 
671 /**
672  * Describe object as an EFI device path
673  *
674  * @v intf Interface
675  * @ret path EFI device path, or NULL
676  *
677  * The caller is responsible for eventually calling free() on the
678  * allocated device path.
679  */
681  struct interface *dest;
682  efi_describe_TYPE ( void * ) *op =
684  void *object = intf_object ( dest );
686 
687  if ( op ) {
688  path = op ( object );
689  } else {
690  path = NULL;
691  }
692 
693  intf_put ( dest );
694  return path;
695 }
696 
697 /**
698  * Fetch an EFI device path fixed-size setting
699  *
700  * @v pathset Path setting
701  * @v path Device path
702  * @v data Buffer to fill with setting data
703  * @v len Length of buffer
704  * @ret len Length of setting data, or negative error
705  */
706 static int efi_path_fetch_fixed ( struct efi_path_setting *pathset,
708  void *data, size_t len ) {
709 
710  /* Copy data */
711  if ( len > pathset->len )
712  len = pathset->len;
713  memcpy ( data, ( ( ( void * ) path ) + pathset->offset ), len );
714 
715  return pathset->len;
716 }
717 
718 /**
719  * Fetch an EFI device path DNS setting
720  *
721  * @v pathset Path setting
722  * @v path Device path
723  * @v data Buffer to fill with setting data
724  * @v len Length of buffer
725  * @ret len Length of setting data, or negative error
726  */
727 static int efi_path_fetch_dns ( struct efi_path_setting *pathset,
729  void *data, size_t len ) {
731  unsigned int count;
732  unsigned int i;
733  size_t frag_len;
734 
735  /* Check applicability */
736  if ( ( !! dns->IsIPv6 ) !=
737  ( pathset->setting->type == &setting_type_ipv6 ) )
738  return -ENOENT;
739 
740  /* Calculate number of addresses */
741  count = ( ( ( ( path->Length[1] << 8 ) | path->Length[0] ) -
742  pathset->offset ) / sizeof ( dns->DnsServerIp[0] ) );
743 
744  /* Copy data */
745  for ( i = 0 ; i < count ; i++ ) {
746  frag_len = len;
747  if ( frag_len > pathset->len )
748  frag_len = pathset->len;
749  memcpy ( data, &dns->DnsServerIp[i], frag_len );
750  data += frag_len;
751  len -= frag_len;
752  }
753 
754  return ( count * pathset->len );
755 }
756 
757 /** EFI device path settings */
760  MSG_IPv4_DP, offsetof ( IPv4_DEVICE_PATH, LocalIpAddress ),
761  sizeof ( struct in_addr ) },
762  { &netmask_setting, efi_path_fetch_fixed, MESSAGING_DEVICE_PATH,
763  MSG_IPv4_DP, offsetof ( IPv4_DEVICE_PATH, SubnetMask ),
764  sizeof ( struct in_addr ) },
765  { &gateway_setting, efi_path_fetch_fixed, MESSAGING_DEVICE_PATH,
766  MSG_IPv4_DP, offsetof ( IPv4_DEVICE_PATH, GatewayIpAddress ),
767  sizeof ( struct in_addr ) },
769  MSG_IPv6_DP, offsetof ( IPv6_DEVICE_PATH, LocalIpAddress ),
770  sizeof ( struct in6_addr ) },
772  MSG_IPv6_DP, offsetof ( IPv6_DEVICE_PATH, PrefixLength ),
773  sizeof ( uint8_t ) },
774  { &gateway6_setting, efi_path_fetch_fixed, MESSAGING_DEVICE_PATH,
775  MSG_IPv6_DP, offsetof ( IPv6_DEVICE_PATH, GatewayIpAddress ),
776  sizeof ( struct in6_addr ) },
777  { &dns_setting, efi_path_fetch_dns, MESSAGING_DEVICE_PATH,
778  MSG_DNS_DP, offsetof ( DNS_DEVICE_PATH, DnsServerIp ),
779  sizeof ( struct in_addr ) },
780  { &dns6_setting, efi_path_fetch_dns, MESSAGING_DEVICE_PATH,
781  MSG_DNS_DP, offsetof ( DNS_DEVICE_PATH, DnsServerIp ),
782  sizeof ( struct in6_addr ) },
783 };
784 
785 /**
786  * Fetch value of EFI device path setting
787  *
788  * @v settings Settings block
789  * @v setting Setting to fetch
790  * @v data Buffer to fill with setting data
791  * @v len Length of buffer
792  * @ret len Length of setting data, or negative error
793  */
794 static int efi_path_fetch ( struct settings *settings, struct setting *setting,
795  void *data, size_t len ) {
796  struct efi_path_settings *pathsets =
798  EFI_DEVICE_PATH_PROTOCOL *path = pathsets->path;
800  struct efi_path_setting *pathset;
801  unsigned int i;
802  int ret;
803 
804  /* Find matching path setting, if any */
805  for ( i = 0 ; i < ( sizeof ( efi_path_settings ) /
806  sizeof ( efi_path_settings[0] ) ) ; i++ ) {
807 
808  /* Check for a matching setting */
809  pathset = &efi_path_settings[i];
810  if ( setting_cmp ( setting, pathset->setting ) != 0 )
811  continue;
812 
813  /* Find matching device path element, if any */
814  for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
815 
816  /* Check for a matching path type */
817  if ( ( path->Type != pathset->type ) ||
818  ( path->SubType != pathset->subtype ) )
819  continue;
820 
821  /* Fetch value */
822  if ( ( ret = pathset->fetch ( pathset, path,
823  data, len ) ) < 0 )
824  return ret;
825 
826  /* Apply default type, if not already set */
827  if ( ! setting->type )
828  setting->type = pathset->setting->type;
829 
830  return ret;
831  }
832  break;
833  }
834 
835  return -ENOENT;
836 }
837 
838 /** EFI device path settings operations */
841 };
842 
843 /**
844  * Create per-netdevice EFI path settings
845  *
846  * @v netdev Network device
847  * @v priv Private data
848  * @ret rc Return status code
849  */
850 static int efi_path_net_probe ( struct net_device *netdev, void *priv ) {
851  struct efi_path_settings *pathsets = priv;
852  struct settings *settings = &pathsets->settings;
854  unsigned int vlan;
855  void *mac;
856  int rc;
857 
858  /* Check applicability */
859  pathsets->path = path;
860  mac = efi_path_mac ( path );
861  vlan = efi_path_vlan ( path );
862  if ( ( mac == NULL ) ||
863  ( memcmp ( mac, netdev->ll_addr,
864  netdev->ll_protocol->ll_addr_len ) != 0 ) ||
865  ( vlan != vlan_tag ( netdev ) ) ) {
866  DBGC ( settings, "EFI path %s does not apply to %s\n",
867  efi_devpath_text ( path ), netdev->name );
868  return 0;
869  }
870 
871  /* Never override a real DHCP settings block */
873  DHCP_SETTINGS_NAME ) ) {
874  DBGC ( settings, "EFI path %s not overriding %s DHCP "
875  "settings\n", efi_devpath_text ( path ), netdev->name );
876  return 0;
877  }
878 
879  /* Initialise and register settings */
881  &netdev->refcnt, NULL );
883  DHCP_SETTINGS_NAME ) ) != 0 ) {
884  DBGC ( settings, "EFI path %s could not register for %s: %s\n",
885  efi_devpath_text ( path ), netdev->name,
886  strerror ( rc ) );
887  return rc;
888  }
889  DBGC ( settings, "EFI path %s registered for %s\n",
890  efi_devpath_text ( path ), netdev->name );
891 
892  return 0;
893 }
894 
895 /** EFI path settings per-netdevice driver */
896 struct net_driver efi_path_net_driver __net_driver = {
897  .name = "EFI path",
898  .priv_len = sizeof ( struct efi_path_settings ),
899  .probe = efi_path_net_probe,
900 };
static int efi_path_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of EFI device path setting.
Definition: efi_path.c:794
#define MSG_FIBRECHANNELEX_DP
Fibre Channel Ex SubType.
Definition: DevicePath.h:384
#define __attribute__(x)
Definition: compiler.h:10
TCP/IP socket address.
Definition: tcpip.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
unsigned int efi_path_vlan(EFI_DEVICE_PATH_PROTOCOL *path)
Get VLAN tag from device path.
Definition: efi_path.c:180
union srp_port_id srp
SRP version of port identifier.
Definition: ib_srp.h:34
Dynamic Host Configuration Protocol.
#define va_end(ap)
Definition: stdarg.h:9
struct net_device * tcpip_netdev(struct sockaddr_tcpip *st_dest)
Determine transmitting network device.
Definition: tcpip.c:114
#define ISCSI_LOGIN_OPTION_AUTHMETHOD_NON
Definition: DevicePath.h:939
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
EFI driver interface.
struct ipxe_ib_sbft sbft
Boot firmware table parameters.
Definition: ib_srp.h:90
uint8_t interface[0]
List of interface numbers.
Definition: usb.h:682
An iSCSI session.
Definition: iscsi.h:544
#define END_DEVICE_PATH_TYPE
Definition: DevicePath.h:1371
struct sockaddr target_sockaddr
Target socket address (for boot firmware table)
Definition: iscsi.h:661
uint8_t offset
Offset within device path.
Definition: efi_path.c:78
unsigned int count
Number of interfaces.
Definition: usb.h:650
uint32_t next
Next descriptor address.
Definition: myson.h:18
Error codes.
UINT8 IfType
Network interface type(i.e.
Definition: DevicePath.h:562
A universally unique ID.
Definition: uuid.h:15
int(* fetch)(struct efi_path_setting *pathset, EFI_DEVICE_PATH_PROTOCOL *path, void *data, size_t len)
Fetch setting.
Definition: efi_path.c:70
UINT8 SignatureType
Type of Disk Signature: (Unused values reserved).
Definition: DevicePath.h:1038
u16 fc
802.11 Frame Control field
Definition: ieee80211.h:14
#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL
Definition: DevicePath.h:688
static void const void void * dst
Definition: crypto.h:244
SRP target port identifier for Infiniband.
Definition: ib_srp.h:32
EFI_MAC_ADDRESS MacAddress
The MAC address for a network interface padded with 0s.
Definition: DevicePath.h:558
static void const void * src
Definition: crypto.h:244
uint16_t major
Major number.
Definition: aoe.h:125
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define DBGC(...)
Definition: compiler.h:505
EFI_DEVICE_PATH_PROTOCOL * path
Device path.
Definition: efi_path.c:54
#define ENOENT
No such file or directory.
Definition: errno.h:514
struct device * dev
Underlying device.
Definition: infiniband.h:410
union srp_port_id target
Target port identifier.
Definition: srp.h:819
static struct settings_operations efi_path_settings_operations
EFI device path settings operations.
Definition: efi_path.c:839
Universally unique IDs.
struct settings settings
Settings interface.
Definition: efi_path.c:52
static int efi_path_fetch_fixed(struct efi_path_setting *pathset, EFI_DEVICE_PATH_PROTOCOL *path, void *data, size_t len)
Fetch an EFI device path fixed-size setting.
Definition: efi_path.c:706
#define MSG_MAC_ADDR_DP
MAC Address Device Path SubType.
Definition: DevicePath.h:552
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:144
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:655
#define ntohs(value)
Definition: byteswap.h:136
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:554
struct net_driver efi_path_net_driver __net_driver
EFI path settings per-netdevice driver.
Definition: efi_path.c:896
union ib_gid dgid
Destination GID.
Definition: ib_srp.h:51
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:45
EFI_DEVICE_PATH_PROTOCOL * efi_uri_path(struct uri *uri)
Construct EFI device path for URI.
Definition: efi_path.c:396
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
UINT16 LoginOption
iSCSI Login Options.
Definition: DevicePath.h:917
Uniform Resource Identifiers.
An EFI device path settings block.
Definition: efi_path.c:50
uint8_t type
Path type.
Definition: efi_path.c:74
#define MESSAGING_DEVICE_PATH
Messaging Device Paths.
Definition: DevicePath.h:323
An EFI device path setting.
Definition: efi_path.c:58
UINT32 ResourceFlags
Flags to help identify/manage InfiniBand device path elements: Bit 0 - IOC/Service (0b = IOC,...
Definition: DevicePath.h:665
A network upper-layer driver.
Definition: netdevice.h:473
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:583
static void settings_init(struct settings *settings, struct settings_operations *op, struct refcnt *refcnt, const struct settings_scope *default_scope)
Initialise a settings block.
Definition: settings.h:500
An AoE device.
Definition: aoe.h:115
void * intf_object(struct interface *intf)
Get pointer to object containing object interface.
Definition: interface.c:159
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition: efi_path.h:30
EFI_DEVICE_PATH_PROTOCOL * efi_path_prev(EFI_DEVICE_PATH_PROTOCOL *path, EFI_DEVICE_PATH_PROTOCOL *curr)
Find previous element of device path.
Definition: efi_path.c:115
struct interface * intf
Original interface.
Definition: interface.h:158
static void uuid_mangle(union uuid *uuid)
Change UUID endianness.
Definition: uuid.h:43
EFI_DEVICE_PATH_PROTOCOL * efi_paths(EFI_DEVICE_PATH_PROTOCOL *first,...)
Concatenate EFI device paths.
Definition: efi_path.c:287
unsigned long tmp
Definition: linux_pci.h:53
EFI_IP_ADDRESS DnsServerIp[]
Instance of the DNS server address.
Definition: DevicePath.h:855
struct usb_device * usb
Underlying USB device, if any.
Definition: usb.h:832
#define MSG_URI_DP
Uniform Resource Identifiers (URI) Device Path SubType.
Definition: DevicePath.h:861
EFI_DEVICE_PATH_PROTOCOL * efi_loaded_image_path
Device path for the loaded image's device handle.
Definition: efi_init.c:40
AoE protocol.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
const char * name
Name.
Definition: netdevice.h:475
#define va_arg(ap, type)
Definition: stdarg.h:8
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:863
struct usb_port * port
USB port.
Definition: usb.h:712
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
Fibre Channel Protocol.
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
An object interface.
Definition: interface.h:124
#define MEDIA_HARDDRIVE_DP
Hard Drive Media Device Path SubType.
Definition: DevicePath.h:996
#define DHCP_SETTINGS_NAME
Settings block name used for DHCP responses.
Definition: dhcp.h:708
struct sbft_srp_subtable srp
The SRP subtable.
Definition: ib_srp.h:69
const char * path
Path (after URI decoding)
Definition: uri.h:80
#define MSG_SATA_DP
SATA Device Path SubType.
Definition: DevicePath.h:512
iSCSI protocol
static struct net_device * netdev
Definition: gdbudp.c:52
UINT8 ParentPortNumber
USB Parent Port Number.
Definition: DevicePath.h:426
Transport-network layer interface.
void * efi_path_mac(EFI_DEVICE_PATH_PROTOCOL *path)
Get MAC address from device path.
Definition: efi_path.c:156
UINT16 VlanId
VLAN identifier (0-4094).
Definition: DevicePath.h:952
size_t format_uri(const struct uri *uri, char *buf, size_t len)
Format URI.
Definition: uri.c:471
const struct setting_type * type
Setting type.
Definition: settings.h:36
An Infiniband SRP sBFT created by iPXE.
Definition: ib_srp.h:63
IP6 address structure.
Definition: in.h:48
#define MSG_IPv4_DP
IPv4 Device Path SubType.
Definition: DevicePath.h:568
EFI_DEVICE_PATH_PROTOCOL * efi_fcp_path(struct fcp_description *desc)
Construct EFI device path for Fibre Channel device.
Definition: efi_path.c:543
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition: efi_debug.c:461
UINT64 Lun
iSCSI Logical Unit Number.
Definition: DevicePath.h:921
union ib_guid service_id
Service ID.
Definition: ib_srp.h:53
static void * dest
Definition: strings.h:176
A USB device.
Definition: usb.h:708
static unsigned int usb_depth(struct usb_device *usb)
Get USB depth.
Definition: usb.h:1248
CHAR8 Uri[]
Instance of the URI pursuant to RFC 3986.
Definition: DevicePath.h:867
EFI_DEVICE_PATH_PROTOCOL * efi_ib_srp_path(struct ib_srp_device *ib_srp)
Construct EFI device path for Infiniband SRP device.
Definition: efi_path.c:571
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:422
Configuration settings.
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path(struct net_device *netdev)
Construct EFI device path for network device.
Definition: efi_path.c:336
uint8_t id
Request identifier.
Definition: ena.h:12
struct refcnt refcnt
Reference counter.
Definition: netdevice.h:354
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
EFI_DEVICE_PATH_PROTOCOL * efi_usb_path(struct usb_function *func)
Construct EFI device path for USB function.
Definition: efi_path.c:626
struct scsi_lun lun
SCSI LUN (for boot firmware table)
Definition: iscsi.h:663
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
IP address structure.
Definition: in.h:39
UINT8 InterfaceNumber
USB Interface Number.
Definition: DevicePath.h:430
static int efi_path_net_probe(struct net_device *netdev, void *priv)
Create per-netdevice EFI path settings.
Definition: efi_path.c:850
A network device.
Definition: netdevice.h:352
#define MSG_ISCSI_DP
iSCSI Device Path SubType
Definition: DevicePath.h:907
#define MSG_IPv6_DP
IPv6 Device Path SubType.
Definition: DevicePath.h:609
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
Settings block operations.
Definition: settings.h:85
UINT64 DeviceId
64-bit persistent ID of remote device.
Definition: DevicePath.h:682
A settings block.
Definition: settings.h:132
#define MSG_INFINIBAND_DP
InfiniBand Device Path SubType.
Definition: DevicePath.h:653
unsigned char uint8_t
Definition: stdint.h:10
#define MSG_DNS_DP
DNS Device Path SubType.
Definition: DevicePath.h:845
EFI device paths.
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:991
An EFI device.
Definition: efi_driver.h:17
struct usb_device * usb
USB device.
Definition: usb.h:663
An Infiniband SRP device.
Definition: ib_srp.h:75
uint16_t ll_proto
Link-layer protocol.
Definition: netdevice.h:194
EFI_DEVICE_PATH_PROTOCOL * efi_path_next(EFI_DEVICE_PATH_PROTOCOL *path)
Find next element in device path.
Definition: efi_path.c:89
An FCP device description.
Definition: fcp.h:167
EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path(struct iscsi_session *iscsi)
Construct EFI device path for iSCSI device.
Definition: efi_path.c:433
static int efi_path_fetch_dns(struct efi_path_setting *pathset, EFI_DEVICE_PATH_PROTOCOL *path, void *data, size_t len)
Fetch an EFI device path DNS setting.
Definition: efi_path.c:727
uint8_t len
Length (if fixed)
Definition: efi_path.c:80
EFI API.
A setting.
Definition: settings.h:23
uint64_t guid
GUID.
Definition: edd.h:30
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
UINT64 TargetPortId
64-bit persistent ID of remote IOC port.
Definition: DevicePath.h:678
Network device management.
UINT8 Signature[16]
Signature unique to this partition: If SignatureType is 0, this field has to be initialized with 16 z...
Definition: DevicePath.h:1025
#define MSG_VLAN_DP
VLAN Device Path SubType.
Definition: DevicePath.h:946
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
UINT64 ServiceId
64-bit unique identifier to remote IOC or server process.
Definition: DevicePath.h:674
char * target_iqn
Target IQN.
Definition: iscsi.h:562
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition: efi_path.c:680
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
static struct efi_path_setting efi_path_settings[]
EFI device path settings.
Definition: efi_path.c:758
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:948
UINT8 Length[2]
Specific Device Path data.
Definition: DevicePath.h:58
uint32_t len
Length.
Definition: ena.h:14
SCSI RDMA Protocol over Infiniband.
UINT8 PortGid[16]
128-bit Global Identifier for remote fabric port.
Definition: DevicePath.h:669
static struct tlan_private * priv
Definition: tlan.c:224
__builtin_va_list va_list
Definition: stdarg.h:6
Universal Serial Bus (USB)
EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path(struct aoe_device *aoedev)
Construct EFI device path for AoE device.
Definition: efi_path.c:499
struct uri * efi_path_uri(EFI_DEVICE_PATH_PROTOCOL *path)
Parse URI from device path.
Definition: efi_path.c:244
struct ib_device * ibdev
Infiniband device.
Definition: ib_srp.h:85
struct usb_hub * hub
USB hub.
Definition: usb.h:800
UINT8 SubType
Varies by Type 0xFF End Entire Device Path, or 0x01 End This Instance of a Device Path and start a ne...
Definition: DevicePath.h:53
int(* fetch)(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.h:122
The Hard Drive Media Device Path is used to represent a partition on a hard drive.
Definition: DevicePath.h:1001
uint16_t count
Number of entries.
Definition: ena.h:22
const struct setting * setting
Setting.
Definition: efi_path.c:60
void intf_put(struct interface *intf)
Decrement reference count on an object interface.
Definition: interface.c:149
uint8_t minor
Minor number.
Definition: aoe.h:127
uint32_t end
Ending offset.
Definition: netvsc.h:18
struct net_device * netdev
Network device.
Definition: aoe.h:120
uint8_t data[48]
Additional event data.
Definition: ena.h:22
Virtual LANs.
struct sbft_ib_subtable ib
The Infiniband subtable.
Definition: ib_srp.h:71
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:46
struct usb_function_descriptor desc
Function descriptor.
Definition: usb.h:665
A Uniform Resource Identifier.
Definition: uri.h:64
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:475
EFI_DEVICE_PATH_PROTOCOL * path
EFI device path copy.
Definition: efi_driver.h:25
struct efi_device * efidev_parent(struct device *dev)
Get parent EFI device.
Definition: efi_driver.c:155
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
#define SIGNATURE_TYPE_GUID
Definition: DevicePath.h:1046
static unsigned int vlan_tag(struct net_device *netdev)
Get the VLAN tag.
Definition: vlan.h:73
#define va_start(ap, last)
Definition: stdarg.h:7
UINT8 IsIPv6
Indicates the DNS server address is IPv4 or IPv6 address.
Definition: DevicePath.h:851
struct settings * find_child_settings(struct settings *parent, const char *name)
Find child settings block.
Definition: settings.c:279
struct device dev
Generic device.
Definition: usb.h:667
A USB function.
Definition: usb.h:659
FILE_LICENCE(GPL2_OR_LATER)
uint64_t tag
Identity tag.
Definition: edd.h:30
uint8_t subtype
Path subtype.
Definition: efi_path.c:76
int setting_cmp(const struct setting *a, const struct setting *b)
Compare two settings.
Definition: settings.c:1120
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
EFI_DEVICE_PATH_PROTOCOL * efi_path_end(EFI_DEVICE_PATH_PROTOCOL *path)
Find end of device path.
Definition: efi_path.c:133
#define intf_get_dest_op(intf, type, dest)
Get object interface destination and operation method.
Definition: interface.h:269
int efi_path_guid(EFI_DEVICE_PATH_PROTOCOL *path, union uuid *guid)
Get partition GUID from device path.
Definition: efi_path.c:204
uint32_t first
Length to skip in first segment.
Definition: pccrc.h:23
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:909
#define MSG_USB_DP
USB Device Path SubType.
Definition: DevicePath.h:420
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
struct uri * parse_uri(const char *uri_string)
Parse URI.
Definition: uri.c:296
void * memset(void *dest, int character, size_t len) __nonnull
PACKED union @478::@492 Header
Definition: Acpi10.h:155
#define efi_describe_TYPE(object_type)
Definition: efi_path.h:63