MINOR: actions: Add flags to configure the action behaviour
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.
diff --git a/include/types/action.h b/include/types/action.h
index d13a549..1a7e9a6 100644
--- a/include/types/action.h
+++ b/include/types/action.h
@@ -59,6 +59,12 @@
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 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);
diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c
index 9975e46..0151130 100644
--- a/src/cfgparse-listen.c
+++ b/src/cfgparse-listen.c
@@ -1333,10 +1333,7 @@
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 @@
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;
diff --git a/src/http_act.c b/src/http_act.c
index 994e3b4..564e5ba 100644
--- a/src/http_act.c
+++ b/src/http_act.c
@@ -748,6 +748,7 @@
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 @@
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 @@
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 @@
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 @@
int dir, cur_arg;
rule->action = ACT_HTTP_REDIR;
+ rule->flags |= ACT_FLAG_FINAL;
cur_arg = *orig_arg;
diff --git a/src/tcp_rules.c b/src/tcp_rules.c
index ebf4e05..fae2e15 100644
--- a/src/tcp_rules.c
+++ b/src/tcp_rules.c
@@ -660,14 +660,17 @@
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 @@
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;