From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: passt.top; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ZV5ns1Gc; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by passt.top (Postfix) with ESMTPS id A5DE35A0265 for ; Thu, 28 May 2026 09:19:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1779952739; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=i8+JzIX9f7fXLoym9/p5CEMiB19np4XXDEUTV96STBM=; b=ZV5ns1GcHvYoxrg9PDTSTNqSVlF1338m+30X0XJZeIJgPGpK6zb40ZpZbrfLd0Y1uUt7Gy 6tlm+qLn8dq/tyIC4NvfgoROtrHmF6t1uuaCcRh0E1QDSZJbJMmcxKPhNqoNI2xT+ieM2n 9D5aZ+liCp4bzLtiCLn094f481+rrhU= Received: from mail-lf1-f72.google.com (mail-lf1-f72.google.com [209.85.167.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-541-evA5GDeQM_SqQHtpO5aMOA-1; Thu, 28 May 2026 03:18:57 -0400 X-MC-Unique: evA5GDeQM_SqQHtpO5aMOA-1 X-Mimecast-MFC-AGG-ID: evA5GDeQM_SqQHtpO5aMOA_1779952736 Received: by mail-lf1-f72.google.com with SMTP id 2adb3069b0e04-5a886a6c4ebso5469371e87.0 for ; Thu, 28 May 2026 00:18:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779952735; x=1780557535; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=i8+JzIX9f7fXLoym9/p5CEMiB19np4XXDEUTV96STBM=; b=IvhIP4TWOfh8kaGd5VMG79LiIjHfhw1mPfq10DnPjR93E0LHKBJvTMwGW2lBsbPvfQ HKr+igE391lq+YQ3IVzJlX7bxwNDlgH9ZqJ3xSQTnff2gWLtGbrbdpvpfvkPGt8I6QRO XcBru4k/ac2jkqg0BCsiXjYxfRscfbcGYqoq8Sgj3BVugcbRRicqWF5tUuHtLHKzYZLA XSIBj7DAQXwSJKJsICuwVpAKfQrFuoxq/LVLWhIRKuyKSBpqa4n0cKrs8L6FwqnQz92K oOGAC43VRMnUhVtH6JG22cu+oWBxPEO7lnUsfzwoNJkzR1OoaZebHLQ5GziBOK4bESLW aLCg== X-Gm-Message-State: AOJu0YyddfJD++VaGExUVnyUgKBK8sGUYFmKA+Hb2J3Xm2Nhq43G3OW1 7ANxNfIqTsipXfB3cN5Hv4mucI7pup99+4vZFUZlArh/RrSMwIQJ+amIZ1+sGcGEmFM+ALvNtpQ yb3WFJrfaIrykzssIyMuOSgDW4dm7Yi+NrH8USpjwNnULbj0xo9lRwiCA6r9Nc/Y/OLb1J3A41T cRuqaoqFQcVF7WDXfQ/HWBdPt3cuep X-Gm-Gg: Acq92OFMltkE1Q3ME/Jj5DIc7daw36OnTHtVGa7avJQwZmlZj94GDToyYvgRpNZvnEw DsEzDLvQSQxox+CDtbIJWI2gbbysK1xauwRnr3bxjFkT7t8QKYXcr7mEftq8DqeBvGN1uv1HGLQ FQVwja28PGh1PfvEb/cimw+dYnlu2lKQkE6FG95Qocpt8GM/0PK8lTwh26aB8HfiCYQWGhsFguI Tz8M0/MWoBVZqtCTPkM6axCRIQPDThwt9vha51M64XVwpFMkA== X-Received: by 2002:a05:6512:3b8a:b0:5a3:eb4b:37a7 with SMTP id 2adb3069b0e04-5aa3235d1abmr8123240e87.6.1779952735476; Thu, 28 May 2026 00:18:55 -0700 (PDT) X-Received: by 2002:a05:6512:3b8a:b0:5a3:eb4b:37a7 with SMTP id 2adb3069b0e04-5aa3235d1abmr8123228e87.6.1779952734991; Thu, 28 May 2026 00:18:54 -0700 (PDT) MIME-Version: 1.0 References: <20260526123115.1226166-1-anskuma@redhat.com> <20260526123115.1226166-6-anskuma@redhat.com> In-Reply-To: From: Anshu Kumari Date: Thu, 28 May 2026 12:48:43 +0530 X-Gm-Features: AVHnY4JAlGsA_Qi2xFZGSPzqHdLL5HGoIxc1KHtyWdutS5FRleNV1QT_PnmGVBw Message-ID: Subject: Re: [PATCH v2 5/6] dhcp: Add option overload To: David Gibson X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: oHEvsTITAI5G-jEmKibxHR_vNN7nzPYJ6wzXAM_nWgY_1779952736 X-Mimecast-Originator: redhat.com Content-Type: multipart/alternative; boundary="0000000000007c8c9f0652db8aeb" Message-ID-Hash: 5FUNBV2MG2ZPBNU726YSDLBH4AEZX5JF X-Message-ID-Hash: 5FUNBV2MG2ZPBNU726YSDLBH4AEZX5JF X-MailFrom: anskuma@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: passt-dev@passt.top, sbrivio@redhat.com, jmaloy@redhat.com, lvivier@redhat.com X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --0000000000007c8c9f0652db8aeb Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Wed, May 27, 2026 at 9:46=E2=80=AFAM David Gibson wrote: > On Tue, May 26, 2026 at 06:01:12PM +0530, Anshu Kumari wrote: > > A user can enter lots of options in command-line which may not fit in > > existing buffer, So when the options field is full, overflow remaining > > DHCP options into the file and sname fields per RFC 2132 option 52. > > > > Also, when the file field is not used for overload, copy the boot > > file URL there directly for legacy PXE clients. > > > > Link: https://bugs.passt.top/show_bug.cgi?id=3D192 > > Signed-off-by: Anshu Kumari > > --- > > v2: > > - Added #define DHCP_OVERLOAD_FILE and #define DHCP_OVERLOAD_SNAME > constants > > - Added comment documenting space reservation: /* Reserve 3 bytes for > option 52 */ > > - Fixed DNS search length: sizeof(m->o) only, not combined with > file+sname > > - Removed dhcp_boot references =E2=80=94 reply.file copy now reads fr= om > opts[67] > > - Used DHCP_OVERLOAD_FILE constant in reply.file guard > > --- > > dhcp.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++------- > > 1 file changed, 75 insertions(+), 9 deletions(-) > > > > diff --git a/dhcp.c b/dhcp.c > > index e126063..a49a05a 100644 > > --- a/dhcp.c > > +++ b/dhcp.c > > @@ -306,14 +306,59 @@ static bool fill_one(uint8_t *buf, size_t size, > int o, int *offset) > > return false; > > } > > > > +#define DHCP_OVERLOAD_FILE 1 > > +#define DHCP_OVERLOAD_SNAME 2 > > IIUC, these values are from the RFC - might be worth referencing the > relevant section in a comment to make it clear they can't be changed > arbitrarily. > > > + > > +/** > > + * fill_overflow() - Fill remaining options into file and sname fields > > + * @m: Message whose file/sname fields may be used for > overflow > > + * > > + * Return: option 52 overload value: 0 if no overflow, > > + * DHCP_OVERLOAD_FILE for file, DHCP_OVERLOAD_SNAME for sname, > > + * or both OR'd together > > + */ > > +static int fill_overflow(struct msg *m) > > +{ > > + int file_off =3D 0, sname_off =3D 0, overload =3D 0; > > + int o; > > + > > + for (o =3D 0; o < 255; o++) { > > You could use ARRAY_size(opts) instead of raw 255, yes? > > > + if (opts[o].slen =3D=3D -1 || opts[o].sent) > > + continue; > > + fill_one(m->file, sizeof(m->file) - 1, o, &file_off); > > + } > > + > > + for (o =3D 0; o < 255; o++) { > > + if (opts[o].slen =3D=3D -1 || opts[o].sent) > > + continue; > > + if (fill_one(m->sname, sizeof(m->sname) - 1, o, > &sname_off)) > > + debug("DHCP: skipping option %i (overload full)", > o); > > + } > > + > > + if (file_off) { > > + m->file[file_off] =3D 255; > > + overload |=3D DHCP_OVERLOAD_FILE; > > + } > > + > > + if (sname_off) { > > + m->sname[sname_off] =3D 255; > > + overload |=3D DHCP_OVERLOAD_SNAME; > > + } > > + > > + return overload; > > +} > > + > > /** > > - * fill() - Fill options in message > > + * fill() - Fill options in message, with overload into file/sname if > needed > > * @m: Message to fill > > + * @overload: Set to option 52 value (0 if none, 1/2/3 per RFC > 2132) > > * > > * Return: current size of options field > > */ > > -static int fill(struct msg *m) > > +static int fill(struct msg *m, int *overload) > > { > > + /* Reserve 3 bytes for option 52 (overload) if needed */ > > + size_t size =3D OPT_MAX - 3; > > int i, o, offset =3D 0; > > > > for (o =3D 0; o < 255; o++) > > @@ -324,20 +369,25 @@ static int fill(struct msg *m) > > * Put it there explicitly, unless requested via option 55. > > */ > > if (opts[55].clen > 0 && !memchr(opts[55].c, 53, opts[55].clen)) > > - if (fill_one(m->o, OPT_MAX, 53, &offset)) > > - debug("DHCP: skipping option 53"); > > + fill_one(m->o, size, 53, &offset); > > > > for (i =3D 0; i < opts[55].clen; i++) { > > o =3D opts[55].c[i]; > > if (opts[o].slen !=3D -1) > > - if (fill_one(m->o, OPT_MAX, o, &offset)) > > - debug("DHCP: skipping option %i", o); > > + fill_one(m->o, size, o, &offset); > > } > > > > for (o =3D 0; o < 255; o++) { > > if (opts[o].slen !=3D -1 && !opts[o].sent) > > - if (fill_one(m->o, OPT_MAX, o, &offset)) > > - debug("DHCP: skipping option %i", o); > > + fill_one(m->o, size, o, &offset); > > + } > > + > > + *overload =3D fill_overflow(m); > > + > > + if (*overload) { > > + m->o[offset++] =3D 52; > > + m->o[offset++] =3D 1; > > + m->o[offset++] =3D *overload; > > } > > > > m->o[offset++] =3D 255; > > @@ -462,6 +512,7 @@ int dhcp(const struct ctx *c, struct iov_tail *data= ) > > struct msg const *m; > > struct msg reply; > > unsigned int i; > > + int overload; > > > > eh =3D IOV_REMOVE_HEADER(data, eh_storage); > > iph =3D IOV_PEEK_HEADER(data, iph_storage); > > @@ -613,7 +664,22 @@ int dhcp(const struct ctx *c, struct iov_tail *dat= a) > > if (!c->no_dhcp_dns_search) > > opt_set_dns_search(c, sizeof(m->o)); > > > > - dlen =3D offsetof(struct msg, o) + fill(&reply); > > + for (i =3D 0; i < (unsigned int)c->custom_opts_count; i++) { > > + uint8_t code =3D c->custom_opts[i].code; > > + > > + opts[code].slen =3D c->custom_opts[i].len; > > + memcpy(opts[code].s, c->custom_opts[i].val, > > + c->custom_opts[i].len); > > + } > > + > > + dlen =3D offsetof(struct msg, o) + fill(&reply, &overload); > > + > > + /* Copy boot file name into the file field for legacy PXE clients= , > > + * unless the file field is already used for option overload. > > Given we do this, would it make more sense to use the slen field in > preference to the file field for overloads? The logic above appears > to do it the other way around, > are you referring to the sname field here? I am not sure how to use the slen field instead of the file field. > > > + */ > > + if (!(overload & DHCP_OVERLOAD_FILE) && > > + opts[67].slen > 0 && (size_t)opts[67].slen < > sizeof(reply.file)) > > + memcpy(&reply.file, opts[67].s, opts[67].slen + 1); > > > > if (m->flags & FLAG_BROADCAST) > > dst =3D in4addr_broadcast; > > -- > > 2.54.0 > > > > -- > David Gibson (he or they) | I'll have my music baroque, and my code > david AT gibson.dropbear.id.au | minimalist, thank you, not the other wa= y > | around. > http://www.ozlabs.org/~dgibson > --0000000000007c8c9f0652db8aeb Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


On Wed, May 27,= 2026 at 9:46=E2=80=AFAM David Gibson <david@gibson.dropbear.id.au> wrote:
On Tue, May 26, 2026 at 06:01:12PM= +0530, Anshu Kumari wrote:
> A user can enter lots of options in command-line which may not fit in<= br> > existing buffer, So when the options field is full, overflow remaining=
> DHCP options into the file and sname fields per RFC 2132 option 52. >
> Also, when the file field is not used for overload, copy the boot
> file URL there directly for legacy PXE clients.
>
> Link: https://bugs.passt.top/show_bug.cgi?id=3D192<= /a>
> Signed-off-by: Anshu Kumari <
anskuma@redhat.com>
> ---
> v2:
>=C2=A0 =C2=A0- Added #define DHCP_OVERLOAD_FILE and #define DHCP_OVERLO= AD_SNAME constants
>=C2=A0 =C2=A0- Added comment documenting space reservation: /* Reserve = 3 bytes for option 52 */
>=C2=A0 =C2=A0- Fixed DNS search length: sizeof(m->o) only, not combi= ned with file+sname
>=C2=A0 =C2=A0- Removed dhcp_boot references =E2=80=94 reply.file copy n= ow reads from opts[67]
>=C2=A0 =C2=A0- Used DHCP_OVERLOAD_FILE constant in reply.file guard
> ---
>=C2=A0 dhcp.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++-= ------
>=C2=A0 1 file changed, 75 insertions(+), 9 deletions(-)
>
> diff --git a/dhcp.c b/dhcp.c
> index e126063..a49a05a 100644
> --- a/dhcp.c
> +++ b/dhcp.c
> @@ -306,14 +306,59 @@ static bool fill_one(uint8_t *buf, size_t size, = int o, int *offset)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0return false;
>=C2=A0 }
>=C2=A0
> +#define DHCP_OVERLOAD_FILE=C2=A0 =C2=A01
> +#define DHCP_OVERLOAD_SNAME=C2=A0 2

IIUC, these values are from the RFC - might be worth referencing the
relevant section in a comment to make it clear they can't be changed arbitrarily.

> +
> +/**
> + * fill_overflow() - Fill remaining options into file and sname field= s
> + * @m:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Message = whose file/sname fields may be used for overflow
> + *
> + * Return: option 52 overload value: 0 if no overflow,
> + *=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DHCP_OVERLOAD_FILE for file, DHCP= _OVERLOAD_SNAME for sname,
> + *=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0or both OR'd together
> + */
> +static int fill_overflow(struct msg *m)
> +{
> +=C2=A0 =C2=A0 =C2=A0int file_off =3D 0, sname_off =3D 0, overload =3D= 0;
> +=C2=A0 =C2=A0 =C2=A0int o;
> +
> +=C2=A0 =C2=A0 =C2=A0for (o =3D 0; o < 255; o++) {

You could use ARRAY_size(opts) instead of raw 255, yes?

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (opts[o].slen =3D= =3D -1 || opts[o].sent)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0continue;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fill_one(m->file, = sizeof(m->file) - 1, o, &file_off);
> +=C2=A0 =C2=A0 =C2=A0}
> +
> +=C2=A0 =C2=A0 =C2=A0for (o =3D 0; o < 255; o++) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (opts[o].slen =3D= =3D -1 || opts[o].sent)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0continue;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (fill_one(m->sn= ame, sizeof(m->sname) - 1, o, &sname_off))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0debug("DHCP: skipping option %i (overload full)", o);
> +=C2=A0 =C2=A0 =C2=A0}
> +
> +=C2=A0 =C2=A0 =C2=A0if (file_off) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0m->file[file_off] = =3D 255;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0overload |=3D DHCP_OV= ERLOAD_FILE;
> +=C2=A0 =C2=A0 =C2=A0}
> +
> +=C2=A0 =C2=A0 =C2=A0if (sname_off) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0m->sname[sname_off= ] =3D 255;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0overload |=3D DHCP_OV= ERLOAD_SNAME;
> +=C2=A0 =C2=A0 =C2=A0}
> +
> +=C2=A0 =C2=A0 =C2=A0return overload;
> +}
> +
>=C2=A0 /**
> - * fill() - Fill options in message
> + * fill() - Fill options in message, with overload into file/sname if= needed
>=C2=A0 =C2=A0* @m:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0Message to fill
> + * @overload:=C2=A0 =C2=A0 =C2=A0 =C2=A0 Set to option 52 value (0 if= none, 1/2/3 per RFC 2132)
>=C2=A0 =C2=A0*
>=C2=A0 =C2=A0* Return: current size of options field
>=C2=A0 =C2=A0*/
> -static int fill(struct msg *m)
> +static int fill(struct msg *m, int *overload)
>=C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0/* Reserve 3 bytes for option 52 (overload) if ne= eded */
> +=C2=A0 =C2=A0 =C2=A0size_t size =3D OPT_MAX - 3;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0int i, o, offset =3D 0;
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0for (o =3D 0; o < 255; o++)
> @@ -324,20 +369,25 @@ static int fill(struct msg *m)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 * Put it there explicitly, unless requested= via option 55.
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 */
>=C2=A0 =C2=A0 =C2=A0 =C2=A0if (opts[55].clen > 0 && !memchr(= opts[55].c, 53, opts[55].clen))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (fill_one(m->o,= OPT_MAX, 53, &offset))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 debug("DHCP: skipping option 53");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fill_one(m->o, siz= e, 53, &offset);
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < opts[55].clen; i++) { >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0o =3D opts[55].c= [i];
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (opts[o].slen= !=3D -1)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0if (fill_one(m->o, OPT_MAX, o, &offset))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0debug("DHCP: skipping option %i&quo= t;, o);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0fill_one(m->o, size, o, &offset);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0}
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0for (o =3D 0; o < 255; o++) {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (opts[o].slen= !=3D -1 && !opts[o].sent)
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0if (fill_one(m->o, OPT_MAX, o, &offset))
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0debug("DHCP: skipping option %i&quo= t;, o);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0fill_one(m->o, size, o, &offset);
> +=C2=A0 =C2=A0 =C2=A0}
> +
> +=C2=A0 =C2=A0 =C2=A0*overload =3D fill_overflow(m);
> +
> +=C2=A0 =C2=A0 =C2=A0if (*overload) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0m->o[offset++] =3D= 52;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0m->o[offset++] =3D= 1;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0m->o[offset++] =3D= *overload;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0}
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0m->o[offset++] =3D 255;
> @@ -462,6 +512,7 @@ int dhcp(const struct ctx *c, struct iov_tail *dat= a)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0struct msg const *m;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0struct msg reply;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int i;
> +=C2=A0 =C2=A0 =C2=A0int overload;
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0eh =3D IOV_REMOVE_HEADER(data, eh_storage);<= br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0iph =3D IOV_PEEK_HEADER(data, iph_storage);<= br> > @@ -613,7 +664,22 @@ int dhcp(const struct ctx *c, struct iov_tail *da= ta)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0if (!c->no_dhcp_dns_search)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0opt_set_dns_sear= ch(c, sizeof(m->o));
>=C2=A0
> -=C2=A0 =C2=A0 =C2=A0dlen =3D offsetof(struct msg, o) + fill(&repl= y);
> +=C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < (unsigned int)c->custom_o= pts_count; i++) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0uint8_t code =3D c-&g= t;custom_opts[i].code;
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0opts[code].slen =3D c= ->custom_opts[i].len;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0memcpy(opts[code].s, = c->custom_opts[i].val,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= c->custom_opts[i].len);
> +=C2=A0 =C2=A0 =C2=A0}
> +
> +=C2=A0 =C2=A0 =C2=A0dlen =3D offsetof(struct msg, o) + fill(&repl= y, &overload);
> +
> +=C2=A0 =C2=A0 =C2=A0/* Copy boot file name into the file field for le= gacy PXE clients,
> +=C2=A0 =C2=A0 =C2=A0 * unless the file field is already used for opti= on overload.

Given we do this, would it make more sense to use the slen field in
preference to the file field for overloads?=C2=A0 The logic above appears to do it the other way around,

are you = referring to the sname field here? I am not sure how to use the slen field = instead of the file field.

> +=C2=A0 =C2=A0 =C2=A0 */
> +=C2=A0 =C2=A0 =C2=A0if (!(overload & DHCP_OVERLOAD_FILE) &&am= p;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0opts[67].slen > 0 && (si= ze_t)opts[67].slen < sizeof(reply.file))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0memcpy(&reply.fil= e, opts[67].s, opts[67].slen + 1);
>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0if (m->flags & FLAG_BROADCAST)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dst =3D in4addr_= broadcast;
> --
> 2.54.0
>

--
David Gibson (he or they)=C2=A0 =C2=A0 =C2=A0 =C2=A0| I'll have my musi= c baroque, and my code
david AT gibson.dropbear.id.au=C2=A0 | minimalist, thank you, not th= e other way
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | around.
http://www.ozlabs.org/~dgibson
--0000000000007c8c9f0652db8aeb--