From e0627bdae0300a91fb8f2d7dcf0b607ebd78c86e Mon Sep 17 00:00:00 2001 From: Thierry FOURNIER Date: Tue, 4 Aug 2015 08:20:33 +0200 Subject: [PATCH] MINOR: stick-tables: Add GPC0 actions This patch adds access to GPC0 through http and tcp actions --- doc/configuration.txt | 31 +++++++++++++++--- include/types/action.h | 3 ++ src/stick_table.c | 74 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 4 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index 8447ff1d3..ab8884d7f 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -3365,6 +3365,7 @@ http-request { allow | deny | tarpit | auth [realm ] | redirect | set-map() | set-var() | { track-sc0 | track-sc1 | track-sc2 } [table ] | + sc-inc-gpc0() | sc-set-gpt0() | lua } @@ -3635,6 +3636,11 @@ http-request { allow | deny | tarpit | auth [realm ] | redirect | an error occurs, this action silently fails and the actions evaluation continues. + - sc-inc-gpc0(): + This action increments the GPC0 counter according with the sticky counter + designated by . If an error occurs, this action silently fails and + the actions evaluation continues. + - "lua" is used to run a Lua function if the action is executed. The single parameter is the name of the function to run. The prototype of the function is documented in the API documentation. @@ -3745,6 +3751,7 @@ http-response { allow | deny | add-header | set-nice | del-map() | set-map() | set-var() | + sc-inc-gpc0() | sc-set-gpt0() | lua } @@ -3950,6 +3957,11 @@ http-response { allow | deny | add-header | set-nice | an error occurs, this action silently fails and the actions evaluation continues. + - sc-inc-gpc0(): + This action increments the GPC0 counter according with the sticky counter + designated by . If an error occurs, this action silently fails and + the actions evaluation continues. + There is no limit to the number of http-response statements per instance. It is important to know that http-response rules are processed very early in @@ -8312,6 +8324,11 @@ tcp-request connection [{if | unless} ] advantage over just checking the keys, because only one table lookup is performed for all ACL checks that make use of it. + - sc-inc-gpc0(): + The "sc-inc-gpc0" increments the GPC0 counter according to the sticky + counter designated by . If an error occurs, this action silently + fails and the actions evaluation continues. + - sc-set-gpt0() : This action sets the GPT0 tag according to the sticky counter designated by and the value of . The expected result is a boolean. If @@ -8354,8 +8371,8 @@ tcp-request content [{if | unless} ] Arguments : defines the action to perform if the condition applies. Valid actions include : "accept", "reject", "track-sc0", "track-sc1", - "track-sc2", "sc-set-gpt0", "capture" and "lua". See - "tcp-request connection" above for their signification. + "track-sc2", "sc-inc-gpc0", "sc-set-gpt0", "capture" and "lua". + See "tcp-request connection" above for their signification. is a standard layer 4-7 ACL-based condition (see section 7). @@ -8388,6 +8405,7 @@ tcp-request content [{if | unless} ] - reject : the request is rejected and the connection is closed - capture : the specified sample expression is captured - { track-sc0 | track-sc1 | track-sc2 } [table
] + - sc-inc-gpc0() - set-gpt0() - lua - set-var() @@ -8556,8 +8574,8 @@ tcp-response content [{if | unless} ] no | no | yes | yes Arguments : defines the action to perform if the condition applies. Valid - actions include : "accept", "close", "reject", "lua", and - "sc-set-gpt0". + actions include : "accept", "close", "reject", "lua", + "sc-inc-gpc0" and "sc-set-gpt0". is a standard layer 4-7 ACL-based condition (see section 7). @@ -8601,6 +8619,11 @@ tcp-response content [{if | unless} ] - set-var() Sets a variable. + - sc-inc-gpc0(): + This action increments the GPC0 counter according to the sticky + counter designated by . If an error occurs, this action fails + silently and the actions evaluation continues. + - sc-set-gpt0() : This action sets the GPT0 tag according to the sticky counter designated by and the value of . The expected result is a boolean. If diff --git a/include/types/action.h b/include/types/action.h index 5d1b2501f..4d438c108 100644 --- a/include/types/action.h +++ b/include/types/action.h @@ -130,6 +130,9 @@ struct act_rule { const char *name; enum vars_scope scope; } vars; + struct { + int sc; + } gpc; struct { int sc; long long int value; diff --git a/src/stick_table.c b/src/stick_table.c index 623667f29..7f3a5a752 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -1309,6 +1309,75 @@ static int sample_conv_table_trackers(const struct arg *arg_p, struct sample *sm return 1; } +/* Always returns 1. */ +static enum act_return action_inc_gpc0(struct act_rule *rule, struct proxy *px, + struct session *sess, struct stream *s) +{ + void *ptr; + struct stksess *ts; + struct stkctr *stkctr; + + /* Extract the stksess, return OK if no stksess available. */ + if (s) + stkctr = &s->stkctr[rule->arg.gpc.sc]; + else + stkctr = &sess->stkctr[rule->arg.gpc.sc]; + ts = stkctr_entry(stkctr); + if (!ts) + return ACT_RET_CONT; + + /* Store the sample in the required sc, and ignore errors. */ + ptr = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_GPC0); + if (!ptr) + return ACT_RET_CONT; + + stktable_data_cast(ptr, gpc0)++; + return ACT_RET_CONT; +} + +/* This function is a common parser for using variables. It understands + * the formats: + * + * sc-inc-gpc0() + * + * It returns 0 if fails and is filled with an error message. Otherwise, + * it returns 1 and the variable is filled with the pointer to the + * expression to execute. + */ +static enum act_parse_ret parse_inc_gpc0(const char **args, int *arg, struct proxy *px, + struct act_rule *rule, char **err) +{ + const char *cmd_name = args[*arg-1]; + char *error; + + cmd_name += strlen("sc-inc-gpc0"); + if (*cmd_name == '\0') { + /* default stick table id. */ + rule->arg.gpc.sc = 0; + } else { + /* parse the stick table id. */ + if (*cmd_name != '(') { + memprintf(err, "invalid stick table track ID. Expects %s()", args[*arg-1]); + return ACT_RET_PRS_ERR; + } + cmd_name++; /* jump the '(' */ + rule->arg.gpc.sc = strtol(cmd_name, &error, 10); /* Convert stick table id. */ + if (*error != ')') { + memprintf(err, "invalid stick table track ID. Expects %s()", args[*arg-1]); + return ACT_RET_PRS_ERR; + } + + if (rule->arg.gpc.sc >= ACT_ACTION_TRK_SCMAX) { + memprintf(err, "invalid stick table track ID. The max allowed ID is %d", + ACT_ACTION_TRK_SCMAX-1); + return ACT_RET_PRS_ERR; + } + } + rule->action = ACT_ACTION_CONT; + rule->action_ptr = action_inc_gpc0; + return ACT_RET_PRS_OK; +} + /* Always returns 1. */ static enum act_return action_set_gpt0(struct act_rule *rule, struct proxy *px, struct session *sess, struct stream *s) @@ -1388,26 +1457,31 @@ static enum act_parse_ret parse_set_gpt0(const char **args, int *arg, struct pro } static struct action_kw_list tcp_conn_kws = { { }, { + { "sc-inc-gpc0", parse_inc_gpc0, 1 }, { "sc-set-gpt0", parse_set_gpt0, 1 }, { /* END */ } }}; static struct action_kw_list tcp_req_kws = { { }, { + { "sc-inc-gpc0", parse_inc_gpc0, 1 }, { "sc-set-gpt0", parse_set_gpt0, 1 }, { /* END */ } }}; static struct action_kw_list tcp_res_kws = { { }, { + { "sc-inc-gpc0", parse_inc_gpc0, 1 }, { "sc-set-gpt0", parse_set_gpt0, 1 }, { /* END */ } }}; static struct action_kw_list http_req_kws = { { }, { + { "sc-inc-gpc0", parse_inc_gpc0, 1 }, { "sc-set-gpt0", parse_set_gpt0, 1 }, { /* END */ } }}; static struct action_kw_list http_res_kws = { { }, { + { "sc-inc-gpc0", parse_inc_gpc0, 1 }, { "sc-set-gpt0", parse_set_gpt0, 1 }, { /* END */ } }};