Jeremy Kerr
2014-Feb-24 08:14 UTC
[syslinux] [RFC, PATCH] core/pxe: Add architecture-specific discovery request for PXE config file
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.
Santillanes, Russel
2014-Feb-24 15:34 UTC
[syslinux] [RFC, PATCH] core/pxe: Add architecture-specific discovery request for PXE config file
Is leveraging the options provided in the DHCP response at the DHCP server level (e.g. option 60 or option 93) a challenge here? Or is that the specific sort of stunting you're looking to avoid? -----Original Message----- From: Syslinux [mailto:syslinux-bounces at zytor.com] On Behalf Of Jeremy Kerr Sent: Monday, February 24, 2014 3:14 AM To: syslinux at zytor.com Subject: [syslinux] [RFC, PATCH] core/pxe: Add architecture-specific discovery request for PXE config file 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.x + html#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. _______________________________________________ Syslinux mailing list Submissions to Syslinux at zytor.com Unsubscribe or set options at: http://www.zytor.com/mailman/listinfo/syslinux Please do not send private replies to mailing list traffic.
Gene Cumm
2014-Feb-24 17:13 UTC
[syslinux] [RFC, PATCH] core/pxe: Add architecture-specific discovery request for PXE config file
On Mon, Feb 24, 2014 at 3:14 AM, Jeremy Kerr <jk at ozlabs.org> wrote:> 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.Actually, you can. COM32 modules are not usable across architectures. I'd suggest separating them to different directories. I don't think I've documented this alternate strategy yet but the overview is to place each in differing directories then determine a strategy for shared content (if any). If symlinks are allowed on the tftpd system (ie a Linux box with ext3), this would probably be the easiest strategy as you otherwise need to develop a strategy for specifying URL-like file locations. Generally ".." in a URL is a bad idea. Quick example: Return a boot file name of "pxelinux.0" or "bios/pxelinux.0" for BIOS clients, "efi32/bootia32.efi" for EFI x86 and "efi64/bootx64.efi" for EFI x86-64. -- -Gene
Don Cupp
2014-Feb-24 17:30 UTC
[syslinux] [RFC, PATCH] core/pxe: Add architecture-specific discovery request for PXE config file
In other words, the dhcp server has to start the client on the correct binary for it's arch and by virtue of running different bins, we can determine the most appropriate config file for the client? On Monday, February 24, 2014 9:13 AM, Gene Cumm <gene.cumm at gmail.com> wrote: On Mon, Feb 24, 2014 at 3:14 AM, Jeremy Kerr <jk at ozlabs.org> wrote:> 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.Actually, you can.? COM32 modules are not usable across architectures. I'd suggest separating them to different directories.? I don't think I've documented this alternate strategy yet but the overview is to place each in differing directories then determine a strategy for shared content (if any).? If symlinks are allowed on the tftpd system (ie a Linux box with ext3), this would probably be the easiest strategy as you otherwise need to develop a strategy for specifying URL-like file locations.? Generally ".." in a URL is a bad idea. Quick example: Return a boot file name of "pxelinux.0" or "bios/pxelinux.0" for BIOS clients, "efi32/bootia32.efi" for EFI x86 and "efi64/bootx64.efi" for EFI x86-64. -- -Gene _______________________________________________ Syslinux mailing list Submissions to Syslinux at zytor.com Unsubscribe or set options at: http://www.zytor.com/mailman/listinfo/syslinux Please do not send private replies to mailing list traffic.