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;