diff --git a/doc/management.txt b/doc/management.txt
index f085ad50a..aa542769c 100644
--- a/doc/management.txt
+++ b/doc/management.txt
@@ -1869,6 +1869,9 @@ clear table
[ data. ] | [ key ] |
the entry cannot be matched using the key due to empty key or incompatible
characters on the cli.
+ If data. is an array type, "[]" may be used to access a specific
+ index in the array, like so: data.gpt[1]
+
Example :
$ echo "show table http_proxy" | socat stdio /tmp/sock1
>>> # table: http_proxy, type: ip, size:204800, used:2
@@ -2625,6 +2628,9 @@ set table ptr [data. ]*
pointer may be relevant if the entry cannot be matched using the key due to
empty key or incompatible characters on the cli.
+ If data. is an array type, "[]" may be used to access a specific
+ index in the array, like so: data.gpt[1]
+
set timeout cli
Change the CLI interface timeout for current connection. This can be useful
during long debugging sessions where the user needs to constantly inspect
@@ -3862,6 +3868,9 @@ show table [ data. [data. ...]] |
the entry cannot be matched using the key due empty key or incompatible
characters on the cli.
+ If data. is an array type, "[]" may be used to access a specific
+ index in the array, like so: data.gpt[1]
+
Example :
$ echo "show table http_proxy" | socat stdio /tmp/sock1
>>> # table: http_proxy, type: ip, size:204800, used:2
diff --git a/src/stick_table.c b/src/stick_table.c
index 775cd1e18..114fa4634 100644
--- a/src/stick_table.c
+++ b/src/stick_table.c
@@ -5281,6 +5281,7 @@ struct show_table_ctx {
long long value[STKTABLE_FILTER_LEN]; /* value to compare against */
signed char data_type[STKTABLE_FILTER_LEN]; /* type of data to compare, or -1 if none */
signed char data_op[STKTABLE_FILTER_LEN]; /* operator (STD_OP_*) when data_type set */
+ unsigned int data_idx[STKTABLE_FILTER_LEN]; /* index of data to consider for array types */
enum {
STATE_NEXT = 0, /* px points to next table, entry=NULL */
STATE_DUMP, /* px points to curr table, entry is valid, refcount held */
@@ -5355,6 +5356,8 @@ static int table_process_entry(struct appctx *appctx, struct stksess *ts, char *
case STK_CLI_ACT_SET:
HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
for (cur_arg = 5; *args[cur_arg]; cur_arg += 2) {
+ unsigned int idx;
+
if (strncmp(args[cur_arg], "data.", 5) != 0) {
cli_err(appctx, "\"data.\" followed by a value expected\n");
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
@@ -5362,7 +5365,7 @@ static int table_process_entry(struct appctx *appctx, struct stksess *ts, char *
return 1;
}
- data_type = stktable_get_data_type(args[cur_arg] + 5);
+ data_type = stktable_get_data_type_idx(args[cur_arg] + 5, &idx);
if (data_type < 0) {
cli_err(appctx, "Unknown data type\n");
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
@@ -5384,7 +5387,17 @@ static int table_process_entry(struct appctx *appctx, struct stksess *ts, char *
return 1;
}
- ptr = __stktable_data_ptr(t, ts, data_type);
+ if (stktable_data_types[data_type].is_array) {
+ ptr = stktable_data_ptr_idx(t, ts, data_type, idx);
+ if (!ptr) {
+ cli_err(appctx, "index out of range in this data array\n");
+ HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
+ stktable_touch_local(t, ts, 1);
+ return 1;
+ }
+ }
+ else
+ ptr = __stktable_data_ptr(t, ts, data_type);
switch (stktable_data_types[data_type].std_type) {
case STD_T_SINT:
@@ -5515,7 +5528,7 @@ static int table_prepare_data_request(struct appctx *appctx, char **args)
if (i > 0 && !*args[3+3*i]) // number of filter entries can be less than STKTABLE_FILTER_LEN
break;
/* condition on stored data value */
- ctx->data_type[i] = stktable_get_data_type(args[3+3*i] + 5);
+ ctx->data_type[i] = stktable_get_data_type_idx(args[3+3*i] + 5, &ctx->data_idx[i]);
if (ctx->data_type[i] < 0)
return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Unknown data type\n", i + 1));
@@ -5670,13 +5683,25 @@ static int cli_io_handler_table(struct appctx *appctx)
if (ctx->data_type[i] == -1)
break;
dt = ctx->data_type[i];
- ptr = stktable_data_ptr(ctx->t,
- ctx->entry,
- dt);
- /* table_prepare_data_request() normally ensures the
- * type is both valid and stored
- */
- BUG_ON(!ptr);
+ if (stktable_data_types[dt].is_array) {
+ ptr = stktable_data_ptr_idx(ctx->t,
+ ctx->entry,
+ dt, ctx->data_idx[i]);
+ if (!ptr) {
+ /* index out of range */
+ skip_entry = 1;
+ break;
+ }
+ }
+ else {
+ ptr = stktable_data_ptr(ctx->t,
+ ctx->entry,
+ dt);
+ /* table_prepare_data_request() normally ensures the
+ * type is both valid and stored
+ */
+ BUG_ON(!ptr);
+ }
data = 0;
switch (stktable_data_types[dt].std_type) {