aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgnat Korchagin <ignat@cloudflare.com>2022-01-25 23:10:08 +0000
committerIgnat Korchagin <ignat@cloudflare.com>2022-01-25 23:36:05 +0000
commit60535013c3e22408f5f39e0fe2cba7bd762b66af (patch)
tree1adf68e530e53479ef3485ad987e9af764d6c2ac
parent857d5ed77d9f0f0cc5122eb7200fa44f3af1053e (diff)
downloadslirp-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.c23
-rw-r--r--src/bootp.h1
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