diff --git a/include/haproxy/cfgparse.h b/include/haproxy/cfgparse.h index a20a30e80..56535b783 100644 --- a/include/haproxy/cfgparse.h +++ b/include/haproxy/cfgparse.h @@ -140,7 +140,7 @@ int warnif_misplaced_tcp_req_sess(struct proxy *proxy, const char *file, int lin int warnif_misplaced_tcp_req_cont(struct proxy *proxy, const char *file, int line, const char *arg, const char *arg2); int warnif_misplaced_tcp_res_cont(struct proxy *proxy, const char *file, int line, const char *arg, const char *arg2); int warnif_misplaced_quic_init(struct proxy *proxy, const char *file, int line, const char *arg, const char *arg2); -int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line); +int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, char **err); int warnif_tcp_http_cond(const struct proxy *px, const struct acl_cond *cond); int too_many_args_idx(int maxarg, int index, char **args, char **msg, int *err_code); int too_many_args(int maxarg, char **args, char **msg, int *err_code); diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index 17bb88404..68bf93731 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -1395,7 +1395,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) where |= SMP_VAL_FE_HRQ_HDR; if (curproxy->cap & PR_CAP_BE) where |= SMP_VAL_BE_HRQ_HDR; - err_code |= warnif_cond_conflicts(rule->cond, where, file, linenum); + err_code |= warnif_cond_conflicts(rule->cond, where, &errmsg); + if (err_code) + ha_warning("parsing [%s:%d] : '%s.\n'", file, linenum, errmsg); LIST_APPEND(&curproxy->http_req_rules, &rule->list); } @@ -1428,7 +1430,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) where |= SMP_VAL_FE_HRS_HDR; if (curproxy->cap & PR_CAP_BE) where |= SMP_VAL_BE_HRS_HDR; - err_code |= warnif_cond_conflicts(rule->cond, where, file, linenum); + err_code |= warnif_cond_conflicts(rule->cond, where, &errmsg); + if (err_code) + ha_warning("parsing [%s:%d] : '%s.\n'", file, linenum, errmsg); LIST_APPEND(&curproxy->http_res_rules, &rule->list); } @@ -1460,7 +1464,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) where |= SMP_VAL_FE_HRS_HDR; if (curproxy->cap & PR_CAP_BE) where |= SMP_VAL_BE_HRS_HDR; - err_code |= warnif_cond_conflicts(rule->cond, where, file, linenum); + err_code |= warnif_cond_conflicts(rule->cond, where, &errmsg); + if (err_code) + ha_warning("parsing [%s:%d] : '%s.\n'", file, linenum, errmsg); LIST_APPEND(&curproxy->http_after_res_rules, &rule->list); } @@ -1522,7 +1528,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) where |= SMP_VAL_FE_HRQ_HDR; if (curproxy->cap & PR_CAP_BE) where |= SMP_VAL_BE_HRQ_HDR; - err_code |= warnif_cond_conflicts(rule->cond, where, file, linenum); + err_code |= warnif_cond_conflicts(rule->cond, where, &errmsg); + if (err_code) + ha_warning("parsing [%s:%d] : '%s.\n'", file, linenum, errmsg); } else if (strcmp(args[0], "use_backend") == 0) { struct switching_rule *rule; @@ -1550,7 +1558,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) goto out; } - err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, file, linenum); + err_code |= warnif_cond_conflicts(cond, SMP_VAL_FE_SET_BCK, &errmsg); + if (err_code) + ha_warning("parsing [%s:%d] : '%s.\n'", file, linenum, errmsg); } else if (*args[2]) { ha_alert("parsing [%s:%d] : unexpected keyword '%s' after switching rule, only 'if' and 'unless' are allowed.\n", @@ -1611,7 +1621,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) goto out; } - err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum); + err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, &errmsg); + if (err_code) + ha_warning("parsing [%s:%d] : '%s.\n'", file, linenum, errmsg); rule = calloc(1, sizeof(*rule)); if (!rule) @@ -1664,7 +1676,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) /* note: BE_REQ_CNT is the first one after FE_SET_BCK, which is * where force-persist is applied. */ - err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, file, linenum); + err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_REQ_CNT, &errmsg); + if (err_code) + ha_warning("parsing [%s:%d] : '%s.\n'", file, linenum, errmsg); rule = calloc(1, sizeof(*rule)); if (!rule) { @@ -1828,9 +1842,11 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) goto out; } if (flags & STK_ON_RSP) - err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, file, linenum); + err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_STO_RUL, &errmsg); else - err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, file, linenum); + err_code |= warnif_cond_conflicts(cond, SMP_VAL_BE_SET_SRV, &errmsg); + if (err_code) + ha_warning("parsing [%s:%d] : '%s.\n'", file, linenum, errmsg); rule = calloc(1, sizeof(*rule)); if (!rule) { @@ -1886,7 +1902,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) where |= SMP_VAL_FE_HRQ_HDR; if (curproxy->cap & PR_CAP_BE) where |= SMP_VAL_BE_HRQ_HDR; - err_code |= warnif_cond_conflicts(cond, where, file, linenum); + err_code |= warnif_cond_conflicts(cond, where, &errmsg); + if (err_code) + ha_warning("parsing [%s:%d] : '%s.\n'", file, linenum, errmsg); rule = calloc(1, sizeof(*rule)); if (!rule) { @@ -1964,7 +1982,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) where |= SMP_VAL_FE_HRQ_HDR; if (curproxy->cap & PR_CAP_BE) where |= SMP_VAL_BE_HRQ_HDR; - err_code |= warnif_cond_conflicts(rule->cond, where, file, linenum); + err_code |= warnif_cond_conflicts(rule->cond, where, &errmsg); + if (err_code) + ha_warning("parsing [%s:%d] : '%s.\n'", file, linenum, errmsg); LIST_APPEND(&curproxy->uri_auth->http_req_rules, &rule->list); } else if (strcmp(args[1], "auth") == 0) { diff --git a/src/cfgparse.c b/src/cfgparse.c index 64d5ef543..5f6d92162 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -390,12 +390,14 @@ int alertif_too_many_args(int maxarg, const char *file, int linenum, char **args } -/* Report it if a request ACL condition uses some keywords that are incompatible - * with the place where the ACL is used. It returns either 0 or ERR_WARN so that - * its result can be or'ed with err_code. Note that may be NULL and then - * will be ignored. +/* Report it if a request ACL condition uses some keywords that are + * incompatible with the place where the ACL is used. It returns either 0 or + * ERR_WARN so that its result can be or'ed with err_code. Note that may + * be NULL and then will be ignored. In case of error, is dynamically + * allocated to contains a description. */ -int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line) +int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, + char **err) { const struct acl *acl; const char *kw; @@ -405,23 +407,27 @@ int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const acl = acl_cond_conflicts(cond, where); if (acl) { - if (acl->name && *acl->name) - ha_warning("parsing [%s:%d] : acl '%s' will never match because it only involves keywords that are incompatible with '%s'\n", - file, line, acl->name, sample_ckp_names(where)); - else - ha_warning("parsing [%s:%d] : anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'\n", - file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where)); + if (acl->name && *acl->name) { + memprintf(err, "acl '%s' will never match because it only involves keywords that are incompatible with '%s'", + acl->name, sample_ckp_names(where)); + } + else { + memprintf(err, "anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'", + LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where)); + } return ERR_WARN; } if (!acl_cond_kw_conflicts(cond, where, &acl, &kw)) return 0; - if (acl->name && *acl->name) - ha_warning("parsing [%s:%d] : acl '%s' involves keywords '%s' which is incompatible with '%s'\n", - file, line, acl->name, kw, sample_ckp_names(where)); - else - ha_warning("parsing [%s:%d] : anonymous acl involves keyword '%s' which is incompatible with '%s'\n", - file, line, kw, sample_ckp_names(where)); + if (acl->name && *acl->name) { + memprintf(err, "acl '%s' involves keywords '%s' which is incompatible with '%s'", + acl->name, kw, sample_ckp_names(where)); + } + else { + memprintf(err, "anonymous acl involves keyword '%s' which is incompatible with '%s'", + kw, sample_ckp_names(where)); + } return ERR_WARN; }