]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http-act/tcp-act: Add "set-log-level" for tcp content rules
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 25 Jun 2021 12:35:29 +0000 (14:35 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 25 Jun 2021 14:11:46 +0000 (16:11 +0200)
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.

doc/configuration.txt
include/haproxy/action-t.h
src/http_act.c
src/http_ana.c
src/stream.c

index 49f7e189c458282f1c7bd33eb628dd50d5cb0810..d94bdf2f1435f872ba3526ecc496053350066e4d 100644 (file)
@@ -12056,6 +12056,7 @@ tcp-request content <action> [{if | unless} <condition>]
     - sc-set-gpt0(<sc-id>) { <int> | <expr> }
     - set-dst <expr>
     - set-dst-port <expr>
+    - set-log-level <level>
     - set-src <expr>
     - set-src-port <expr>
     - set-var(<var-name>) <expr>
@@ -12108,6 +12109,9 @@ tcp-request content <action> [{if | unless} <condition>]
   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 <action> [{if | unless} <condition>]
         or false (when used with "unless"). The first such rule executed ends
         the rules evaluation. Rejected session are immediately closed.
 
+    - set-log-level <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(<var-name>) <expr>
         Sets a variable.
 
index d4fc3f6dabad777c8d9d5c4fff64d0891c9a51ac..2e56848d8f200d47556873b3dfd0e9dc55eec3b2 100644 (file)
@@ -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,
 
index 0aa8a37594b3a15493b3e40a462060edd86516a5..3bc72d79430e667a3265a14b189369f4b055ff10 100644 (file)
@@ -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 },
index be0f7471198c9517a3cf620d18b5be03be347dad..29a9806b67d58531586e0a5ff2de785e504d8a8f 100644 (file)
@@ -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))
index c9c01fce28e4911393ced9b401e8ee9619d555d3..3525bc42e7405e4bb9b602525ff335f3769c004c 100644 (file)
@@ -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)
 {