]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: actions: Add flags to configure the action behaviour
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 18 Dec 2019 13:58:12 +0000 (14:58 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 20 Jan 2020 14:18:45 +0000 (15:18 +0100)
Some flags can now be set on an action when it is registered. The flags are
defined in the act_flag enum. For now, only ACT_FLAG_FINAL may be set on an
action to specify if it stops the rules evaluation. It is set on
ACT_ACTION_ALLOW, ACT_ACTION_DENY, ACT_HTTP_REQ_TARPIT, ACT_HTTP_REQ_AUTH,
ACT_HTTP_REDIR and ACT_TCP_CLOSE actions. But, when required, it may also be set
on custom actions.

Consequently, this flag is checked instead of the action type during the
configuration parsing to trigger a warning when a rule inhibits all the
following ones.

include/types/action.h
src/cfgparse-listen.c
src/http_act.c
src/tcp_rules.c

index d13a54903fd077c3854bc0c33df750c48f13617f..1a7e9a641d73be3a068dbe5fd1d72e9780b14d87 100644 (file)
@@ -59,6 +59,12 @@ enum act_opt {
        ACT_OPT_FIRST = 0x00000002,  /* first call for this action */
 };
 
+/* Flags used to describe the action. */
+enum act_flag {
+        ACT_FLAG_FINAL = 1 << 0, /* the action stops the rules evaluation when executed */
+};
+
+
 /* known actions to be used without any action function pointer. This enum is
  * typically used in a switch case, iff .action_ptr is undefined. So if an
  * action function is defined for one of following action types, the function
@@ -110,6 +116,7 @@ struct act_rule {
        struct list list;
        struct acl_cond *cond;                 /* acl condition to meet */
        enum act_name action;                  /* ACT_ACTION_* */
+       unsigned int flags;                    /* ACT_FLAG_* */
        enum act_from from;                    /* ACT_F_* */
        enum act_return (*action_ptr)(struct act_rule *rule, struct proxy *px,  /* ptr to custom action */
                                      struct session *sess, struct stream *s, int opts);
index 9975e4687640d3e0985685daa5a3c94401bd50e5..0151130cd71c0e9b7a952049c7f5801406b77d46 100644 (file)
@@ -1333,10 +1333,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
 
                if (!LIST_ISEMPTY(&curproxy->http_req_rules) &&
                    !LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->cond &&
-                   (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
-                    LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_ACTION_DENY ||
-                    LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REDIR ||
-                    LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->action == ACT_HTTP_REQ_AUTH)) {
+                   (LIST_PREV(&curproxy->http_req_rules, struct act_rule *, list)->flags & ACT_FLAG_FINAL)) {
                        ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
                                   file, linenum, args[0]);
                        err_code |= ERR_WARN;
@@ -1367,8 +1364,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
 
                if (!LIST_ISEMPTY(&curproxy->http_res_rules) &&
                    !LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->cond &&
-                   (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_ALLOW ||
-                    LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->action == ACT_ACTION_DENY)) {
+                   (LIST_PREV(&curproxy->http_res_rules, struct act_rule *, list)->flags & ACT_FLAG_FINAL)) {
                        ha_warning("parsing [%s:%d]: previous '%s' action is final and has no condition attached, further entries are NOOP.\n",
                                   file, linenum, args[0]);
                        err_code |= ERR_WARN;
index 994e3b47c0524ca7983625e8d735493b5736ae98..564e5ba66e558410f39b5e31201d472f56c27e77 100644 (file)
@@ -748,6 +748,7 @@ static enum act_parse_ret parse_http_allow(const char **args, int *orig_arg, str
                                           struct act_rule *rule, char **err)
 {
        rule->action = ACT_ACTION_ALLOW;
+       rule->flags |= ACT_FLAG_FINAL;
        return ACT_RET_PRS_OK;
 }
 
@@ -769,6 +770,7 @@ static enum act_parse_ret parse_http_req_deny(const char **args, int *orig_arg,
                rule->action = ACT_ACTION_DENY;
                rule->arg.http.i = HTTP_ERR_403;
        }
+       rule->flags |= ACT_FLAG_FINAL;
 
        if (strcmp(args[cur_arg], "deny_status") == 0) {
                cur_arg++;
@@ -801,6 +803,7 @@ static enum act_parse_ret parse_http_res_deny(const char **args, int *orig_arg,
                                              struct act_rule *rule, char **err)
 {
        rule->action = ACT_ACTION_DENY;
+       rule->flags |= ACT_FLAG_FINAL;
        return ACT_RET_PRS_OK;
 }
 
@@ -813,6 +816,7 @@ static enum act_parse_ret parse_http_auth(const char **args, int *orig_arg, stru
        int cur_arg;
 
        rule->action = ACT_HTTP_REQ_AUTH;
+       rule->flags |= ACT_FLAG_FINAL;
 
        cur_arg = *orig_arg;
        if (!strcmp(args[cur_arg], "realm")) {
@@ -1071,6 +1075,7 @@ static enum act_parse_ret parse_http_redirect(const char **args, int *orig_arg,
        int dir, cur_arg;
 
        rule->action = ACT_HTTP_REDIR;
+       rule->flags |= ACT_FLAG_FINAL;
 
        cur_arg = *orig_arg;
 
index ebf4e05c72366956b49017e6f1dbb24d2dfc1cd9..fae2e152bc95bc439a7a90cbfe4ed534717532f1 100644 (file)
@@ -660,14 +660,17 @@ static int tcp_parse_response_rule(char **args, int arg, int section_type,
        if (strcmp(args[arg], "accept") == 0) {
                arg++;
                rule->action = ACT_ACTION_ALLOW;
+               rule->flags |= ACT_FLAG_FINAL;
        }
        else if (strcmp(args[arg], "reject") == 0) {
                arg++;
                rule->action = ACT_ACTION_DENY;
+               rule->flags |= ACT_FLAG_FINAL;
        }
        else if (strcmp(args[arg], "close") == 0) {
                arg++;
                rule->action = ACT_TCP_CLOSE;
+               rule->flags |= ACT_FLAG_FINAL;
        }
        else {
                struct action_kw *kw;
@@ -721,10 +724,12 @@ static int tcp_parse_request_rule(char **args, int arg, int section_type,
        if (!strcmp(args[arg], "accept")) {
                arg++;
                rule->action = ACT_ACTION_ALLOW;
+               rule->flags |= ACT_FLAG_FINAL;
        }
        else if (!strcmp(args[arg], "reject")) {
                arg++;
                rule->action = ACT_ACTION_DENY;
+               rule->flags |= ACT_FLAG_FINAL;
        }
        else if (strcmp(args[arg], "capture") == 0) {
                struct sample_expr *expr;