From: Amaury Denoyelle Date: Mon, 12 Jan 2026 14:25:52 +0000 (+0100) Subject: MINOR: proxy: parse mode on dynamic backend creation X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e15291332797bc71562b4a5706561ce0d26a21a0;p=thirdparty%2Fhaproxy.git MINOR: proxy: parse mode on dynamic backend creation Add an optional "mode" argument to "add backend" CLI command. This argument allows to specify if the backend is in TCP or HTTP mode. By default, it is mandatory, unless the inherited default proxy already explicitely specifies the mode. To differentiate if TCP mode is implicit or explicit, a new proxy flag PR_FL_DEF_EXPLICIT_MODE is defined. It is set for every defaults instances which explicitely defined their mode. --- diff --git a/doc/management.txt b/doc/management.txt index b07f287ba..43eed4507 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -1725,14 +1725,17 @@ add acl [@] This command cannot be used if the reference is a name also used with a map. In this case, the "add map" command must be used instead. -add backend from [ EXPERIMENTAL ] +add backend from [mode ] [ EXPERIMENTAL ] Instantiate a new backend proxy with the name . Only TCP or HTTP proxies can be created. All of the settings are inherited - from default proxy instance. Servers can be added via the command - "add server". The backend is initialized in the unpublished state. Once - considered ready for traffic, use "publish backend" to expose the newly - created instance. + from default proxy instance. By default, it is mandatory to + specify the backend mode via the argument of the same name, unless + already defines it explicitely. + + Servers can be added via the command "add server". The backend is initialized + in the unpublished state. Once considered ready for traffic, use "publish + backend" to expose the newly created instance. This command is restricted and can only be issued on sockets configured for level "admin". Moreover, this feature is still considered in development so it diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h index 4f4b6c45d..20c359126 100644 --- a/include/haproxy/proxy-t.h +++ b/include/haproxy/proxy-t.h @@ -242,7 +242,7 @@ enum PR_SRV_STATE_FILE { /* Proxy flags */ #define PR_FL_DISABLED 0x01 /* The proxy was disabled in the configuration (not at runtime) */ #define PR_FL_STOPPED 0x02 /* The proxy was stopped */ -/* 0x04 unused */ +#define PR_FL_DEF_EXPLICIT_MODE 0x04 /* Proxy mode is explicitely defined - only used for defaults instance */ #define PR_FL_EXPLICIT_REF 0x08 /* The default proxy is explicitly referenced by another proxy */ #define PR_FL_IMPLICIT_REF 0x10 /* The default proxy is implicitly referenced by another proxy */ #define PR_FL_PAUSED 0x20 /* The proxy was paused at run time (reversible) */ diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index 3c27a638e..9a680ef09 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -657,6 +657,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) } curproxy->mode = mode; + if (curproxy->cap & PR_CAP_DEF) + curproxy->flags |= PR_FL_DEF_EXPLICIT_MODE; } else if (strcmp(args[0], "id") == 0) { struct proxy *conflict; diff --git a/src/proxy.c b/src/proxy.c index 3d9f9440b..43651b515 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -4789,6 +4789,7 @@ static int cli_parse_add_backend(char **args, char *payload, struct appctx *appc struct proxy *px, *defpx; const char *be_name, *def_name, *err; char *msg = NULL; + enum pr_mode mode = 0; usermsgs_clr("CLI"); @@ -4813,11 +4814,39 @@ static int cli_parse_add_backend(char **args, char *payload, struct appctx *appc return 1; } + /* Parse optional arguments */ + args += 2; + while (*args[1]) { + /* "mode" */ + if (*args[2] && !mode && strcmp(args[1], "mode") == 0) { + mode = str_to_proxy_mode(args[2]); + if (mode == PR_MODES) { + cli_err(appctx, "Unknown proxy mode.\n"); + return 1; + } + if (mode != PR_MODE_TCP && mode != PR_MODE_HTTP) { + cli_err(appctx, "Dynamic backends are compatible with only TCP or HTTP mode.\n"); + return 1; + } + } + /* unknown, malformed or duplicate argument */ + else { + cli_err(appctx, "Usage: add backend from [mode ].\n"); + return 1; + } + + args += 2; + } + defpx = proxy_find_by_name(def_name, PR_CAP_DEF, 0); if (!defpx) { cli_dynerr(appctx, memprintf(&msg, "Cannot find default proxy '%s'.\n", def_name)); return 1; } + if (!(defpx->flags & PR_FL_DEF_EXPLICIT_MODE) && !mode) { + cli_dynerr(appctx, memprintf(&msg, "Mode is required as '%s' default proxy does not explicitely defines it.\n", def_name)); + return 1; + } thread_isolate();