diff options
author | Ignat Korchagin <ignat@cloudflare.com> | 2022-01-25 23:10:08 +0000 |
---|---|---|
committer | Ignat Korchagin <ignat@cloudflare.com> | 2022-01-25 23:36:05 +0000 |
commit | 60535013c3e22408f5f39e0fe2cba7bd762b66af (patch) | |
tree | 1adf68e530e53479ef3485ad987e9af764d6c2ac | |
parent | 857d5ed77d9f0f0cc5122eb7200fa44f3af1053e (diff) | |
download | slirp-60535013c3e22408f5f39e0fe2cba7bd762b66af.zip slirp-60535013c3e22408f5f39e0fe2cba7bd762b66af.tar.gz slirp-60535013c3e22408f5f39e0fe2cba7bd762b66af.tar.bz2 |
bootp: add support for UEFI HTTP boot
Current bootp implementation is only one step away from supporting UEFI HTTP
boot in QEMU. The only missing bit is that the UEFI specification [1] requires
a vendor class identifier option (num 60) set to "HTTPClient" string present
in the DHCP response.
OVMF [2] indeed ignores the DHCP response and considers UEFI HTTP boot as
failed, if this option is not present.
With this change one would be able to configure QEMU user networking like
below:
$ qemu ... -nic user,tftp=tftp-root,bootfile=http://10.0.2.2/ipxe.efi
and boot the VM using UEFI HTTP boot instead of TFTP.
[1]: https://uefi.org/sites/default/files/resources/UEFI_Spec_2_9_2021_03_18.pdf
[2]: https://github.com/tianocore/edk2/tree/5302bd81d9ba0c9e7f2371a81c438ec919ec8e1e/OvmfPkg
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
-rw-r--r-- | src/bootp.c | 23 | ||||
-rw-r--r-- | src/bootp.h | 1 |
2 files changed, 24 insertions, 0 deletions
diff --git a/src/bootp.c b/src/bootp.c index 1a3517e..3ade02c 100644 --- a/src/bootp.c +++ b/src/bootp.c @@ -34,6 +34,8 @@ #define LEASE_TIME (24 * 3600) +#define UEFI_HTTP_VENDOR_CLASS_ID "HTTPClient" + static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE }; #define DPRINTF(fmt, ...) DEBUG_CALL(fmt, ##__VA_ARGS__) @@ -340,6 +342,27 @@ static void bootp_reply(Slirp *slirp, q += val; } } + + /* this allows to support UEFI HTTP boot: according to the UEFI + specification, DHCP server must send vendor class identifier option + set to "HTTPClient" string, when responding to DHCP requests as part + of the UEFI HTTP boot + + we assume that, if the bootfile parameter was configured as an http + URL, the user intends to perform UEFI HTTP boot, so send this option + automatically */ + if (g_str_has_prefix(slirp->bootp_filename, "http://")) { + val = strlen(UEFI_HTTP_VENDOR_CLASS_ID); + if (q + val + 2 >= end) { + g_warning("DHCP packet size exceeded, " + "omitting vendor class id option."); + } else { + *q++ = RFC2132_VENDOR_CLASS_ID; + *q++ = val; + memcpy(q, UEFI_HTTP_VENDOR_CLASS_ID, val); + q += val; + } + } } else { static const char nak_msg[] = "requested address not available"; diff --git a/src/bootp.h b/src/bootp.h index 31ce5fd..cf7797f 100644 --- a/src/bootp.h +++ b/src/bootp.h @@ -71,6 +71,7 @@ #define RFC2132_MAX_SIZE 57 #define RFC2132_RENEWAL_TIME 58 #define RFC2132_REBIND_TIME 59 +#define RFC2132_VENDOR_CLASS_ID 60 #define RFC2132_TFTP_SERVER_NAME 66 #define DHCPDISCOVER 1 |