From: Christopher Faulet Date: Tue, 21 Feb 2023 10:16:08 +0000 (+0100) Subject: MINOR: cfgcond: Implement enabled condition expression X-Git-Tag: v2.8-dev5~149 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c13f3028e8e5576b9b7dedd984fc44db01c25f90;p=thirdparty%2Fhaproxy.git MINOR: cfgcond: Implement enabled condition expression Implement a way to test if some options are enabled at run-time. For now, following options may be detected: POLL, EPOLL, KQUEUE, EVPORTS, SPLICE, GETADDRINFO, REUSEPORT, FAST-FORWARD, SERVER-SSL-VERIFY-NONE These options are those that can be disabled on the command line. This way it is possible, from a reg-test for instance, to know if a feature is supported or not : feature cmd "$HAPROXY_PROGRAM -cc '!(globa.tune & GTUNE_NO_FAST_FWD)'" --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 8aea55ebb8..370b96022c 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -877,6 +877,12 @@ The list of currently supported predicates is the following: version syntax is the same as shown by "haproxy -v" and missing components are assumed as being zero. + - enabled() : returns true if the option is enabled at + run-time. Only a subset of options are supported: + POLL, EPOLL, KQUEUE, EVPORTS, SPLICE, + GETADDRINFO, REUSEPORT, FAST-FORWARD, + SERVER-SSL-VERIFY-NONE + Example: .if defined(HAPROXY_MWORKER) diff --git a/include/haproxy/cfgcond-t.h b/include/haproxy/cfgcond-t.h index 206ae06255..00fc1267b1 100644 --- a/include/haproxy/cfgcond-t.h +++ b/include/haproxy/cfgcond-t.h @@ -54,6 +54,7 @@ enum cond_predicate { CFG_PRED_OSSL_VERSION_ATLEAST, // "openssl_version_atleast" CFG_PRED_OSSL_VERSION_BEFORE, // "openssl_version_before" CFG_PRED_SSLLIB_NAME_STARTSWITH, // "ssllib_name_startswith" + CFG_PRED_ENABLED, // "enabled" }; /* types for condition terms */ diff --git a/src/cfgcond.c b/src/cfgcond.c index b29fcbf095..89036ada3f 100644 --- a/src/cfgcond.c +++ b/src/cfgcond.c @@ -28,6 +28,7 @@ const struct cond_pred_kw cond_predicates[] = { { "openssl_version_atleast", CFG_PRED_OSSL_VERSION_ATLEAST, ARG1(1, STR) }, { "openssl_version_before", CFG_PRED_OSSL_VERSION_BEFORE, ARG1(1, STR) }, { "ssllib_name_startswith", CFG_PRED_SSLLIB_NAME_STARTSWITH, ARG1(1, STR) }, + { "enabled", CFG_PRED_ENABLED, ARG1(1, STR) }, { NULL, CFG_PRED_NONE, 0 } }; @@ -175,6 +176,33 @@ int cfg_parse_cond_term(const char **text, struct cfg_cond_term **term, char **e return -1; } +/* evaluate a "enabled" expression. Only a subset of options are matched. It + * returns 1 if the option is enabled. 0 is returned is the option is not + * enabled or if it is not recognized. + */ +static int cfg_eval_cond_enabled(const char *str) +{ + if (strcmp(str, "POLL") == 0) + return !!(global.tune.options & GTUNE_USE_POLL); + else if (strcmp(str, "EPOLL") == 0) + return !!(global.tune.options & GTUNE_USE_EPOLL); + else if (strcmp(str, "KQUEUE") == 0) + return !!(global.tune.options & GTUNE_USE_EPOLL); + else if (strcmp(str, "EVPORTS") == 0) + return !!(global.tune.options & GTUNE_USE_EVPORTS); + else if (strcmp(str, "SPLICE") == 0) + return !!(global.tune.options & GTUNE_USE_SPLICE); + else if (strcmp(str, "GETADDRINFO") == 0) + return !!(global.tune.options & GTUNE_USE_GAI); + else if (strcmp(str, "REUSEPORT") == 0) + return !!(global.tune.options & GTUNE_USE_REUSEPORT); + else if (strcmp(str, "FAST-FORWARD") == 0) + return !!(global.tune.options & GTUNE_USE_FAST_FWD); + else if (strcmp(str, "SERVER-SSL-VERIFY-NONE") == 0) + return !!(global.ssl_server_verify == SSL_SERVER_VERIFY_NONE); + return 0; +} + /* evaluate a condition term on a .if/.elif line. The condition was already * parsed in . Returns -1 on error (in which case err is filled with a * message, and only in this case), 0 if the condition is false, 1 if it's @@ -260,6 +288,10 @@ int cfg_eval_cond_term(const struct cfg_cond_term *term, char **err) ret = openssl_compare_current_name(term->args[0].data.str.area) == 0; break; } + case CFG_PRED_ENABLED: { // checks if the arg matches on a subset of enabled options + ret = cfg_eval_cond_enabled(term->args[0].data.str.area) != 0; + break; + } default: memprintf(err, "internal error: unhandled conditional expression predicate '%s'", term->pred->word); break;