From: Aurelien DARRAGON Date: Wed, 15 Jan 2025 20:14:21 +0000 (+0100) Subject: MINOR: stktable: add table_{inc,clr}_gpc* converters X-Git-Tag: v3.2-dev4~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0486b9e4918d271ae2ec52d7deb82d415cf7a34c;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 89f156a91..50b8456fe 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -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, 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([,
]) + 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 of the gpc array and returns its previous value. 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([
]) + 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([
]) + 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([
]) 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 remained idle since the last time it was updated. See also the table_expire sample fetch keyword. +table_inc_gpc([,
]) + 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 of the array and returns its new value. 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([
]) + 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([
]) + 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([
]) 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([
]) : integer Equivalent to: src,table_bytes_out_rate([
]) src_clr_gpc([,
]) : integer - Clears the General Purpose Counter at the index of the array - 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. 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([,
]) src_clr_gpc0([
]) : 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([
]) src_clr_gpc1([
]) : 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([
]) src_conn_cnt([
]) : integer Same as "table_conn_cnt" converter with key set to the incoming @@ -23804,35 +23857,22 @@ src_http_req_rate([
]) : integer Equivalent to: src,table_http_req_rate([
]) src_inc_gpc([,
]) : integer - Increments the General Purpose Counter at index of the array - 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. 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([,
]) src_inc_gpc0([
]) : 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([
]) src_inc_gpc1([
]) : 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([
]) src_is_local : boolean Returns true if the source address of the incoming connection is local to the diff --git a/src/stick_table.c b/src/stick_table.c index dd23b52d6..d143c5e87 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -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 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, + * 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 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, + * 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 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, + * 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 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 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, 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 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, + * 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 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, + * 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 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 },