MEDIUM: stick-table: add the new array of gpt data_type

This patch adds the definition of a new array data_type
'gpt'. This is an array of 32bits General Purpose Tags.

Like for all arrays, it is limited to 100 elements.

This patch also adds actions and fetches to handle
elements of this array.

Note: As documented, those new actions and fetches won't
apply to the legacy 'gpt0' data type.
This commit is contained in:
Emeric Brun 2021-06-30 18:57:49 +02:00 committed by Willy Tarreau
parent 1a6b7254de
commit 877b0b5a7b
4 changed files with 321 additions and 34 deletions

View File

@ -6416,6 +6416,18 @@ http-request sc-inc-gpc1(<sc-id>) [ { if | unless } <condition> ]
counter designated by <sc-id>. If an error occurs, this action silently fails
and the actions evaluation continues.
http-request sc-set-gpt(<idx>,<sc-id>) { <int> | <expr> }
[ { if | unless } <condition> ]
This action sets the 32-bit unsigned GPT at the index <idx> of the array
associated to the sticky counter designated by <sc-id> at the value of
<int>/<expr>. The expected result is a boolean.
If an error occurs, this action silently fails and the actions evaluation
continues. <idx> is an integer between 0 and 99 and <sc-id> is an integer
between 0 and 2. It also silently fails if the there is no GPT stored
at this index.
This action applies only to the 'gpt' array data_type (and not to the
legacy 'gpt0' data-type).
http-request sc-set-gpt0(<sc-id>) { <int> | <expr> }
[ { if | unless } <condition> ]
@ -7115,6 +7127,19 @@ http-response sc-inc-gpc1(<sc-id>) [ { if | unless } <condition> ]
counter designated by <sc-id>. If an error occurs, this action silently fails
and the actions evaluation continues.
http-response sc-set-gpt(<idx>,<sc-id>) { <int> | <expr> }
[ { if | unless } <condition> ]
This action sets the 32-bit unsigned GPT at the index <idx> of the array
associated to the sticky counter designated by <sc-id> at the value of
<int>/<expr>. The expected result is a boolean.
If an error occurs, this action silently fails and the actions evaluation
continues. <idx> is an integer between 0 and 99 and <sc-id> is an integer
between 0 and 2. It also silently fails if the there is no GPT stored
at this index.
This action applies only to the 'gpt' array data_type (and not to the
legacy 'gpt0' data-type).
http-response sc-set-gpt0(<sc-id>) { <int> | <expr> }
[ { if | unless } <condition> ]
@ -11182,6 +11207,17 @@ stick-table type {ip | integer | string [len <length>] | binary [len <length>]}
incremented. Most of the time it will be used to measure the frequency of
occurrence of certain events (e.g. requests to a specific URL).
- gpt(<nb>) : General Purpose Tags Array of <nb> elements. This is an array
of positive 32-bit integers which may be used for anything.
Most of the time they will be used to put a special tags on some entries,
for instance to note that a specific behavior was detected and must be
known for future matches. This array is limited to a maximum of 100
elements: gpt0 to gpt99, to ensure that the build of a peer update
message can fit into the buffer. Users should take in consideration
that a large amount of counters will increase the data size and the
traffic load using peers protocol since all data/counters are pushed
each time any of them is updated.
- gpt0 : first General Purpose Tag. It is a positive 32-bit integer
integer which may be used for anything. Most of the time it will be used
to put a special tag on some entries, for instance to note that a
@ -11901,6 +11937,17 @@ tcp-request connection <action> [{if | unless} <condition>]
counter designated by <sc-id>. If an error occurs, this action silently
fails and the actions evaluation continues.
- sc-set-gpt(<idx>,<sc-id>) { <int> | <expr> }:
This action sets the 32-bit unsigned GPT at the index <idx> of the
array associated to the sticky counter designated by <sc-id> at the
value of <int>/<expr>. The expected result is a boolean.
If an error occurs, this action silently fails and the actions
evaluation continues. <idx> is an integer between 0 and 99 and <sc-id>
is an integer between 0 and 2. It also silently fails if the there is
no GPT stored at this index.
This action applies only to the 'gpt' array data_type (and not to the
legacy 'gpt0' data-type).
- sc-set-gpt0(<sc-id>) { <int> | <expr> }:
This action sets the 32-bit unsigned GPT0 tag according to the sticky
counter designated by <sc-id> and the value of <int>/<expr>. The
@ -12085,6 +12132,7 @@ tcp-request content <action> [{if | unless} <condition>]
- { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>]
- sc-inc-gpc0(<sc-id>)
- sc-inc-gpc1(<sc-id>)
- sc-set-gpt(<idx>,<sc-id>) { <int> | <expr> }
- sc-set-gpt0(<sc-id>) { <int> | <expr> }
- set-dst <expr>
- set-dst-port <expr>
@ -12434,6 +12482,17 @@ tcp-response content <action> [{if | unless} <condition>]
counter designated by <sc-id>. If an error occurs, this action fails
silently and the actions evaluation continues.
- sc-set-gpt(<idx>,<sc-id>) { <int> | <expr> }
This action sets the 32-bit unsigned GPT at the index <idx> of the
array associated to the sticky counter designated by <sc-id> at the
value of <int>/<expr>. The expected result is a boolean.
If an error occurs, this action silently fails and the actions
evaluation continues. <idx> is an integer between 0 and 99 and <sc-id>
is an integer between 0 and 2. It also silently fails if the there is
no GPT stored at this index.
This action applies only to the 'gpt' array data_type (and not to the
legacy 'gpt0' data-type).
- sc-set-gpt0(<sc-id>) { <int> | <expr> }
This action sets the 32-bit unsigned GPT0 tag according to the sticky
counter designated by <sc-id> and the value of <int>/<expr>. The
@ -12559,6 +12618,7 @@ tcp-request session <action> [{if | unless} <condition>]
- { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>]
- sc-inc-gpc0(<sc-id>)
- sc-inc-gpc1(<sc-id>)
- sc-set-gpt(<idx>,<sc-id>) { <int> | <expr> }
- sc-set-gpt0(<sc-id>) { <int> | <expr> }
- set-mark <mark>
- set-dst <expr>
@ -16702,6 +16762,17 @@ table_conn_rate(<table>)
rate associated with the input sample in the designated table. See also the
sc_conn_rate sample fetch keyword.
table_gpt(<idx>,<table>)
Uses the string representation of the input sample to perform a lookup in
the specified table. If the key is not found in the table, boolean value zero
is returned. Otherwise the converter returns the current value of the general
purpose tag at the index <idx> of the array associated to the input sample
in the designated <table>. <idx> is an integer between 0 and 99.
If there is no GPT stored at this index, it also returns the boolean value 0.
This applies only to the 'gpt' array data_type (and not on the legacy 'gpt0'
data-type).
See also the sc_get_gpt sample fetch keyword.
table_gpt0(<table>)
Uses the string representation of the input sample to perform a look up in
the specified table. If the key is not found in the table, boolean value zero
@ -17753,6 +17824,15 @@ sc2_get_gpc1([<table>]) : integer
Returns the value of the second General Purpose Counter associated to the
currently tracked counters. See also src_get_gpc1 and sc/sc0/sc1/sc2_inc_gpc1.
sc_get_gpt(<idx>,<ctr>[,<table>]) : integer
Returns the value of the first General Purpose Tag at the index <idx> of
the array associated to the tracked counter of ID <ctr> and from the
current proxy's sitck-table or the designated stick-table <table>. <idx>
is an integer between 0 and 99 and <ctr> an integer between 0 and 2.
If there is no GPT stored at this index, zero is returned.
This fetch applies only to the 'gpt' array data_type (and not on
the legacy 'gpt0' data-type). See also src_get_gpt.
sc_get_gpt0(<ctr>[,<table>]) : integer
sc0_get_gpt0([<table>]) : integer
sc1_get_gpt0([<table>]) : integer
@ -18014,6 +18094,14 @@ src_get_gpc1([<table>]) : integer
the designated stick-table. If the address is not found, zero is returned.
See also sc/sc0/sc1/sc2_get_gpc1 and src_inc_gpc1.
src_get_gpt(<idx>[,<table>]) : integer
Returns the value of the first General Purpose Tag at the index <idx> of
the array associated to the incoming connection's source address in the
current proxy's stick-table or in the designated stick-table <table>.
<idx> is an integer between 0 and 99.
If the address is not found or the GPT is not stored, zero is returned.
See also the sc_get_gpt sample fetch keyword.
src_get_gpt0([<table>]) : integer
Returns the value of the first General Purpose Tag associated to the
incoming connection's source address in the current proxy's stick-table or in

View File

@ -171,6 +171,7 @@ struct act_rule {
} gpc;
struct {
int sc;
unsigned int idx;
long long int value;
struct sample_expr *expr;
} gpt;

View File

@ -60,6 +60,8 @@ enum {
STKTABLE_DT_SERVER_KEY, /* The server key */
STKTABLE_DT_HTTP_FAIL_CNT, /* cumulated number of HTTP server failures */
STKTABLE_DT_HTTP_FAIL_RATE,/* HTTP server failures rate */
STKTABLE_DT_GPT, /* array of gpt */
STKTABLE_STATIC_DATA_TYPES,/* number of types above */
/* up to STKTABLE_EXTRA_DATA_TYPES types may be registered here, always

View File

@ -1143,6 +1143,7 @@ struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES] = {
[STKTABLE_DT_SERVER_KEY] = { .name = "server_key", .std_type = STD_T_DICT },
[STKTABLE_DT_HTTP_FAIL_CNT] = { .name = "http_fail_cnt", .std_type = STD_T_UINT },
[STKTABLE_DT_HTTP_FAIL_RATE]= { .name = "http_fail_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY },
[STKTABLE_DT_GPT] = { .name = "gpt", .std_type = STD_T_UINT, .is_array = 1 },
};
/* Registers stick-table extra data type with index <idx>, name <name>, type
@ -1406,6 +1407,45 @@ static int sample_conv_table_bytes_out_rate(const struct arg *arg_p, struct samp
return !!ptr;
}
/* Casts sample <smp> to the type of the table specified in arg_p(1), and looks
* it up into this table. Returns the value of the GPT[arg_p(0)] tag for the key
* if the key is present in the table, otherwise false, so that comparisons can
* be easily performed. If the inspected parameter is not stored in the table,
* <not found> is returned.
*/
static int sample_conv_table_gpt(const struct arg *arg_p, struct sample *smp, void *private)
{
struct stktable *t;
struct stktable_key *key;
struct stksess *ts;
void *ptr;
unsigned int idx;
idx = arg_p[0].data.sint;
t = arg_p[1].data.t;
key = smp_to_stkey(smp, t);
if (!key)
return 0;
ts = stktable_lookup_key(t, key);
smp->flags = SMP_F_VOL_TEST;
smp->data.type = SMP_T_SINT;
smp->data.u.sint = 0;
if (!ts) /* key not present */
return 1;
ptr = stktable_data_ptr_idx(t, ts, STKTABLE_DT_GPT, idx);
if (ptr)
smp->data.u.sint = stktable_data_cast(ptr, std_t_uint);
stktable_release(t, ts);
return !!ptr;
}
/* Casts sample <smp> to the type of the table specified in arg(0), and looks
* it up into this table. Returns the value of the GPT0 tag for the key
* if the key is present in the table, otherwise false, so that comparisons can
@ -2185,6 +2225,77 @@ static enum act_parse_ret parse_inc_gpc1(const char **args, int *arg, struct pro
return ACT_RET_PRS_OK;
}
/* This function sets the gpt at index 'rule->arg.gpt.idx' of the array on the
* tracksc counter of index 'rule->arg.gpt.sc' stored into the <stream> or
* directly in the session <sess> if <stream> is set to NULL. This gpt is
* set to the value computed by the expression 'rule->arg.gpt.expr' or if
* 'rule->arg.gpt.expr' is null directly to the value of 'rule->arg.gpt.value'.
*
* This function always returns ACT_RET_CONT and parameter flags is unused.
*/
static enum act_return action_set_gpt(struct act_rule *rule, struct proxy *px,
struct session *sess, struct stream *s, int flags)
{
void *ptr;
struct stksess *ts;
struct stkctr *stkctr;
unsigned int value = 0;
struct sample *smp;
int smp_opt_dir;
/* Extract the stksess, return OK if no stksess available. */
if (s)
stkctr = &s->stkctr[rule->arg.gpt.sc];
else
stkctr = &sess->stkctr[rule->arg.gpt.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_idx(stkctr->table, ts, STKTABLE_DT_GPT, rule->arg.gpt.idx);
if (ptr) {
if (!rule->arg.gpt.expr)
value = (unsigned int)(rule->arg.gpt.value);
else {
switch (rule->from) {
case ACT_F_TCP_REQ_SES: smp_opt_dir = SMP_OPT_DIR_REQ; break;
case ACT_F_TCP_REQ_CNT: smp_opt_dir = SMP_OPT_DIR_REQ; break;
case ACT_F_TCP_RES_CNT: smp_opt_dir = SMP_OPT_DIR_RES; break;
case ACT_F_HTTP_REQ: smp_opt_dir = SMP_OPT_DIR_REQ; break;
case ACT_F_HTTP_RES: smp_opt_dir = SMP_OPT_DIR_RES; break;
default:
send_log(px, LOG_ERR, "stick table: internal error while setting gpt%u.", rule->arg.gpt.idx);
if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
ha_alert("stick table: internal error while executing setting gpt%u.\n", rule->arg.gpt.idx);
return ACT_RET_CONT;
}
/* Fetch and cast the expression. */
smp = sample_fetch_as_type(px, sess, s, smp_opt_dir|SMP_OPT_FINAL, rule->arg.gpt.expr, SMP_T_SINT);
if (!smp) {
send_log(px, LOG_WARNING, "stick table: invalid expression or data type while setting gpt%u.", rule->arg.gpt.idx);
if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
ha_alert("stick table: invalid expression or data type while setting gpt%u.\n", rule->arg.gpt.idx);
return ACT_RET_CONT;
}
value = (unsigned int)(smp->data.u.sint);
}
HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
stktable_data_cast(ptr, std_t_uint) = value;
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
stktable_touch_local(stkctr->table, ts, 0);
}
return ACT_RET_CONT;
}
/* Always returns 1. */
static enum act_return action_set_gpt0(struct act_rule *rule, struct proxy *px,
struct session *sess, struct stream *s, int flags)
@ -2248,46 +2359,78 @@ static enum act_return action_set_gpt0(struct act_rule *rule, struct proxy *px,
return ACT_RET_CONT;
}
/* This function is a common parser for using variables. It understands
* the format:
/* This function is a parser for the "sc-set-gpt" and "sc-set-gpt0" actions.
* It understands the formats:
*
* set-gpt0(<stick-table ID>) <expression>
* sc-set-gpt(<gpt IDX>,<track ID>) <expression>
* sc-set-gpt0(<track ID>) <expression>
*
* It returns 0 if fails and <err> is filled with an error message. Otherwise,
* it returns 1 and the variable <expr> is filled with the pointer to the
* expression to execute.
* It returns ACT_RET_PRS_ERR if fails and <err> is filled with an error message.
* Otherwise, it returns ACT_RET_PRS_OK and the variable 'rule->arg.gpt.expr'
* is filled with the pointer to the expression to execute or NULL if the arg
* is directly an integer stored into 'rule->arg.gpt.value'.
*/
static enum act_parse_ret parse_set_gpt0(const char **args, int *arg, struct proxy *px,
static enum act_parse_ret parse_set_gpt(const char **args, int *arg, struct proxy *px,
struct act_rule *rule, char **err)
{
const char *cmd_name = args[*arg-1];
char *error;
int smp_val;
cmd_name += strlen("sc-set-gpt0");
if (*cmd_name == '\0') {
/* default stick table id. */
rule->arg.gpt.sc = 0;
} else {
/* parse the stick table id. */
if (*cmd_name != '(') {
memprintf(err, "invalid stick table track ID '%s'. Expects sc-set-gpt0(<Track ID>)", args[*arg-1]);
return ACT_RET_PRS_ERR;
}
cmd_name++; /* jump the '(' */
rule->arg.gpt.sc = strtol(cmd_name, &error, 10); /* Convert stick table id. */
if (*error != ')') {
memprintf(err, "invalid stick table track ID '%s'. Expects sc-set-gpt0(<Track ID>)", args[*arg-1]);
cmd_name += strlen("sc-set-gpt");
if (*cmd_name == '(') {
cmd_name++; /* skip the '(' */
rule->arg.gpt.idx = strtoul(cmd_name, &error, 10); /* Convert stick table id. */
if (*error != ',') {
memprintf(err, "Missing gpt ID '%s'. Expects sc-set-gpt(<GPT ID>,<Track ID>)", args[*arg-1]);
return ACT_RET_PRS_ERR;
}
else {
cmd_name = error + 1; /* skip the ',' */
rule->arg.gpt.sc = strtol(cmd_name, &error, 10); /* Convert stick table id. */
if (*error != ')') {
memprintf(err, "invalid stick table track ID '%s'. Expects sc-set-gpt(<GPT ID>,<Track ID>)", args[*arg-1]);
return ACT_RET_PRS_ERR;
}
if (rule->arg.gpt.sc >= MAX_SESS_STKCTR) {
memprintf(err, "invalid stick table track ID '%s'. The max allowed ID is %d",
args[*arg-1], MAX_SESS_STKCTR-1);
return ACT_RET_PRS_ERR;
if (rule->arg.gpt.sc >= MAX_SESS_STKCTR) {
memprintf(err, "invalid stick table track ID '%s'. The max allowed ID is %d",
args[*arg-1], MAX_SESS_STKCTR-1);
return ACT_RET_PRS_ERR;
}
}
rule->action_ptr = action_set_gpt;
}
else if (*cmd_name == '0') {
cmd_name++;
if (*cmd_name == '\0') {
/* default stick table id. */
rule->arg.gpt.sc = 0;
} else {
/* parse the stick table id. */
if (*cmd_name != '(') {
memprintf(err, "invalid stick table track ID '%s'. Expects sc-set-gpt0(<Track ID>)", args[*arg-1]);
return ACT_RET_PRS_ERR;
}
cmd_name++; /* jump the '(' */
rule->arg.gpt.sc = strtol(cmd_name, &error, 10); /* Convert stick table id. */
if (*error != ')') {
memprintf(err, "invalid stick table track ID '%s'. Expects sc-set-gpt0(<Track ID>)", args[*arg-1]);
return ACT_RET_PRS_ERR;
}
if (rule->arg.gpt.sc >= MAX_SESS_STKCTR) {
memprintf(err, "invalid stick table track ID '%s'. The max allowed ID is %d",
args[*arg-1], MAX_SESS_STKCTR-1);
return ACT_RET_PRS_ERR;
}
}
rule->action_ptr = action_set_gpt0;
}
else {
/* default stick table id. */
memprintf(err, "invalid gpt ID '%s'. Expects sc-set-gpt(<GPT ID>,<Track ID>)", args[*arg-1]);
return ACT_RET_PRS_ERR;
}
rule->arg.gpt.expr = NULL;
@ -2318,7 +2461,6 @@ static enum act_parse_ret parse_set_gpt0(const char **args, int *arg, struct pro
(*arg)++;
rule->action = ACT_CUSTOM;
rule->action_ptr = action_set_gpt0;
return ACT_RET_PRS_OK;
}
@ -2488,6 +2630,51 @@ smp_fetch_sc_tracked(const struct arg *args, struct sample *smp, const char *kw,
return 1;
}
/* set <smp> to the General Purpose Tag of index set as first arg
* to value from the stream's tracked frontend counters or from the src.
* Supports being called as "sc_get_gpt(<gpt-idx>,<sc-idx>[,<table>])" or
* "src_get_gpt(<gpt-idx>[,<table>])" only. Value zero is returned if
* the key is new or gpt is not stored.
*/
static int
smp_fetch_sc_get_gpt(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct stkctr tmpstkctr;
struct stkctr *stkctr;
unsigned int idx;
idx = args[0].data.sint;
stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args + 1, kw, &tmpstkctr);
if (!stkctr)
return 0;
smp->flags = SMP_F_VOL_TEST;
smp->data.type = SMP_T_SINT;
smp->data.u.sint = 0;
if (stkctr_entry(stkctr)) {
void *ptr;
ptr = stktable_data_ptr_idx(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPT, idx);
if (!ptr) {
if (stkctr == &tmpstkctr)
stktable_release(stkctr->table, stkctr_entry(stkctr));
return 0; /* parameter not stored */
}
HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
smp->data.u.sint = stktable_data_cast(ptr, std_t_uint);
HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
if (stkctr == &tmpstkctr)
stktable_release(stkctr->table, stkctr_entry(stkctr));
}
return 1;
}
/* set <smp> to the General Purpose Flag 0 value from the stream's tracked
* frontend counters or from the src.
* Supports being called as "sc[0-9]_get_gpc0" or "src_get_gpt0" only. Value
@ -4183,7 +4370,8 @@ INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws);
static struct action_kw_list tcp_conn_kws = { { }, {
{ "sc-inc-gpc0", parse_inc_gpc0, KWF_MATCH_PREFIX },
{ "sc-inc-gpc1", parse_inc_gpc1, KWF_MATCH_PREFIX },
{ "sc-set-gpt0", parse_set_gpt0, KWF_MATCH_PREFIX },
{ "sc-set-gpt", parse_set_gpt, KWF_MATCH_PREFIX },
{ "sc-set-gpt0", parse_set_gpt, KWF_MATCH_PREFIX },
{ /* END */ }
}};
@ -4192,7 +4380,8 @@ INITCALL1(STG_REGISTER, tcp_req_conn_keywords_register, &tcp_conn_kws);
static struct action_kw_list tcp_sess_kws = { { }, {
{ "sc-inc-gpc0", parse_inc_gpc0, KWF_MATCH_PREFIX },
{ "sc-inc-gpc1", parse_inc_gpc1, KWF_MATCH_PREFIX },
{ "sc-set-gpt0", parse_set_gpt0, KWF_MATCH_PREFIX },
{ "sc-set-gpt", parse_set_gpt, KWF_MATCH_PREFIX },
{ "sc-set-gpt0", parse_set_gpt, KWF_MATCH_PREFIX },
{ /* END */ }
}};
@ -4201,7 +4390,8 @@ INITCALL1(STG_REGISTER, tcp_req_sess_keywords_register, &tcp_sess_kws);
static struct action_kw_list tcp_req_kws = { { }, {
{ "sc-inc-gpc0", parse_inc_gpc0, KWF_MATCH_PREFIX },
{ "sc-inc-gpc1", parse_inc_gpc1, KWF_MATCH_PREFIX },
{ "sc-set-gpt0", parse_set_gpt0, KWF_MATCH_PREFIX },
{ "sc-set-gpt", parse_set_gpt, KWF_MATCH_PREFIX },
{ "sc-set-gpt0", parse_set_gpt, KWF_MATCH_PREFIX },
{ /* END */ }
}};
@ -4210,7 +4400,8 @@ INITCALL1(STG_REGISTER, tcp_req_cont_keywords_register, &tcp_req_kws);
static struct action_kw_list tcp_res_kws = { { }, {
{ "sc-inc-gpc0", parse_inc_gpc0, KWF_MATCH_PREFIX },
{ "sc-inc-gpc1", parse_inc_gpc1, KWF_MATCH_PREFIX },
{ "sc-set-gpt0", parse_set_gpt0, KWF_MATCH_PREFIX },
{ "sc-set-gpt", parse_set_gpt, KWF_MATCH_PREFIX },
{ "sc-set-gpt0", parse_set_gpt, KWF_MATCH_PREFIX },
{ /* END */ }
}};
@ -4219,7 +4410,8 @@ INITCALL1(STG_REGISTER, tcp_res_cont_keywords_register, &tcp_res_kws);
static struct action_kw_list http_req_kws = { { }, {
{ "sc-inc-gpc0", parse_inc_gpc0, KWF_MATCH_PREFIX },
{ "sc-inc-gpc1", parse_inc_gpc1, KWF_MATCH_PREFIX },
{ "sc-set-gpt0", parse_set_gpt0, KWF_MATCH_PREFIX },
{ "sc-set-gpt", parse_set_gpt, KWF_MATCH_PREFIX },
{ "sc-set-gpt0", parse_set_gpt, KWF_MATCH_PREFIX },
{ /* END */ }
}};
@ -4228,7 +4420,8 @@ INITCALL1(STG_REGISTER, http_req_keywords_register, &http_req_kws);
static struct action_kw_list http_res_kws = { { }, {
{ "sc-inc-gpc0", parse_inc_gpc0, KWF_MATCH_PREFIX },
{ "sc-inc-gpc1", parse_inc_gpc1, KWF_MATCH_PREFIX },
{ "sc-set-gpt0", parse_set_gpt0, KWF_MATCH_PREFIX },
{ "sc-set-gpt", parse_set_gpt, KWF_MATCH_PREFIX },
{ "sc-set-gpt0", parse_set_gpt, KWF_MATCH_PREFIX },
{ /* END */ }
}};
@ -4245,6 +4438,7 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
{ "sc_conn_cnt", smp_fetch_sc_conn_cnt, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
{ "sc_conn_cur", smp_fetch_sc_conn_cur, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
{ "sc_conn_rate", smp_fetch_sc_conn_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
{ "sc_get_gpt", smp_fetch_sc_get_gpt, ARG3(2,SINT,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
{ "sc_get_gpt0", smp_fetch_sc_get_gpt0, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
{ "sc_get_gpc0", smp_fetch_sc_get_gpc0, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
{ "sc_get_gpc1", smp_fetch_sc_get_gpc1, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN },
@ -4349,6 +4543,7 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
{ "src_conn_cnt", smp_fetch_sc_conn_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
{ "src_conn_cur", smp_fetch_sc_conn_cur, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
{ "src_conn_rate", smp_fetch_sc_conn_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
{ "src_get_gpt" , smp_fetch_sc_get_gpt, ARG2(2,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
{ "src_get_gpt0", smp_fetch_sc_get_gpt0, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
{ "src_get_gpc0", smp_fetch_sc_get_gpc0, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
{ "src_get_gpc1", smp_fetch_sc_get_gpc1, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
@ -4382,6 +4577,7 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, {
{ "table_conn_cnt", sample_conv_table_conn_cnt, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_conn_cur", sample_conv_table_conn_cur, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_conn_rate", sample_conv_table_conn_rate, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_gpt", sample_conv_table_gpt, ARG2(2,SINT,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_gpt0", sample_conv_table_gpt0, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_gpc0", sample_conv_table_gpc0, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_gpc1", sample_conv_table_gpc1, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },