diff --git a/include/common/defaults.h b/include/common/defaults.h index 6e5840ee0..cc1fbbd87 100644 --- a/include/common/defaults.h +++ b/include/common/defaults.h @@ -83,6 +83,11 @@ #define MAX_SESS_STKCTR 3 #endif +// max # of extra stick-table data types that can be registred at runtime +#ifndef STKTABLE_EXTRA_DATA_TYPES +#define STKTABLE_EXTRA_DATA_TYPES 0 +#endif + // max # of loops we can perform around a read() which succeeds. // It's very frequent that the system returns a few TCP segments at a time. #ifndef MAX_READ_POLL_LOOPS diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h index a121ad5dc..a5e7520bf 100644 --- a/include/proto/stick_table.h +++ b/include/proto/stick_table.h @@ -51,6 +51,7 @@ struct stktable_key *stktable_fetch_key(struct stktable *t, struct proxy *px, struct session *l4, void *l7, unsigned int opt, struct sample_expr *expr, struct sample *smp); int stktable_compatible_sample(struct sample_expr *expr, unsigned long table_type); +int stktable_register_data_store(int idx, const char *name, int std_type, int arg_type); int stktable_get_data_type(char *name); struct proxy *find_stktable(const char *name); int stktable_trash_oldest(struct stktable *t, int to_batch); diff --git a/include/types/stick_table.h b/include/types/stick_table.h index e28492cd5..6fdc58e65 100644 --- a/include/types/stick_table.h +++ b/include/types/stick_table.h @@ -60,7 +60,11 @@ enum { STKTABLE_DT_BYTES_IN_RATE,/* bytes rate from client to servers */ STKTABLE_DT_BYTES_OUT_CNT,/* cumulated bytes count from servers to client */ STKTABLE_DT_BYTES_OUT_RATE,/* bytes rate from servers to client */ - STKTABLE_DATA_TYPES /* Number of data types, must always be last */ + STKTABLE_STATIC_DATA_TYPES,/* number of types above */ + /* up to STKTABLE_EXTRA_DATA_TYPES types may be registered here, always + * followed by the number of data types, must always be last. + */ + STKTABLE_DATA_TYPES = STKTABLE_STATIC_DATA_TYPES + STKTABLE_EXTRA_DATA_TYPES }; /* The equivalent standard types of the stored data */ diff --git a/src/stick_table.c b/src/stick_table.c index a2a86885c..a6ee77fd4 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -688,7 +688,10 @@ int stktable_compatible_sample(struct sample_expr *expr, unsigned long table_typ return 1; } -/* Extra data types processing */ +/* Extra data types processing : after the last one, some room may remain + * before STKTABLE_DATA_TYPES that may be used to register extra data types + * at run time. + */ struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES] = { [STKTABLE_DT_SERVER_ID] = { .name = "server_id", .std_type = STD_T_SINT }, [STKTABLE_DT_GPC0] = { .name = "gpc0", .std_type = STD_T_UINT }, @@ -708,6 +711,36 @@ struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES] = { [STKTABLE_DT_BYTES_OUT_RATE]= { .name = "bytes_out_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY }, }; +/* Registers stick-table extra data type with index , name , type + * and arg type . If the index is negative, the next free + * index is automatically allocated. The allocated index is returned, or -1 if + * no free index was found or was already registered. The is used + * directly as a pointer, so if it's not stable, the caller must allocate it. + */ +int stktable_register_data_store(int idx, const char *name, int std_type, int arg_type) +{ + if (idx < 0) { + for (idx = 0; idx < STKTABLE_DATA_TYPES; idx++) { + if (!stktable_data_types[idx].name) + break; + + if (strcmp(stktable_data_types[idx].name, name) == 0) + return -1; + } + } + + if (idx >= STKTABLE_DATA_TYPES) + return -1; + + if (stktable_data_types[idx].name != NULL) + return -1; + + stktable_data_types[idx].name = name; + stktable_data_types[idx].std_type = std_type; + stktable_data_types[idx].arg_type = arg_type; + return idx; +} + /* * Returns the data type number for the stktable_data_type whose name is , * or <0 if not found. @@ -717,6 +750,8 @@ int stktable_get_data_type(char *name) int type; for (type = 0; type < STKTABLE_DATA_TYPES; type++) { + if (!stktable_data_types[type].name) + continue; if (strcmp(name, stktable_data_types[type].name) == 0) return type; }