diff --git a/src/acl.c b/src/acl.c index dc9925d51..025e4780a 100644 --- a/src/acl.c +++ b/src/acl.c @@ -1396,6 +1396,26 @@ struct acl_expr *parse_acl_expr(const char **args) if (nbargs < 0) goto out_free_expr; } + else if (ARGM(aclkw->arg_mask) == 1) { + int type = (aclkw->arg_mask >> 4) & 15; + + /* If a proxy is noted as a mandatory argument, we'll fake + * an empty one so that acl_find_targets() resolves it as + * the current one later. + */ + if (type != ARGT_FE && type != ARGT_BE && type != ARGT_TAB) + goto out_free_expr; + + /* Build an arg list containing the type as an empty string + * and the usual STOP. + */ + expr->args = calloc(2, sizeof(*expr->args)); + expr->args[0].type = type; + expr->args[0].data.str.str = strdup(""); + expr->args[0].data.str.len = 1; + expr->args[0].data.str.len = 0; + expr->args[1].type = ARGT_STOP; + } else if (ARGM(aclkw->arg_mask)) { /* there were some mandatory arguments */ goto out_free_expr; @@ -2013,20 +2033,23 @@ acl_find_targets(struct proxy *p) expr->args->data.srv = srv; } else if (arg->type == ARGT_FE) { - struct proxy *prx; - char *pname; + struct proxy *prx = p; + char *pname = p->id; - if (!expr->args->data.str.len) { - Alert("proxy %s: acl '%s' %s(): missing frontend name.\n", - p->id, acl->name, expr->kw->kw); + if (expr->args->data.str.len) { + pname = expr->args->data.str.str; + prx = findproxy(pname, PR_CAP_FE); + } + + if (!prx) { + Alert("proxy %s: acl '%s' %s(): unable to find frontend '%s'.\n", + p->id, acl->name, expr->kw->kw, pname); cfgerr++; continue; } - pname = expr->args->data.str.str; - prx = findproxy(pname, PR_CAP_FE); - if (!prx) { - Alert("proxy %s: acl '%s' %s(): unable to find frontend '%s'.\n", + if (!(prx->cap & PR_CAP_FE)) { + Alert("proxy %s: acl '%s' %s(): proxy '%s' has no frontend capability.\n", p->id, acl->name, expr->kw->kw, pname); cfgerr++; continue; @@ -2036,20 +2059,23 @@ acl_find_targets(struct proxy *p) expr->args->data.prx = prx; } else if (arg->type == ARGT_BE) { - struct proxy *prx; - char *pname; + struct proxy *prx = p; + char *pname = p->id; - if (!expr->args->data.str.len) { - Alert("proxy %s: acl '%s' %s(): missing backend name.\n", - p->id, acl->name, expr->kw->kw); + if (expr->args->data.str.len) { + pname = expr->args->data.str.str; + prx = findproxy(pname, PR_CAP_BE); + } + + if (!prx) { + Alert("proxy %s: acl '%s' %s(): unable to find backend '%s'.\n", + p->id, acl->name, expr->kw->kw, pname); cfgerr++; continue; } - pname = expr->args->data.str.str; - prx = findproxy(pname, PR_CAP_BE); - if (!prx) { - Alert("proxy %s: acl '%s' %s(): unable to find backend '%s'.\n", + if (!(prx->cap & PR_CAP_BE)) { + Alert("proxy %s: acl '%s' %s(): proxy '%s' has no backend capability.\n", p->id, acl->name, expr->kw->kw, pname); cfgerr++; continue; @@ -2059,20 +2085,24 @@ acl_find_targets(struct proxy *p) expr->args->data.prx = prx; } else if (arg->type == ARGT_TAB) { - struct proxy *prx; - char *pname; + struct proxy *prx = p; + char *pname = p->id; - if (!expr->args->data.str.len) { - Alert("proxy %s: acl '%s' %s(): missing table name.\n", - p->id, acl->name, expr->kw->kw); + if (expr->args->data.str.len) { + pname = expr->args->data.str.str; + prx = find_stktable(pname); + } + + if (!prx) { + Alert("proxy %s: acl '%s' %s(): unable to find table '%s'.\n", + p->id, acl->name, expr->kw->kw, pname); cfgerr++; continue; } - pname = expr->args->data.str.str; - prx = find_stktable(pname); - if (!prx) { - Alert("proxy %s: acl '%s' %s(): unable to find table '%s'.\n", + + if (!prx->table.size) { + Alert("proxy %s: acl '%s' %s(): no table in proxy '%s'.\n", p->id, acl->name, expr->kw->kw, pname); cfgerr++; continue; diff --git a/src/backend.c b/src/backend.c index fd2528f4a..b0d7c39b1 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1578,13 +1578,13 @@ acl_fetch_srv_conn(struct proxy *px, struct session *l4, void *l7, int dir, * Please take care of keeping this list alphabetically sorted. */ static struct acl_kw_list acl_kws = {{ },{ - { "avg_queue", acl_parse_int, acl_fetch_avg_queue_size, acl_match_int, ACL_USE_NOTHING, ARG1(0,BE) }, - { "be_conn", acl_parse_int, acl_fetch_be_conn, acl_match_int, ACL_USE_NOTHING, ARG1(0,BE) }, + { "avg_queue", acl_parse_int, acl_fetch_avg_queue_size, acl_match_int, ACL_USE_NOTHING, ARG1(1,BE) }, + { "be_conn", acl_parse_int, acl_fetch_be_conn, acl_match_int, ACL_USE_NOTHING, ARG1(1,BE) }, { "be_id", acl_parse_int, acl_fetch_be_id, acl_match_int, ACL_USE_NOTHING, 0 }, - { "be_sess_rate", acl_parse_int, acl_fetch_be_sess_rate, acl_match_int, ACL_USE_NOTHING, ARG1(0,BE) }, - { "connslots", acl_parse_int, acl_fetch_connslots, acl_match_int, ACL_USE_NOTHING, ARG1(0,BE) }, - { "nbsrv", acl_parse_int, acl_fetch_nbsrv, acl_match_int, ACL_USE_NOTHING, ARG1(0,BE) }, - { "queue", acl_parse_int, acl_fetch_queue_size, acl_match_int, ACL_USE_NOTHING, ARG1(0,BE) }, + { "be_sess_rate", acl_parse_int, acl_fetch_be_sess_rate, acl_match_int, ACL_USE_NOTHING, ARG1(1,BE) }, + { "connslots", acl_parse_int, acl_fetch_connslots, acl_match_int, ACL_USE_NOTHING, ARG1(1,BE) }, + { "nbsrv", acl_parse_int, acl_fetch_nbsrv, acl_match_int, ACL_USE_NOTHING, ARG1(1,BE) }, + { "queue", acl_parse_int, acl_fetch_queue_size, acl_match_int, ACL_USE_NOTHING, ARG1(1,BE) }, { "srv_conn", acl_parse_int, acl_fetch_srv_conn, acl_match_int, ACL_USE_NOTHING, ARG1(1,SRV) }, { "srv_id", acl_parse_int, acl_fetch_srv_id, acl_match_int, ACL_USE_RTR_INTERNAL, 0 }, { "srv_is_up", acl_parse_nothing, acl_fetch_srv_is_up, acl_match_nothing, ACL_USE_NOTHING, ARG1(1,SRV) }, diff --git a/src/frontend.c b/src/frontend.c index ebe864bb9..9f8c3232f 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -544,9 +544,9 @@ acl_fetch_fe_conn(struct proxy *px, struct session *l4, void *l7, int dir, * Please take care of keeping this list alphabetically sorted. */ static struct acl_kw_list acl_kws = {{ },{ - { "fe_conn", acl_parse_int, acl_fetch_fe_conn, acl_match_int, ACL_USE_NOTHING, ARG1(0,FE) }, + { "fe_conn", acl_parse_int, acl_fetch_fe_conn, acl_match_int, ACL_USE_NOTHING, ARG1(1,FE) }, { "fe_id", acl_parse_int, acl_fetch_fe_id, acl_match_int, ACL_USE_NOTHING, 0 }, - { "fe_sess_rate", acl_parse_int, acl_fetch_fe_sess_rate, acl_match_int, ACL_USE_NOTHING, ARG1(0,FE) }, + { "fe_sess_rate", acl_parse_int, acl_fetch_fe_sess_rate, acl_match_int, ACL_USE_NOTHING, ARG1(1,FE) }, { NULL, NULL, NULL, NULL }, }}; diff --git a/src/session.c b/src/session.c index 4c5671a75..999701479 100644 --- a/src/session.c +++ b/src/session.c @@ -3372,25 +3372,25 @@ static struct acl_kw_list acl_kws = {{ },{ { "sc2_kbytes_out", acl_parse_int, acl_fetch_sc2_kbytes_out, acl_match_int, ACL_USE_TCP4_VOLATILE, 0 }, { "sc2_sess_cnt", acl_parse_int, acl_fetch_sc2_sess_cnt, acl_match_int, ACL_USE_NOTHING, 0 }, { "sc2_sess_rate", acl_parse_int, acl_fetch_sc2_sess_rate, acl_match_int, ACL_USE_NOTHING, 0 }, - { "src_bytes_in_rate", acl_parse_int, acl_fetch_src_bytes_in_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_bytes_out_rate", acl_parse_int, acl_fetch_src_bytes_out_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_clr_gpc0", acl_parse_int, acl_fetch_src_clr_gpc0, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_conn_cnt", acl_parse_int, acl_fetch_src_conn_cnt, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_conn_cur", acl_parse_int, acl_fetch_src_conn_cur, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_conn_rate", acl_parse_int, acl_fetch_src_conn_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_get_gpc0", acl_parse_int, acl_fetch_src_get_gpc0, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_http_err_cnt", acl_parse_int, acl_fetch_src_http_err_cnt, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_http_err_rate", acl_parse_int, acl_fetch_src_http_err_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_http_req_cnt", acl_parse_int, acl_fetch_src_http_req_cnt, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_http_req_rate", acl_parse_int, acl_fetch_src_http_req_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_inc_gpc0", acl_parse_int, acl_fetch_src_inc_gpc0, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_kbytes_in", acl_parse_int, acl_fetch_src_kbytes_in, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_kbytes_out", acl_parse_int, acl_fetch_src_kbytes_out, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_sess_cnt", acl_parse_int, acl_fetch_src_sess_cnt, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_sess_rate", acl_parse_int, acl_fetch_src_sess_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "src_updt_conn_cnt", acl_parse_int, acl_fetch_src_updt_conn_cnt, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(0,TAB) }, - { "table_avl", acl_parse_int, acl_fetch_table_avl, acl_match_int, ACL_USE_NOTHING, ARG1(0,TAB) }, - { "table_cnt", acl_parse_int, acl_fetch_table_cnt, acl_match_int, ACL_USE_NOTHING, ARG1(0,TAB) }, + { "src_bytes_in_rate", acl_parse_int, acl_fetch_src_bytes_in_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_bytes_out_rate", acl_parse_int, acl_fetch_src_bytes_out_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_clr_gpc0", acl_parse_int, acl_fetch_src_clr_gpc0, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_conn_cnt", acl_parse_int, acl_fetch_src_conn_cnt, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_conn_cur", acl_parse_int, acl_fetch_src_conn_cur, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_conn_rate", acl_parse_int, acl_fetch_src_conn_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_get_gpc0", acl_parse_int, acl_fetch_src_get_gpc0, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_http_err_cnt", acl_parse_int, acl_fetch_src_http_err_cnt, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_http_err_rate", acl_parse_int, acl_fetch_src_http_err_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_http_req_cnt", acl_parse_int, acl_fetch_src_http_req_cnt, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_http_req_rate", acl_parse_int, acl_fetch_src_http_req_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_inc_gpc0", acl_parse_int, acl_fetch_src_inc_gpc0, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_kbytes_in", acl_parse_int, acl_fetch_src_kbytes_in, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_kbytes_out", acl_parse_int, acl_fetch_src_kbytes_out, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_sess_cnt", acl_parse_int, acl_fetch_src_sess_cnt, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_sess_rate", acl_parse_int, acl_fetch_src_sess_rate, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "src_updt_conn_cnt", acl_parse_int, acl_fetch_src_updt_conn_cnt, acl_match_int, ACL_USE_TCP4_VOLATILE, ARG1(1,TAB) }, + { "table_avl", acl_parse_int, acl_fetch_table_avl, acl_match_int, ACL_USE_NOTHING, ARG1(1,TAB) }, + { "table_cnt", acl_parse_int, acl_fetch_table_cnt, acl_match_int, ACL_USE_NOTHING, ARG1(1,TAB) }, { NULL, NULL, NULL, NULL }, }};