[syslinux] [RFC, PATCH] core/pxe: Add architecture-specific discovery request for PXE config file

Jeremy Kerr jk at ozlabs.org
Mon Feb 24 00:14:13 PST 2014


Currently, the TFTP configuration file discovery process will request a
set of files based on the UUID, MAC address, lease IP address and
eventually fall back to "default":

  /mybootdir/pxelinux.cfg/b8945908-d6a6-41a9-611d-74a6ab80b83d
  /mybootdir/pxelinux.cfg/01-88-99-aa-bb-cc-dd
  /mybootdir/pxelinux.cfg/C000025B
  [...]
  /mybootdir/pxelinux.cfg/C
  /mybootdir/pxelinux.cfg/default

When serving PXE config files to machines of different architectures
(requiring separate boot images and config files), this means we
cannot use the autodisovery mechanism without having prior knowledge of
a MAC/IP/uuid-to-architecture mapping.

This change introduces an additional step to the autodiscovery process,
using a name based on the client machine architecture. I use IANA's
mapping of processor architecture types to DHCP option codes[1] to
define the available client architecture identifiers.

The identifier is converted to lowercase hex, and prefixed with "arch-".
So, for an x64 EFI machine (identifier 0x00 0x77), the discovery process
will be:

  /mybootdir/pxelinux.cfg/b8945908-d6a6-41a9-611d-74a6ab80b83d
  /mybootdir/pxelinux.cfg/01-88-99-aa-bb-cc-dd
  /mybootdir/pxelinux.cfg/C000025B
  [...]
  /mybootdir/pxelinux.cfg/C
  /mybootdir/pxelinux.cfg/arch-0007
  /mybootdir/pxelinux.cfg/default

I have given this patch some brief testing, but this isn't probably the
most elegant way to determine the client architecture. I'm more looking
for feedback on the changes to the discovery request process (hence the
RFC tag), but comments on both design and implementation are welcome.

1: https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#processor-architecture

Signed-off-by: Jeremy Kerr <jk at ozlabs.org>

---
 core/Makefile     |    1 +
 core/fs/pxe/pxe.c |    5 +++++
 core/fs/pxe/pxe.h |   12 ++++++++++++
 doc/pxelinux.txt  |   21 +++++++++++++++++----
 4 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/core/Makefile b/core/Makefile
index a7503ef..233a374 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -82,6 +82,7 @@ ifdef EFI_BUILD
 FILTER_OBJS += $(subst $(SRC)/,, \
 	$(patsubst %.c,%.o, $(wildcard $(SRC)/thread/*.c)) \
 	$(patsubst %.S,%.o, $(wildcard $(SRC)/thread/*.S)))
+CFLAGS += -D__EFI__
 endif
 
 COBJS	 = $(filter-out $(FILTER_OBJS),$(COBJ))
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index 4de4dbf..5cc9082 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -471,6 +471,11 @@ static int pxe_open_config(struct com32_filedata *filedata)
         tries--;
     };
 
+    /* Try by client architecture */
+    sprintf(config_file, "arch-%04x", ntohs(DHCP_CLIENT_ARCH));
+    if (open_file(ConfigName, O_RDONLY, filedata) >= 0)
+        return 0;
+
     /* Final attempt: "default" string */
     strcpy(config_file, default_str);
     if (open_file(ConfigName, O_RDONLY, filedata) >= 0)
diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
index 279957a..9ba27e5 100644
--- a/core/fs/pxe/pxe.h
+++ b/core/fs/pxe/pxe.h
@@ -35,6 +35,18 @@
 #define BOOTP_OPTION_MAGIC  htonl(0x63825363)
 #define MAC_MAX 32
 
+#ifdef __EFI__
+
+#ifdef __x86_64__
+#define DHCP_CLIENT_ARCH    htons(0x0007)
+#else
+#define DHCP_CLIENT_ARCH    htons(0x0006)
+#endif
+
+#else
+#define DHCP_CLIENT_ARCH    htons(0x0000)
+#endif
+
 /*
  * structures
  */
diff --git a/doc/pxelinux.txt b/doc/pxelinux.txt
index 4dbb152..b751934 100644
--- a/doc/pxelinux.txt
+++ b/doc/pxelinux.txt
@@ -62,13 +62,25 @@ search for its config file on the boot server in the following way:
   hexadecimal IP address for any host.)
 
   If that file is not found, it will remove one hex digit and try
-  again.  Ultimately, it will try looking for a file named "default"
-  (in lower case).
+  again.
+
+  Next, it will search for the config file using the client architecture
+  type (using the DHCP client-architecture identifiers registered with
+  IANA), as a 4-digit lowecase hexadecimal number, prefixed with
+  "arch-". For example, an x86 UEFI machine (client architecture
+  0x00 0x07) would request the filename "arch-0007".
+
+  IANA's registry of client architecture identifiers is at:
+
+    https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#processor-architecture
+
+  Ultimately, it will try looking for a file named "default" (in
+  lower case).
 
   As an example, if the boot file name is /mybootdir/pxelinux.0, the
   UUID is b8945908-d6a6-41a9-611d-74a6ab80b83d, the Ethernet MAC
-  address is 88:99:AA:BB:CC:DD and the IP address 192.0.2.91, it will
-  try:
+  address is 88:99:AA:BB:CC:DD, the IP address 192.0.2.91, and
+  the architecture is x86 BIOS (0x0000) it will try:
 
 	/mybootdir/pxelinux.cfg/b8945908-d6a6-41a9-611d-74a6ab80b83d
 	/mybootdir/pxelinux.cfg/01-88-99-aa-bb-cc-dd
@@ -80,6 +92,7 @@ search for its config file on the boot server in the following way:
 	/mybootdir/pxelinux.cfg/C00
 	/mybootdir/pxelinux.cfg/C0
 	/mybootdir/pxelinux.cfg/C
+	/mybootdir/pxelinux.cfg/arch-0000
 	/mybootdir/pxelinux.cfg/default
 
   ... in that order.


More information about the Syslinux mailing list