From: Christopher Faulet Date: Fri, 25 Jun 2021 12:35:29 +0000 (+0200) Subject: MINOR: http-act/tcp-act: Add "set-log-level" for tcp content rules X-Git-Tag: v2.5-dev1~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=551a641cff24af548218dc7fff5c3990dc774a30;p=thirdparty%2Fhaproxy.git MINOR: http-act/tcp-act: Add "set-log-level" for tcp content rules It is now possible to set the stream log level from a "tcp-request content" or "tcp-response content" ruleset. To do so, the action parsing is moved in stream.c and the action evaluation is handled in a dedicated function. This patch should fix issue #1306. It may be backported as far as 2.2 if necessary. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 49f7e189c4..d94bdf2f14 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -12056,6 +12056,7 @@ tcp-request content [{if | unless} ] - sc-set-gpt0() { | } - set-dst - set-dst-port + - set-log-level - set-src - set-src-port - set-var() @@ -12108,6 +12109,9 @@ tcp-request content [{if | unless} ] The "set-dst" and "set-dst-port" are used to set respectively the destination IP and port. More information on how to use it at "http-request set-dst". + The "set-log-level" is used to set the log level of the current session. More + information on how to use it at "http-request set-log-level". + The "set-src" and "set-src-port" are used to set respectively the source IP and port. More information on how to use it at "http-request set-src". @@ -12350,6 +12354,11 @@ tcp-response content [{if | unless} ] or false (when used with "unless"). The first such rule executed ends the rules evaluation. Rejected session are immediately closed. + - set-log-level + The "set-log-level" is used to set the log level of the current + session. More information on how to use it at "http-response + set-log-level". + - set-var() Sets a variable. diff --git a/include/haproxy/action-t.h b/include/haproxy/action-t.h index d4fc3f6dab..2e56848d8f 100644 --- a/include/haproxy/action-t.h +++ b/include/haproxy/action-t.h @@ -82,7 +82,6 @@ enum act_name { /* common http actions .*/ ACT_HTTP_REDIR, ACT_HTTP_SET_NICE, - ACT_HTTP_SET_LOGL, ACT_HTTP_SET_TOS, ACT_HTTP_SET_MARK, diff --git a/src/http_act.c b/src/http_act.c index 0aa8a37594..3bc72d7943 100644 --- a/src/http_act.c +++ b/src/http_act.c @@ -1406,32 +1406,6 @@ static enum act_parse_ret parse_http_set_mark(const char **args, int *orig_arg, #endif } -/* Parse a "set-log-level" action. It takes the level value as argument. It - * returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error. - */ -static enum act_parse_ret parse_http_set_log_level(const char **args, int *orig_arg, struct proxy *px, - struct act_rule *rule, char **err) -{ - int cur_arg; - - rule->action = ACT_HTTP_SET_LOGL; - - cur_arg = *orig_arg; - if (!*args[cur_arg]) { - bad_log_level: - memprintf(err, "expects exactly 1 argument (log level name or 'silent')"); - return ACT_RET_PRS_ERR; - } - if (strcmp(args[cur_arg], "silent") == 0) - rule->arg.http.i = -1; - else if ((rule->arg.http.i = get_log_level(args[cur_arg]) + 1) == 0) - goto bad_log_level; - - LIST_INIT(&rule->arg.http.fmt); - *orig_arg = cur_arg + 1; - return ACT_RET_PRS_OK; -} - /* This function executes a early-hint action. It adds an HTTP Early Hint HTTP * 103 response header with <.arg.http.str> name and with a value built * according to <.arg.http.fmt> log line format. If it is the first early-hint @@ -2508,7 +2482,6 @@ static struct action_kw_list http_req_actions = { { "replace-value", parse_http_replace_header, 0 }, { "return", parse_http_return, 0 }, { "set-header", parse_http_set_header, 0 }, - { "set-log-level", parse_http_set_log_level, 0 }, { "set-map", parse_http_set_map, KWF_MATCH_PREFIX }, { "set-method", parse_set_req_line, 0 }, { "set-mark", parse_http_set_mark, 0 }, @@ -2544,7 +2517,6 @@ static struct action_kw_list http_res_actions = { { "replace-value", parse_http_replace_header, 0 }, { "return", parse_http_return, 0 }, { "set-header", parse_http_set_header, 0 }, - { "set-log-level", parse_http_set_log_level, 0 }, { "set-map", parse_http_set_map, KWF_MATCH_PREFIX }, { "set-mark", parse_http_set_mark, 0 }, { "set-nice", parse_http_set_nice, 0 }, diff --git a/src/http_ana.c b/src/http_ana.c index be0f747119..29a9806b67 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -2843,10 +2843,6 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis conn_set_mark(objt_conn(sess->origin), rule->arg.http.i); break; - case ACT_HTTP_SET_LOGL: - s->logs.level = rule->arg.http.i; - break; - /* other flags exists, but normally, they never be matched. */ default: break; @@ -2978,10 +2974,6 @@ resume_execution: conn_set_mark(objt_conn(sess->origin), rule->arg.http.i); break; - case ACT_HTTP_SET_LOGL: - s->logs.level = rule->arg.http.i; - break; - case ACT_HTTP_REDIR: rule_ret = HTTP_RULE_RES_ABRT; if (!http_apply_redirect_rule(rule->arg.redir, s, txn)) diff --git a/src/stream.c b/src/stream.c index c9c01fce28..3525bc42e7 100644 --- a/src/stream.c +++ b/src/stream.c @@ -2850,6 +2850,42 @@ struct ist stream_generate_unique_id(struct stream *strm, struct list *format) /************************************************************************/ /* All supported ACL keywords must be declared here. */ /************************************************************************/ +static enum act_return stream_action_set_log_level(struct act_rule *rule, struct proxy *px, + struct session *sess, struct stream *s, int flags) +{ + s->logs.level = (uintptr_t)rule->arg.act.p[0]; + return ACT_RET_CONT; +} + + +/* Parse a "set-log-level" action. It takes the level value as argument. It + * returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error. + */ +static enum act_parse_ret stream_parse_set_log_level(const char **args, int *cur_arg, struct proxy *px, + struct act_rule *rule, char **err) +{ + int level; + + if (!*args[*cur_arg]) { + bad_log_level: + memprintf(err, "expects exactly 1 argument (log level name or 'silent')"); + return ACT_RET_PRS_ERR; + } + if (strcmp(args[*cur_arg], "silent") == 0) + level = -1; + else if ((level = get_log_level(args[*cur_arg]) + 1) == 0) + goto bad_log_level; + + (*cur_arg)++; + + /* Register processing function. */ + rule->action_ptr = stream_action_set_log_level; + rule->action = ACT_CUSTOM; + rule->arg.act.p[0] = (void *)(uintptr_t)level; + return ACT_RET_PRS_OK; +} + + static enum act_return tcp_action_switch_stream_mode(struct act_rule *rule, struct proxy *px, struct session *sess, struct stream *s, int flags) { @@ -3705,20 +3741,37 @@ static struct cli_kw_list cli_kws = {{ },{ INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws); /* main configuration keyword registration. */ -static struct action_kw_list stream_tcp_keywords = { ILH, { - { "switch-mode", stream_parse_switch_mode }, - { "use-service", stream_parse_use_service }, +static struct action_kw_list stream_tcp_req_keywords = { ILH, { + { "set-log-level", stream_parse_set_log_level }, + { "switch-mode", stream_parse_switch_mode }, + { "use-service", stream_parse_use_service }, + { /* END */ } +}}; + +INITCALL1(STG_REGISTER, tcp_req_cont_keywords_register, &stream_tcp_req_keywords); + +/* main configuration keyword registration. */ +static struct action_kw_list stream_tcp_res_keywords = { ILH, { + { "set-log-level", stream_parse_set_log_level }, + { /* END */ } +}}; + +INITCALL1(STG_REGISTER, tcp_res_cont_keywords_register, &stream_tcp_res_keywords); + +static struct action_kw_list stream_http_req_keywords = { ILH, { + { "set-log-level", stream_parse_set_log_level }, + { "use-service", stream_parse_use_service }, { /* END */ } }}; -INITCALL1(STG_REGISTER, tcp_req_cont_keywords_register, &stream_tcp_keywords); +INITCALL1(STG_REGISTER, http_req_keywords_register, &stream_http_req_keywords); -static struct action_kw_list stream_http_keywords = { ILH, { - { "use-service", stream_parse_use_service }, +static struct action_kw_list stream_http_res_keywords = { ILH, { + { "set-log-level", stream_parse_set_log_level }, { /* END */ } }}; -INITCALL1(STG_REGISTER, http_req_keywords_register, &stream_http_keywords); +INITCALL1(STG_REGISTER, http_res_keywords_register, &stream_http_res_keywords); static int smp_fetch_cur_server_timeout(const struct arg *args, struct sample *smp, const char *km, void *private) {