git: a098fd021e51 - main - loader: request DHCP initmd option
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 11 Sep 2026 05:04:25 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=a098fd021e517df930d8df0ac3a808d63c24252b
commit a098fd021e517df930d8df0ac3a808d63c24252b
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-09-11 04:13:57 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-09-11 04:15:28 +0000
loader: request DHCP initmd option
Request FreeBSD RFC 3925 PEM 2238 DHCP 125 option. Use suboption 1 to
specify a ramdisk image to load and use to load the kernel and as the
root file system.
Differential Revision: https://reviews.freebsd.org/D59428
Sponsored by: Netflix
---
stand/libsa/bootp.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
stand/libsa/bootp.h | 5 +++++
2 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/stand/libsa/bootp.c b/stand/libsa/bootp.c
index 6008f0bf8f11..f708006169d0 100644
--- a/stand/libsa/bootp.c
+++ b/stand/libsa/bootp.c
@@ -69,6 +69,7 @@ static char vm_cmu[4] = VM_CMU;
static ssize_t bootpsend(struct iodesc *, void *, size_t);
static ssize_t bootprecv(struct iodesc *, void **, void **, time_t, void *);
static int vend_rfc1048(u_char *, u_int);
+static void vend_vivso(const u_char *, size_t);
#ifdef BOOTP_VEND_CMU
static void vend_cmu(u_char *);
#endif
@@ -122,6 +123,15 @@ bootp_fill_request(unsigned char *bp_vend)
bcopy("FreeBSD", &bp_vend[off], 7);
off += 7;
+ /* Vendor-Identifying Vendor Class, RFC 3925. */
+ bp_vend[off++] = TAG_VI_VENDOR_CLASS;
+ bp_vend[off++] = 12;
+ be32enc(&bp_vend[off], FREEBSD_ENTERPRISE_NUMBER);
+ off += 4;
+ bp_vend[off++] = 7;
+ bcopy("FreeBSD", &bp_vend[off], 7);
+ off += 7;
+
/*
* Client architecture (RFC 4578). Value is 2 bytes big-endian.
* Omit entirely for loaders that don't have a spec-defined value.
@@ -146,7 +156,7 @@ bootp_fill_request(unsigned char *bp_vend)
bp_vend[off++] = 1472 & 0xff;
bp_vend[off++] = TAG_PARAM_REQ;
- bp_vend[off++] = 7;
+ bp_vend[off++] = 8;
bp_vend[off++] = TAG_ROOTPATH;
bp_vend[off++] = TAG_HOSTNAME;
bp_vend[off++] = TAG_SWAPSERVER;
@@ -154,6 +164,7 @@ bootp_fill_request(unsigned char *bp_vend)
bp_vend[off++] = TAG_SUBNET_MASK;
bp_vend[off++] = TAG_INTF_MTU;
bp_vend[off++] = TAG_SERVERID;
+ bp_vend[off++] = TAG_VI_VENDOR_OPTS;
bp_vend[off] = TAG_END;
}
@@ -497,6 +508,8 @@ vend_rfc1048(u_char *cp, u_int len)
if (intf_mtu <= 0)
intf_mtu = be16dec(cp);
}
+ if (tag == TAG_VI_VENDOR_OPTS)
+ vend_vivso(cp, size);
#ifdef SUPPORT_DHCP
if (tag == TAG_DHCP_MSGTYPE) {
if(*cp != expected_dhcpmsgtype)
@@ -513,6 +526,49 @@ vend_rfc1048(u_char *cp, u_int len)
return(0);
}
+static void
+vend_freebsd(const u_char *cp, size_t len)
+{
+ char value[256];
+ size_t size;
+ u_char tag;
+
+ while (len >= 2) {
+ tag = *cp++;
+ size = *cp++;
+ len -= 2;
+ if (size > len)
+ return;
+ if (tag == FREEBSD_VI_INITMD && size < sizeof(value)) {
+ bcopy(cp, value, size);
+ value[size] = '\0';
+ setenv("dhcp.initmd", value, 0);
+ }
+ cp += size;
+ len -= size;
+ }
+}
+
+static void
+vend_vivso(const u_char *cp, size_t len)
+{
+ uint32_t enterprise;
+ size_t size;
+
+ while (len >= 5) {
+ enterprise = be32dec(cp);
+ cp += 4;
+ size = *cp++;
+ len -= 5;
+ if (size > len)
+ return;
+ if (enterprise == FREEBSD_ENTERPRISE_NUMBER)
+ vend_freebsd(cp, size);
+ cp += size;
+ len -= size;
+ }
+}
+
#ifdef BOOTP_VEND_CMU
static void
vend_cmu(u_char *cp)
@@ -687,6 +743,7 @@ static struct dhcp_opt dhcp_opt[] = {
{86, __TXT, "nds-tree-name"},
{87, __TXT, "nds-context"},
{210, __TXT, "authenticate"},
+ {125, __NONE, "vendor-identifying-vendor-options"},
/* use the following entries for arbitrary variables */
{246, __ILIST, ""},
diff --git a/stand/libsa/bootp.h b/stand/libsa/bootp.h
index 577449a79292..d5f65d0c6981 100644
--- a/stand/libsa/bootp.h
+++ b/stand/libsa/bootp.h
@@ -108,6 +108,11 @@ struct bootp {
#define TAG_CLIENTID ((unsigned char) 61)
#define TAG_USER_CLASS ((unsigned char) 77)
#define TAG_CLIENT_ARCH ((unsigned char) 93) /* RFC 4578 */
+#define TAG_VI_VENDOR_CLASS ((unsigned char) 124) /* RFC 3925 */
+#define TAG_VI_VENDOR_OPTS ((unsigned char) 125) /* RFC 3925 */
+
+#define FREEBSD_ENTERPRISE_NUMBER 2238
+#define FREEBSD_VI_INITMD 1
#endif
#define TAG_END ((unsigned char) 255)