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=DeaCLIT/; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by passt.top (Postfix) with ESMTPS id 6AD685A065D for ; Wed, 26 Aug 2026 16:11:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1787753505; 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: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:autocrypt:autocrypt; bh=XQrgdYusRf2DX8BGCcxVbNnwce0X2f7sEToPZ9Ah7rE=; b=DeaCLIT/0OAlSQNcuxONH5LTEIv4Sn9hT348sj3orKWqQteEWuOPLf1OodsyVaUhfr+SKJ ykmMHnfnsgN/3JVUEk2/MTrm9HHuaW6b4cRz+7B2LAki/bEc7oNS64vGz4L0Wz70SjGtsx m/+z5Hjbby+qu8SIEoxFvJQoofLLcO4= Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-282-eGKaNLYBM_-7KDnHdnXyXQ-1; Wed, 26 Aug 2026 10:11:44 -0400 X-MC-Unique: eGKaNLYBM_-7KDnHdnXyXQ-1 X-Mimecast-MFC-AGG-ID: eGKaNLYBM_-7KDnHdnXyXQ_1787753502 Received: by mail-ej1-f72.google.com with SMTP id a640c23a62f3a-c252634bc4dso71951566b.1 for ; Wed, 26 Aug 2026 07:11:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787753502; x=1788358302; h=content-transfer-encoding:content-type:in-reply-to:autocrypt:from :content-language:references:cc:to:subject:user-agent:mime-version :date:message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=XQrgdYusRf2DX8BGCcxVbNnwce0X2f7sEToPZ9Ah7rE=; b=qxn2zLaW08mdnDSVmUobcfdFN9Mv7AhXCz1sj9TgmNJP3v4D80+hMqqFQbUSlv2nSf +32eOPpnOdRoOpPkcN77tKNndrkIfWUfUkCZc+oUTg83p9tudmuN4NAQUmK3xrVgTpxN CEdqjwaPYVaZW1Oz8g6WnfJCMrBbMTyOrELij871ht4233kJD0TUHrkJiwMaxgq58f9P x4p7dnG7F1WiwQOn7hb5EZW5dxkt3o4UoCuI0RB8DI5MrBg8vwCUdzKmbMcI8+fHEO4x xTr7Wz5pFiHMjPaosHgzubbJyEO1Funxnde9TvjN1hCOWt0ytx0tuGpgYVcXqrje4B2z Psxg== X-Forwarded-Encrypted: i=1; AHgh+RpYvGoesZZBQtnHhOp53AcIegKcaFVgJi16R6l7khtho2ShzQA8/dBCcQwDSMOmUazJS9slH+0KubE=@passt.top X-Gm-Message-State: AFuF++kBpcKSPGFaZLbruFvWsIKr3FsaXo/k7i2VkorpveHOhU6RJwwx 80veNNBd6QKVfD9JG74KM0usitlOXAwQf+E1LB+/72mHatULAB1rhheze0WLQG/aWosezQMnoNp b76IthlXU5b+e6WkeTtojhRHWHJkOh23y9jIu6b9fdLXa3FuwAGhkbQ== X-Gm-Gg: AR+sD10E3tZ4vdyBlNEl0No+z/10NhThhS0Keb6mKPHsa3QsDLmUvmrlN6IUQRthWSk bH6lbnidKRlW00rPMSyTimo/RluPEOmbE14owBKqA7piIc0OuvVSFoPp/pkaSK8LujcfJVNJtIp muxV0I6lXTdw/Bd1VNFn6nlrJl3DM02i/uND1WH7R02dJ0pJgaLdt+a6cLkqAVEw5WZuZ4hXVI4 9P4u6z0bIvbaRMWX8o6MExvMsFnnUa87Zl3MUT+KlOCy562YxjDJJN4EEjdSBW6q/OgbyeX+v2l JV7Jp7T4XPrgoUgR42K/5ZgCoozycuxwBk0deLbg96+5ENJVim+SNPtk6Bfz9qsIYhxJY5PV7Uz AYOAoCD7Tk5RAcISmzkYoOdvXOsuRY+0DkcSG1lL4G6I= X-Received: by 2002:a17:907:1c11:b0:c25:6e8:7c64 with SMTP id a640c23a62f3a-c250bb3792dmr824469066b.5.1787753501622; Wed, 26 Aug 2026 07:11:41 -0700 (PDT) X-Received: by 2002:a17:907:1c11:b0:c25:6e8:7c64 with SMTP id a640c23a62f3a-c250bb3792dmr824461666b.5.1787753500965; Wed, 26 Aug 2026 07:11:40 -0700 (PDT) Received: from ?IPV6:2a01:e0a:e10:ef90:d92c:7e4a:47e6:1b23? ([2a01:e0a:e10:ef90:d92c:7e4a:47e6:1b23]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c250dfd6e6asm405121666b.19.2026.08.26.07.11.34 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 26 Aug 2026 07:11:35 -0700 (PDT) Message-ID: <1296bd18-87cd-4765-aa3b-eb99fa14e14c@redhat.com> Date: Wed, 26 Aug 2026 16:11:34 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v6 6/6] dhcp: Add RFC 3396 option splitting for concatenation-requiring options To: Anshu Kumari , sbrivio@redhat.com, passt-dev@passt.top References: <20260824134436.282300-1-anskuma@redhat.com> <20260824134436.282300-7-anskuma@redhat.com> From: Laurent Vivier Autocrypt: addr=lvivier@redhat.com; keydata= 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 In-Reply-To: <20260824134436.282300-7-anskuma@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: MK3j4S9fMUmo_g1OkwIciVIFWNHKKQX7-bypTXdWMkM_1787753502 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Message-ID-Hash: CHNB5IDVX5JPRQM7ZK472CRYNZGOER4P X-Message-ID-Hash: CHNB5IDVX5JPRQM7ZK472CRYNZGOER4P X-MailFrom: lvivier@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: david@gibson.dropbear.id.au, jmaloy@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: On 8/24/26 15:44, Anshu Kumari wrote: > Implement option splitting per RFC 3396 for options that may exceed > 255 bytes. A new concat_req[] lookup table marks options requiring > concatenation (currently option 81, Client FQDN per RFC 4702). > > The opts[].s buffer is resized from 255 to 497 bytes > (OPT_CONCAT_MAX) to hold the maximum data that can be split > across the options field, file field, and sname field. > > When a concatenation-requiring option does not fit as a single > option in any field, fill() calls fill_split() to split it across > fields in RFC 3396 order: options field first, then file, then > sname. > > Link: https://bugs.passt.top/show_bug.cgi?id=192 > Signed-off-by: Anshu Kumari > --- > v6: > - Merged v5 patches 6/7 and 7/7 into a single patch. > - Replaced DHCP_OPT_STR_CONCAT enum value and is_concat_opt() > helper with a concat_req[] boolean lookup table. > - Used MIN() macro instead of ternary for chunk size. > - Fixed space calculation to account for 2-byte code+length > overhead per chunk. > > v5: > - New patch: implement option splitting per RFC 3396 for options exceeding 255 bytes > - Add DHCP_OPT_STR_CONCAT type, is_concat_opt(), fill_split() helpers > - Resize opts[].s from 255 to OPT_CONCAT_MAX (497) bytes > - Add /* fallthrough */ between DHCP_OPT_STR and DHCP_OPT_STR_CONCAT case > --- > dhcp.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 98 insertions(+), 1 deletion(-) > > diff --git a/dhcp.c b/dhcp.c > index 43ce133..eda04d1 100644 > --- a/dhcp.c > +++ b/dhcp.c > @@ -35,6 +35,11 @@ > #include "dhcp.h" > #include "parse.h" > > +/* RFC 3396: maximum option data that can be split across options field, > + * file field, and sname field (minus code+length overhead per portion). > + */ > +#define OPT_CONCAT_MAX 497 > + > /** > * enum opt_state - DHCP option state > * @OPT_UNSET: Option not configured > @@ -59,7 +64,7 @@ enum opt_state { > struct opt { > int sent; > int slen; > - uint8_t s[255]; > + uint8_t s[OPT_CONCAT_MAX]; > int clen; > uint8_t c[255]; > enum opt_state state; > @@ -215,6 +220,13 @@ static const enum dhcp_opt_type dhcp_opt_types[] = { > [252] = DHCP_OPT_STR, /* WPAD URL */ > }; > > +/** > + * concat_req - Options requiring RFC 3396 concatenation, indexed by code > + */ > +static const bool concat_req[256] = { > + [81] = true, /* Client FQDN (RFC 4702, Section 2) */ > +}; > + > /** > * dhcp_opt_parse() - Parse a DHCP option value > * @code: DHCP option code > @@ -309,6 +321,9 @@ static int dhcp_opt_parse(uint8_t code, const char *str, > case DHCP_OPT_STR: > slen = strlen(str); > > + if (!concat_req[code] && slen > 255) > + return -1; > + > if (slen >= buf_len) > return -1; > > @@ -442,6 +457,40 @@ enum dhcp_overload { > DHCP_OVERLOAD_SNAME = 2, > }; > > +/** > + * fill_split() - Write a split portion of an option into a buffer > + * @buf: Buffer to write into > + * @size: Usable size of @buf > + * @o: Option number (code) > + * @offset: Current offset within @buf, updated on write > + * @data: Pointer to remaining option data to write > + * @remaining: Bytes of option data still to write > + * > + * Return: number of data bytes written (excluding code+length header) > + */ > +static size_t fill_split(uint8_t *buf, size_t size, int o, int *offset, > + const uint8_t *data, size_t remaining) > +{ > + size_t avail, chunk; > + > + if (*offset + 2 >= (int)size) > + return 0; > + > + avail = size - *offset - 2; > + chunk = MIN(remaining, avail); > + if (!chunk) > + return 0; > + > + buf[*offset] = o; > + buf[*offset + 1] = chunk; buf[] is uint8_t, but chunk can be > 255: avail can be OPT_MAX - 3 - 2 (302) remainining is, on first call opts[81].slen (that is opts[81].slen = strlen(c->fqdn) + 5, that can be PASST_MAXDNAME - 1 + 5 = 258). So to avoid this overflow (or other in future options) you should use chunk = MIN(MIN(remaining, avail), 255) > + *offset += 2; > + > + memcpy(buf + *offset, data, chunk); > + *offset += chunk; > + > + return chunk; > +} > + > /** > * fill() - Fill options in message, with overload into file/sname if needed > * @m: Message to fill > @@ -495,6 +544,54 @@ static int fill(struct msg *m, enum dhcp_overload *overload, bool has_bootfile) > } > } > > + /* RFC 3396: split concatenation-requiring options that didn't fit > + * as a single option. Split order: options, file, sname. > + */ > + for (o = 0; (size_t)o < ARRAY_SIZE(opts); o++) { > + size_t file_cap, sname_cap, total, written; > + > + if (opts[o].state == OPT_UNSET || opts[o].sent || > + !concat_req[o]) > + continue; > + > + sname_cap = sizeof(m->sname) - 1 > (size_t)sname_off ? > + sizeof(m->sname) - 1 - sname_off : 0; > + > + if (has_bootfile || sizeof(m->file) - 1 <= (size_t)file_off) > + file_cap = 0; > + else > + file_cap = sizeof(m->file) - 1 - file_off; > + > + total = (size > (size_t)offset ? size - offset - 2 : 0) here also 'size - offset - 2' must be capped by 255 otherwise total available space is not correctly evaluated. > + + (file_cap > 2 ? file_cap - 2 : 0) > + + (sname_cap > 2 ? sname_cap - 2 : 0); > + > + if (total < (size_t)opts[o].slen) { > + debug("DHCP: skipping option %i (no space to split)", > + o); > + continue; > + } > + > + written = 0; > + written += fill_split(m->o, size, o, &offset, > + opts[o].s, opts[o].slen); > + if (written < (size_t)opts[o].slen && !has_bootfile) > + written += fill_split(m->file, > + sizeof(m->file) - 1, o, > + &file_off, > + opts[o].s + written, > + opts[o].slen - written); > + if (written < (size_t)opts[o].slen) > + written += fill_split(m->sname, > + sizeof(m->sname) - 1, o, > + &sname_off, > + opts[o].s + written, > + opts[o].slen - written); > + > + if (written >= (size_t)opts[o].slen) > + opts[o].sent = 1; > + } > + > /* Report any options that could not be sent */ > for (o = 0; (size_t)o < ARRAY_SIZE(opts); o++) { > if (opts[o].state != OPT_UNSET && !opts[o].sent)