MINOR: stktable: add table_{inc,clr}_gpc* converters

As discussed in GH #2423, there are some cases where src_{inc,clr}_gpc*
is not sufficient because we need to perform the lookup on a specific
key. Indeed, just like we did in e642916 ("MEDIUM: stktable: leverage
smp_fetch_* helpers from sample conv"), we can easily implement new
table converters based on existing fetches. This is what we do in
this patch.

Also the doc was updated so that src_{inc,clr}_gpc* fetches now point to
their generic equivalent table_{inc,clr}_gpc*. Indeed, src_{inc,clr}_gpc*
are simply aliases.

This should fix GH #2423.
This commit is contained in:
Aurelien DARRAGON 2025-01-15 21:14:21 +01:00
parent 9f68049cc1
commit 0486b9e491
2 changed files with 203 additions and 52 deletions

View File

@ -20144,6 +20144,9 @@ strcmp(var) string boolean
sub(value) integer integer
table_bytes_in_rate([table]) any integer
table_bytes_out_rate([table]) any integer
table_clr_gpc(idx[,table]) any integer
table_clr_gpc0([table]) any integer
table_clr_gpc1([table]) any integer
table_conn_cnt([table]) any integer
-- keyword -------------------------------------+- input type + output type -
table_conn_cur([table]) any integer
@ -20166,6 +20169,9 @@ table_http_fail_rate([table]) any integer
table_http_req_cnt([table]) any integer
table_http_req_rate([table]) any integer
table_idle([table[,default_value]]) any integer
table_inc_gpc(idx[,table]) any integer
table_inc_gpc0([table]) any integer
table_inc_gpc1([table]) any integer
table_kbytes_in([table]) any integer
-- keyword -------------------------------------+- input type + output type -
table_kbytes_out([table]) any integer
@ -21385,6 +21391,41 @@ table_bytes_out_rate([<table>])
table, measured in amount of bytes over the period configured in the table.
See also the sc_bytes_out_rate sample fetch keyword.
table_clr_gpc(<idx>[,<table>])
Uses the input sample to perform a look up in the current proxy's stick-table
or in the designated stick-table. Clears the General Purpose Counter at the
index <idx> of the gpc array and returns its previous value. <idx> is an
integer between 0 and 99. If the entry is not found, an entry is created and
0 is returned. This converter applies only to the 'gpc' array data_type (and
not to the legacy 'gpc0' nor 'gpc1' data_types).
See also the sc_clr_gpc sample fetch keyword.
table_clr_gpc0([<table>])
Uses the input sample to perform a look up in the current proxy's stick-table
or in the designated stick-table. Clears the first General Purpose Counter
'0' and returns its previous value. If the entry is not found, an entry is
created and 0 is returned. This is typically used as a second ACL in an
expression in order to mark a connection when a first ACL was verified :
Example:
# block if 5 consecutive requests continue to come faster than 10 sess
# per second, and reset the counter as soon as the traffic slows down.
acl abuse src_http_req_rate gt 10
acl kill src,table_inc_gpc0 gt 5
acl save src,table_clr_gpc0 ge 0
tcp-request connection accept if !abuse save
tcp-request connection reject if abuse kill
See also the sc_clr_gpc0 sample fetch keyword.
table_clr_gpc1([<table>])
Uses the input sample to perform a look up in the current proxy's stick-table
or in the designated stick-table. Clears the first General Purpose Counter
'1' and returns its previous value. If the entry is not found, an entry is
created and 0 is returned. This is typically used as a second ACL in an
expression in order to mark a connection when a first ACL was verified.
See also the sc_clr_gpc1 sample fetch keyword.
table_conn_cnt([<table>])
Uses the input sample to perform a look up in the current proxy's stick-table
or in the designated stick-table. If the key is not found in the table,
@ -21553,6 +21594,35 @@ table_idle([<table>[,<default_value>]])
table remained idle since the last time it was updated. See also the
table_expire sample fetch keyword.
table_inc_gpc(<idx>[,<table>])
Uses the input sample to perform a look up in the current proxy's stick-table
or in the designated stick-table. Increments the General Purpose Counter at
index <idx> of the array and returns its new value. <idx> is an integer
between 0 and 99. If the entry is not found, an entry is created and 1 is
returned. This converter applies only to the 'gpc' array data_type (and not to
the legacy 'gpc0' nor 'gpc1' data_types). See also sc_inc_gpc.
table_inc_gpc0([<table>])
Uses the input sample to perform a look up in the current proxy's stick-table
or in the designated stick-table. Increments the General Purpose Counter '0'
and returns its new value. If the entry is not found, an entry is created and
1 is returned. See also sc0/sc2/sc2_inc_gpc0. This is typically used as a
second ACL in an expression in order to mark a connection when a first ACL
was verified :
Example:
acl abuse src,table_req_rate gt 10
acl kill src,table_inc_gpc0 gt 0
tcp-request connection reject if abuse kill
table_inc_gpc1([<table>])
Uses the input sample to perform a look up in the current proxy's stick-table
or in the designated stick-table. Increments the General Purpose Counter '1'
and returns its new value. If the entry is not found, an entry is created and
1 is returned. See also sc0/sc2/sc2_inc_gpc1. This is typically used as a
second ACL in an expression in order to mark a connection when a first ACL
was verified.
table_kbytes_in([<table>])
Uses the input sample to perform a look up in the current proxy's stick-table
or in the designated stick-table. If the key is not found in the table,
@ -23655,39 +23725,22 @@ src_bytes_out_rate([<table>]) : integer
Equivalent to: src,table_bytes_out_rate([<table>])
src_clr_gpc(<idx>[,<table>]) : integer
Clears the General Purpose Counter 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>, and returns its
previous value. <idx> is an integer between 0 and 99.
If the address is not found, an entry is created and 0 is returned.
This fetch applies only to the 'gpc' array data_type (and not to the legacy
'gpc0' nor 'gpc1' data_types).
See also sc_clr_gpc.
Same as "table_clr_gpc" converter with key set to the incoming
connection's source address.
Equivalent to: src,table_clr_gpc(<idx>[,<table>])
src_clr_gpc0([<table>]) : integer
Clears the first General Purpose Counter associated to the incoming
connection's source address in the current proxy's stick-table or in the
designated stick-table, and returns its previous value. If the address is not
found, an entry is created and 0 is returned. This is typically used as a
second ACL in an expression in order to mark a connection when a first ACL
was verified :
Same as "table_clr_gpc0" converter with key set to the incoming
connection's source address.
Example:
# block if 5 consecutive requests continue to come faster than 10 sess
# per second, and reset the counter as soon as the traffic slows down.
acl abuse src_http_req_rate gt 10
acl kill src_inc_gpc0 gt 5
acl save src_clr_gpc0 ge 0
tcp-request connection accept if !abuse save
tcp-request connection reject if abuse kill
Equivalent to: src,table_clr_gpc0([<table>])
src_clr_gpc1([<table>]) : integer
Clears the second General Purpose Counter associated to the incoming
connection's source address in the current proxy's stick-table or in the
designated stick-table, and returns its previous value. If the address is not
found, an entry is created and 0 is returned. This is typically used as a
second ACL in an expression in order to mark a connection when a first ACL
was verified.
Same as "table_clr_gpc1" converter with key set to the incoming
connection's source address.
Equivalent to: src,table_clr_gpc1([<table>])
src_conn_cnt([<table>]) : integer
Same as "table_conn_cnt" converter with key set to the incoming
@ -23804,35 +23857,22 @@ src_http_req_rate([<table>]) : integer
Equivalent to: src,table_http_req_rate([<table>])
src_inc_gpc(<idx>[,<table>]) : integer
Increments the General Purpose Counter at 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>, and returns its new
value. <idx> is an integer between 0 and 99.
If the address is not found, an entry is created and 1 is returned.
This fetch applies only to the 'gpc' array data_type (and not to the legacy
'gpc0' nor 'gpc1' data_types).
See also sc_inc_gpc.
Same as "src_inc_gpc" converter with key set to the incoming
connection's source address.
Equivalent to: src,table_inc_gpc(<idx>[,<table>])
src_inc_gpc0([<table>]) : integer
Increments the first General Purpose Counter associated to the incoming
connection's source address in the current proxy's stick-table or in the
designated stick-table, and returns its new value. If the address is not
found, an entry is created and 1 is returned. See also sc0/sc2/sc2_inc_gpc0.
This is typically used as a second ACL in an expression in order to mark a
connection when a first ACL was verified :
Same as "src_inc_gpc0" converter with key set to the incoming
connection's source address.
Example:
acl abuse src_http_req_rate gt 10
acl kill src_inc_gpc0 gt 0
tcp-request connection reject if abuse kill
Equivalent to: src,table_inc_gpc0([<table>])
src_inc_gpc1([<table>]) : integer
Increments the second General Purpose Counter associated to the incoming
connection's source address in the current proxy's stick-table or in the
designated stick-table, and returns its new value. If the address is not
found, an entry is created and 1 is returned. See also sc0/sc2/sc2_inc_gpc1.
This is typically used as a second ACL in an expression in order to mark a
connection when a first ACL was verified.
Same as "src_inc_gpc1" converter with key set to the incoming
connection's source address.
Equivalent to: src,table_inc_gpc1([<table>])
src_is_local : boolean
Returns true if the source address of the incoming connection is local to the

View File

@ -1842,6 +1842,59 @@ static int sample_conv_table_bytes_out_rate(const struct arg *arg_p, struct samp
return smp_fetch_bytes_out_rate(&stkctr, smp, 1);
}
/* Casts sample <smp> to the type of the table specified in arg(1), and looks
* it up into this table. Clears the general purpose counter at GPC[arg_p(0)]
* and return its previous value if the key is present in the table,
* otherwise zero. If the inspected parameter is not stored in the table,
* <not found> is returned.
*/
static int smp_fetch_clr_gpc(struct stkctr *stkctr, struct sample *smp, unsigned int idx, int decrefcnt);
static int sample_conv_table_clr_gpc(const struct arg *arg_p, struct sample *smp, void *private)
{
struct stkctr stkctr;
unsigned int idx;
idx = arg_p[0].data.sint;
stkctr.table = arg_p[1].data.t;
stkctr_set_entry(&stkctr, smp_fetch_stksess(stkctr.table, smp, 1));
return smp_fetch_clr_gpc(&stkctr, smp, idx, 1);
}
/* Casts sample <smp> to the type of the table specified in arg(0), and looks
* it up into this table. Clears the general purpose counter at GPC0
* and return its previous value if the key is present in the table,
* otherwise zero. If the inspected parameter is not stored in the table,
* <not found> is returned.
*/
static int smp_fetch_clr_gpc0(struct stkctr *stkctr, struct sample *smp, int decrefcnt);
static int sample_conv_table_clr_gpc0(const struct arg *arg_p, struct sample *smp, void *private)
{
struct stkctr stkctr;
stkctr.table = arg_p[0].data.t;
stkctr_set_entry(&stkctr, smp_fetch_stksess(stkctr.table, smp, 1));
return smp_fetch_clr_gpc0(&stkctr, smp, 1);
}
/* Casts sample <smp> to the type of the table specified in arg(0), and looks
* it up into this table. Clears the general purpose counter at GPC1
* and return its previous value if the key is present in the table,
* otherwise zero. If the inspected parameter is not stored in the table,
* <not found> is returned.
*/
static int smp_fetch_clr_gpc1(struct stkctr *stkctr, struct sample *smp, int decrefcnt);
static int sample_conv_table_clr_gpc1(const struct arg *arg_p, struct sample *smp, void *private)
{
struct stkctr stkctr;
stkctr.table = arg_p[0].data.t;
stkctr_set_entry(&stkctr, smp_fetch_stksess(stkctr.table, smp, 1));
return smp_fetch_clr_gpc1(&stkctr, smp, 1);
}
/* Casts sample <smp> to the type of the table specified in arg(0), and looks
* it up into this table. Returns the cumulated number of connections for the key
* if the key is present in the table, otherwise zero, so that comparisons can
@ -1959,6 +2012,58 @@ static int sample_conv_table_idle(const struct arg *arg_p, struct sample *smp, v
return 1;
}
/* Casts sample <smp> to the type of the table specified in arg(1), and looks
* it up into this table. Increases the general purpose counter at GPC[arg_p(0)]
* and return its new value if the key is present in the table, otherwise zero.
* If the inspected parameter is not stored in the table, <not found> is returned.
*/
static int smp_fetch_inc_gpc(struct stkctr *stkctr, struct sample *smp, unsigned int idx, int decrefcnt);
static int sample_conv_table_inc_gpc(const struct arg *arg_p, struct sample *smp, void *private)
{
struct stkctr stkctr;
unsigned int idx;
idx = arg_p[0].data.sint;
stkctr.table = arg_p[1].data.t;
stkctr_set_entry(&stkctr, smp_fetch_stksess(stkctr.table, smp, 1));
return smp_fetch_inc_gpc(&stkctr, smp, idx, 1);
}
/* Casts sample <smp> to the type of the table specified in arg(0), and looks
* it up into this table. Increases the general purpose counter at GPC0
* and return its new value if the key is present in the table, otherwise
* zero. If the inspected parameter is not stored in the table, <not found>
* is returned.
*/
static int smp_fetch_inc_gpc0(struct stkctr *stkctr, struct sample *smp, int decrefcnt);
static int sample_conv_table_inc_gpc0(const struct arg *arg_p, struct sample *smp, void *private)
{
struct stkctr stkctr;
stkctr.table = arg_p[0].data.t;
stkctr_set_entry(&stkctr, smp_fetch_stksess(stkctr.table, smp, 1));
return smp_fetch_inc_gpc0(&stkctr, smp, 1);
}
/* Casts sample <smp> to the type of the table specified in arg(0), and looks
* it up into this table. Increases the general purpose counter at GPC1
* and return its new value if the key is present in the table, otherwise
* zero. If the inspected parameter is not stored in the table, <not found>
* is returned.
*/
static int smp_fetch_inc_gpc1(struct stkctr *stkctr, struct sample *smp, int decrefcnt);
static int sample_conv_table_inc_gpc1(const struct arg *arg_p, struct sample *smp, void *private)
{
struct stkctr stkctr;
stkctr.table = arg_p[0].data.t;
stkctr_set_entry(&stkctr, smp_fetch_stksess(stkctr.table, smp, 1));
return smp_fetch_inc_gpc1(&stkctr, smp, 1);
}
/* Casts sample <smp> to the type of the table specified in arg(0), and looks
* it up into this table. Returns the cumulated number of front glitches for the
* key if the key is present in the table, otherwise zero, so that comparisons
@ -5932,6 +6037,9 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, {
{ "in_table", sample_conv_in_table, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_BOOL },
{ "table_bytes_in_rate", sample_conv_table_bytes_in_rate, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_bytes_out_rate", sample_conv_table_bytes_out_rate, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_clr_gpc", sample_conv_table_clr_gpc, ARG2(2,SINT,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_clr_gpc0", sample_conv_table_clr_gpc0, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_clr_gpc1", sample_conv_table_clr_gpc1, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "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 },
@ -5953,6 +6061,9 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, {
{ "table_http_req_cnt", sample_conv_table_http_req_cnt, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_http_req_rate", sample_conv_table_http_req_rate, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_idle", sample_conv_table_idle, ARG2(1,TAB,SINT), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_inc_gpc", sample_conv_table_inc_gpc, ARG2(2,SINT,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_inc_gpc0", sample_conv_table_inc_gpc0, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_inc_gpc1", sample_conv_table_inc_gpc1, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_kbytes_in", sample_conv_table_kbytes_in, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_kbytes_out", sample_conv_table_kbytes_out, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
{ "table_server_id", sample_conv_table_server_id, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },