From 9b2717e7bb754c75816fb9272f3a2bcd6ea258cf Mon Sep 17 00:00:00 2001 From: Aurelien DARRAGON Date: Mon, 18 Dec 2023 15:37:25 +0100 Subject: [PATCH] MINOR: stktable: use {show,set,clear} table with ptr This patchs adds support for optional ptr (0xffff form) instead of key argument to match against existing sticktable entries, ie: if the key is empty or cannot be matched on the cli due to incompatible characters. Lookup is performed using a linear search so it will be slower than key search which relies on eb tree lookup. Example: set table mytable key mykey data.gpc0 1 show table mytable > 0x7fbd00032bd8: key=mykey use=0 exp=86373242 shard=0 gpc0=1 clear table mytable ptr 0x7fbd00032bd8 This patchs depends on: - "MINOR: stktable: add table_process_entry helper function" It should solve GH #2118 --- src/stick_table.c | 68 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/src/stick_table.c b/src/stick_table.c index 0994bd31c7..6b461c00ff 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -385,6 +385,40 @@ struct stksess *stktable_lookup_key(struct stktable *t, struct stktable_key *key return ts; } +/* + * Looks in table for a sticky session matching ptr . + * Returns pointer on requested sticky session or NULL if none was found. + * The refcount of the found entry is increased and this function + * is protected using the table lock + */ +struct stksess *stktable_lookup_ptr(struct stktable *t, void *ptr) +{ + struct stksess *ts = NULL; + struct ebmb_node *eb; + + HA_RWLOCK_RDLOCK(STK_TABLE_LOCK, &t->lock); + /* linear search is performed, this could be optimized by adding + * an eb node dedicated to ptr lookups into stksess struct to + * leverage eb_lookup function instead. + */ + eb = ebmb_first(&t->keys); + while (eb) { + struct stksess *cur; + + cur = ebmb_entry(eb, struct stksess, key); + if (cur == ptr) { + ts = cur; + break; + } + eb = ebmb_next(eb); + } + if (ts) + HA_ATOMIC_INC(&ts->ref_cnt); + HA_RWLOCK_RDUNLOCK(STK_TABLE_LOCK, &t->lock); + + return ts; +} + /* * Looks in table for a sticky session with same key as . * Returns pointer on requested sticky session or NULL if none was found. @@ -5080,6 +5114,32 @@ static int table_process_entry_per_key(struct appctx *appctx, char **args) return table_process_entry(appctx, ts, args); } +/* Processes a single table entry matching a specific ptr passed in argument. + * returns 0 if wants to be called again, 1 if has ended processing. + */ +static int table_process_entry_per_ptr(struct appctx *appctx, char **args) +{ + struct show_table_ctx *ctx = appctx->svcctx; + struct stktable *t = ctx->target; + long long int ptr; + char *error; + struct stksess *ts; + + if (!*args[4] || args[4][0] != '0' || args[4][1] != 'x') + return cli_err(appctx, "Pointer expected (0xffff notation)\n"); + + /* Convert argument to integer value */ + ptr = strtoll(args[4], &error, 16); + if (*error != '\0') + return cli_err(appctx, "Malformed ptr.\n"); + + ts = stktable_lookup_ptr(t, (void *)ptr); + if (!ts) + return cli_err(appctx, "No entry can be found matching ptr.\n"); + + return table_process_entry(appctx, ts, args); +} + /* Prepares the appctx fields with the data-based filters from the command line. * Returns 0 if the dump can proceed, 1 if has ended processing. */ @@ -5145,6 +5205,8 @@ static int cli_parse_table_req(char **args, char *payload, struct appctx *appctx if (strcmp(args[3], "key") == 0) return table_process_entry_per_key(appctx, args); + if (strcmp(args[3], "ptr") == 0) + return table_process_entry_per_ptr(appctx, args); else if (strncmp(args[3], "data.", 5) == 0) return table_prepare_data_request(appctx, args); else if (*args[3]) @@ -5155,11 +5217,11 @@ static int cli_parse_table_req(char **args, char *payload, struct appctx *appctx err_args: switch (ctx->action) { case STK_CLI_ACT_SHOW: - return cli_err(appctx, "Optional argument only supports \"data.\" and key \n"); + return cli_err(appctx, "Optional argument only supports \"data.\" or key or ptr \n"); case STK_CLI_ACT_CLR: - return cli_err(appctx, "Required arguments: \"data.\" or
key \n"); + return cli_err(appctx, "Required arguments:
\"data.\" or
key or
ptr \n"); case STK_CLI_ACT_SET: - return cli_err(appctx, "Required arguments:
key [data. ]*\n"); + return cli_err(appctx, "Required arguments:
key [data. ]* or
ptr [data. ]*\n"); default: return cli_err(appctx, "Unknown action\n"); } -- 2.39.5