mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
[MEDIUM] acl: when possible, report the name and requirements of ACLs in warnings
When an ACL is referenced at a wrong place (eg: response during request, layer7 during layer4), try to indicate precisely the name and requirements of this ACL. Only the first faulty ACL is returned. A small change consisting in iterating that way may improve reports : cap = ACL_USE_any_unexpected while ((acl=cond_find_require(cond, cap))) { warning() cap &= ~acl->requires; } This will report the first ACL of each unsupported type. But doing so will mangle the error reporting a lot, so we need to rework error reports first.
This commit is contained in:
parent
0ceba5af74
commit
dd64f8d394
@ -87,6 +87,11 @@ struct acl_cond *parse_acl_cond(const char **args, struct list *known_acl, int p
|
|||||||
*/
|
*/
|
||||||
int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, void *l7, int dir);
|
int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, void *l7, int dir);
|
||||||
|
|
||||||
|
/* Reports a pointer to the first ACL used in condition <cond> which requires
|
||||||
|
* at least one of the USE_FLAGS in <require>. Returns NULL if none matches.
|
||||||
|
*/
|
||||||
|
struct acl *cond_find_require(struct acl_cond *cond, unsigned int require);
|
||||||
|
|
||||||
/* Return a pointer to the ACL <name> within the list starting at <head>, or
|
/* Return a pointer to the ACL <name> within the list starting at <head>, or
|
||||||
* NULL if not found.
|
* NULL if not found.
|
||||||
*/
|
*/
|
||||||
|
24
src/acl.c
24
src/acl.c
@ -1096,6 +1096,30 @@ int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, v
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Reports a pointer to the first ACL used in condition <cond> which requires
|
||||||
|
* at least one of the USE_FLAGS in <require>. Returns NULL if none matches.
|
||||||
|
* The construct is almost the same as for acl_exec_cond() since we're walking
|
||||||
|
* down the ACL tree as well. It is important that the tree is really walked
|
||||||
|
* through and never cached, because that way, this function can be used as a
|
||||||
|
* late check.
|
||||||
|
*/
|
||||||
|
struct acl *cond_find_require(struct acl_cond *cond, unsigned int require)
|
||||||
|
{
|
||||||
|
struct acl_term_suite *suite;
|
||||||
|
struct acl_term *term;
|
||||||
|
struct acl *acl;
|
||||||
|
|
||||||
|
list_for_each_entry(suite, &cond->suites, list) {
|
||||||
|
list_for_each_entry(term, &suite->terms, list) {
|
||||||
|
acl = term->acl;
|
||||||
|
if (acl->requires & require)
|
||||||
|
return acl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* All supported keywords must be declared here. */
|
/* All supported keywords must be declared here. */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
@ -1244,8 +1244,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
|
|||||||
|
|
||||||
cond->line = linenum;
|
cond->line = linenum;
|
||||||
if (cond->requires & ACL_USE_RTR_ANY) {
|
if (cond->requires & ACL_USE_RTR_ANY) {
|
||||||
Warning("parsing [%s:%d] : switching rule involves some response-only criteria which will be ignored.\n",
|
struct acl *acl;
|
||||||
file, linenum);
|
const char *name;
|
||||||
|
|
||||||
|
acl = cond_find_require(cond, ACL_USE_RTR_ANY);
|
||||||
|
name = acl ? acl->name : "(unknown)";
|
||||||
|
Warning("parsing [%s:%d] : acl '%s' involves some response-only criteria which will be ignored.\n",
|
||||||
|
file, linenum, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
rule = (struct switching_rule *)calloc(1, sizeof(*rule));
|
rule = (struct switching_rule *)calloc(1, sizeof(*rule));
|
||||||
|
@ -377,6 +377,7 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
|
|||||||
|
|
||||||
if (!strcmp(args[1], "content")) {
|
if (!strcmp(args[1], "content")) {
|
||||||
int action;
|
int action;
|
||||||
|
int warn = 0;
|
||||||
int pol = ACL_COND_NONE;
|
int pol = ACL_COND_NONE;
|
||||||
struct acl_cond *cond;
|
struct acl_cond *cond;
|
||||||
struct tcp_rule *rule;
|
struct tcp_rule *rule;
|
||||||
@ -410,17 +411,32 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
|
|||||||
if (pol != ACL_COND_NONE &&
|
if (pol != ACL_COND_NONE &&
|
||||||
(cond = parse_acl_cond((const char **)args+4, &curpx->acl, pol)) == NULL) {
|
(cond = parse_acl_cond((const char **)args+4, &curpx->acl, pol)) == NULL) {
|
||||||
retlen = snprintf(err, errlen,
|
retlen = snprintf(err, errlen,
|
||||||
"Error detected in %s '%s' while parsing '%s' condition",
|
"error detected in %s '%s' while parsing '%s' condition",
|
||||||
proxy_type_str(curpx), curpx->id, args[3]);
|
proxy_type_str(curpx), curpx->id, args[3]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: how to set this ?
|
||||||
|
// cond->line = linenum;
|
||||||
|
if (cond->requires & (ACL_USE_RTR_ANY | ACL_USE_L7_ANY)) {
|
||||||
|
struct acl *acl;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
acl = cond_find_require(cond, ACL_USE_RTR_ANY|ACL_USE_L7_ANY);
|
||||||
|
name = acl ? acl->name : "(unknown)";
|
||||||
|
|
||||||
|
retlen = snprintf(err, errlen,
|
||||||
|
"acl '%s' involves some %s criteria which will be ignored.",
|
||||||
|
name,
|
||||||
|
(acl->requires & ACL_USE_RTR_ANY) ? "response-only" : "layer 7");
|
||||||
|
warn++;
|
||||||
|
}
|
||||||
rule = (struct tcp_rule *)calloc(1, sizeof(*rule));
|
rule = (struct tcp_rule *)calloc(1, sizeof(*rule));
|
||||||
rule->cond = cond;
|
rule->cond = cond;
|
||||||
rule->action = action;
|
rule->action = action;
|
||||||
LIST_INIT(&rule->list);
|
LIST_INIT(&rule->list);
|
||||||
LIST_ADDQ(&curpx->tcp_req.inspect_rules, &rule->list);
|
LIST_ADDQ(&curpx->tcp_req.inspect_rules, &rule->list);
|
||||||
return 0;
|
return warn;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(err, errlen, "unknown argument '%s' after '%s' in %s '%s'",
|
snprintf(err, errlen, "unknown argument '%s' after '%s' in %s '%s'",
|
||||||
|
Loading…
Reference in New Issue
Block a user