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
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);
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;
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;
struct act_rule *rule, char **err)
{
rule->action = ACT_ACTION_ALLOW;
+ rule->flags |= ACT_FLAG_FINAL;
return ACT_RET_PRS_OK;
}
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++;
struct act_rule *rule, char **err)
{
rule->action = ACT_ACTION_DENY;
+ rule->flags |= ACT_FLAG_FINAL;
return ACT_RET_PRS_OK;
}
int cur_arg;
rule->action = ACT_HTTP_REQ_AUTH;
+ rule->flags |= ACT_FLAG_FINAL;
cur_arg = *orig_arg;
if (!strcmp(args[cur_arg], "realm")) {
int dir, cur_arg;
rule->action = ACT_HTTP_REDIR;
+ rule->flags |= ACT_FLAG_FINAL;
cur_arg = *orig_arg;
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;
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;