On Mon, May 18, 2026 at 06:49:57PM +0530, Anshu Kumari wrote: > Introduce the --dhcp-opt flag that allows setting arbitrary DHCP > options from command-line in the form of [Option CODE,VALUE]. > This patch adds the option storage in struct ctx and CLI parsing; > the type-aware value parser and DHCP reply injection follow > in subsequent patches. > > Link: https://bugs.passt.top/show_bug.cgi?id=192 > Signed-off-by: Anshu Kumari > --- > conf.c | 36 +++++++++++++++++++++++++++++++++++- > passt.h | 10 ++++++++++ > 2 files changed, 45 insertions(+), 1 deletion(-) > > diff --git a/conf.c b/conf.c > index 029b9c7..2624e58 100644 > --- a/conf.c > +++ b/conf.c > @@ -47,6 +47,7 @@ > #include "lineread.h" > #include "isolation.h" > #include "log.h" > +#include "dhcp.h" > #include "vhost_user.h" > #include "epoll_ctl.h" > #include "conf.h" > @@ -616,7 +617,8 @@ static void usage(const char *name, FILE *f, int status) > " -S, --search LIST Space-separated list, search domains\n" > " a single, empty option disables the DNS search list\n" > " -H, --hostname NAME Hostname to configure client with\n" > - " --fqdn NAME FQDN to configure client with\n"); > + " --fqdn NAME FQDN to configure client with\n" > + " --dhcp-opt CODE,VAL Set DHCP option by code\n"); > if (strstr(name, "pasta")) > FPRINTF(f, " default: don't use any search list\n"); > else > @@ -844,6 +846,10 @@ static void conf_print(const struct ctx *c) > info(" router: %s", > inet_ntop(AF_INET, &c->ip4.guest_gw, > buf, sizeof(buf))); > + for (i = 0; i < c->custom_opts_count; i++) > + info(" option %u: %s", > + c->custom_opts[i].code, > + c->custom_opts[i].str); > } > > for (i = 0; i < ARRAY_SIZE(c->ip4.dns); i++) { > @@ -1233,6 +1239,7 @@ void conf(struct ctx *c, int argc, char **argv) > {"migrate-no-linger", no_argument, NULL, 30 }, > {"stats", required_argument, NULL, 31 }, > {"conf-path", required_argument, NULL, 'c' }, > + {"dhcp-opt", required_argument, NULL, 33 }, > { 0 }, > }; > const char *optstring = "+dqfel:hs:c:F:I:p:P:m:a:n:M:g:i:o:D:S:H:461t:u:T:U:"; > @@ -1465,6 +1472,33 @@ void conf(struct ctx *c, int argc, char **argv) > die("Can't display statistics if not running in foreground"); > c->stats = strtol(optarg, NULL, 0); > break; > + case 33: { > + unsigned long code; > + const char *comma; > + char *end; > + > + comma = strchr(optarg, ','); > + if (!comma) > + die("--dhcp-opt requires Option CODE,VALUE format"); > + > + code = strtoul(optarg, &end, 0); > + if (end != comma || code < 1 || code > 254) > + die("DHCP option code must be 1-254: %s", > + optarg); > + > + if (c->custom_opts_count >= MAX_CUSTOM_DHCP_OPTS) > + die("Too many --dhcp-opt entries (max %d)", > + MAX_CUSTOM_DHCP_OPTS); > + > + c->custom_opts[c->custom_opts_count].code = code; > + if (snprintf_check(c->custom_opts[c->custom_opts_count].str, > + sizeof(c->custom_opts[0].str), > + "%s", comma + 1)) > + die("DHCP option value too long: %s", > + comma + 1); > + c->custom_opts_count++; > + break; > + } > case 'd': > c->debug = 1; > c->quiet = 0; > diff --git a/passt.h b/passt.h > index 1726965..acb57dd 100644 > --- a/passt.h > +++ b/passt.h > @@ -263,6 +263,16 @@ struct ctx { > char hostname[PASST_MAXDNAME]; > char fqdn[PASST_MAXDNAME]; > > +#define MAX_CUSTOM_DHCP_OPTS 32 > + > + struct { > + uint8_t code; > + uint8_t len; > + uint8_t val[255]; The @len and @val fields are not used so far. I'm assuming they are later in the series, but in that case it's generally preferable to add those fields in the patches that use them. Possible more comments there. > + char str[256]; > + } custom_opts[MAX_CUSTOM_DHCP_OPTS]; > + int custom_opts_count; > + > int ifi6; > struct ip6_ctx ip6; > > -- > 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