On Thu, Jun 04, 2026 at 04:21:50PM +0530, Anshu Kumari wrote:
Add dhcpv6_custom_opts_fill() which appends user-specified custom options to DHCPv6 response packets, and call it from the main dhcpv6() handler after the built-in DNS and FQDN options.
Each custom option is written with its DHCPv6 option header (code + length) followed by the binary-encoded value from dhcpv6_opt_parse(). Options that would exceed the IPv6 minimum MTU are skipped with a debug message.
Signed-off-by: Anshu Kumari
Reviewed-by: David Gibson
--- dhcpv6.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/dhcpv6.c b/dhcpv6.c index 85e2926..590c40d 100644 --- a/dhcpv6.c +++ b/dhcpv6.c @@ -798,6 +798,41 @@ 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 + * @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->custom_v6opts_count; i++) { + struct opt_hdr *hdr; + uint16_t len = c->custom_v6opts[i].len; + + if ((size_t)offset + sizeof(struct opt_hdr) + len > OPT_MAX_SIZE) { + debug("DHCPv6: custom option %u doesn't fit, skipping", + c->custom_v6opts[i].code); + continue; + } + + hdr = (struct opt_hdr *)(buf + offset); + hdr->t = htons(c->custom_v6opts[i].code); + hdr->l = htons(len); + offset += sizeof(struct opt_hdr); + + memcpy(buf + offset, c->custom_v6opts[i].val, len); + offset += len; + } + + return offset; +} + /** * dhcpv6() - Check if this is a DHCPv6 message, reply as needed * @c: Execution context @@ -936,6 +971,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