On Thu, Jun 18, 2026 at 05:35:29PM +0530, Anshu Kumari wrote: > Append user-specified options from --dhcpv6-opt to DHCPv6 reply > messages. Options are parsed from the stored string value at reply > time using dhcpv6_opt_parse(), and skipped with a debug message if > they exceed the available space. > > Link: https://bugs.passt.top/show_bug.cgi?id=192 > Signed-off-by: Anshu Kumari > --- > v2: > - Updated dhcpv6_custom_opts_fill() to parse str at reply time > using dhcpv6_opt_parse() instead of copying cached val/len. As with DHCPv4, it's not that I'm against storing the parsed values persistently, just that I'm against storing them twice. The existing data structures for DHCPv6 are different, so maybe there's not an obvious place to store pre-parsed options. > --- > dhcpv6.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 44 insertions(+) > > diff --git a/dhcpv6.c b/dhcpv6.c > index 1e1dd0d..6b1e90b 100644 > --- a/dhcpv6.c > +++ b/dhcpv6.c > @@ -748,6 +748,49 @@ static size_t dhcpv6_client_fqdn_fill(const struct iov_tail *data, > return offset + sizeof(struct opt_hdr) + opt_len; > } > > +/** > + * dhcpv6_custom_opts_fill() - Append user-specified custom options to reply As discussed elsewhere "custom" isn't a great name. "user" might be better, or just drop it. > + * @c: Execution context > + * @buf: Response message buffer > + * @offset: Current offset in buffer > + * > + * Return: updated offset after appending custom options > + */ > +static size_t dhcpv6_custom_opts_fill(const struct ctx *c, > + char *buf, int offset) > +{ > + int i; > + > + for (i = 0; i < c->dhcpv6_opts_count; i++) { > + uint16_t code = c->dhcpv6_opts[i].code; > + struct opt_hdr *hdr; > + uint8_t val[255]; > + int vlen; > + > + vlen = dhcpv6_opt_parse(code, c->dhcpv6_opts[i].str, > + val, sizeof(val)); > + if (vlen < 0) > + continue; > + > + if ((size_t)offset + sizeof(struct opt_hdr) + vlen > > + OPT_MAX_SIZE) { > + debug("DHCPv6: custom option %u doesn't fit," > + " skipping", code); > + continue; > + } > + > + hdr = (struct opt_hdr *)(buf + offset); > + hdr->t = htons(code); > + hdr->l = htons(vlen); > + offset += sizeof(struct opt_hdr); > + > + memcpy(buf + offset, val, vlen); > + offset += vlen; > + } > + > + return offset; > +} > + > /** > * dhcpv6() - Check if this is a DHCPv6 message, reply as needed > * @c: Execution context > @@ -886,6 +929,7 @@ int dhcpv6(struct ctx *c, struct iov_tail *data, > sizeof(struct opt_hdr) + ntohs(client_id->l); > n = dhcpv6_dns_fill(c, (char *)&resp, n); > n = dhcpv6_client_fqdn_fill(data, c, (char *)&resp, n); > + n = dhcpv6_custom_opts_fill(c, (char *)&resp, n); > > resp.hdr.xid = mh->xid; > > -- > 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 way | around. http://www.ozlabs.org/~dgibson