]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: stick-table: make it easier to register extra data types
authorWilly Tarreau <w@1wt.eu>
Tue, 15 Jul 2014 14:44:27 +0000 (16:44 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 15 Jul 2014 17:14:52 +0000 (19:14 +0200)
Some users want to add their own data types to stick tables. We don't
want to use a linked list here for performance reasons, so we need to
continue to use an indexed array. This patch allows one to reserve a
compile-time-defined number of extra data types by setting the new
macro STKTABLE_EXTRA_DATA_TYPES to anything greater than zero, keeping
in mind that anything larger will slightly inflate the memory consumed
by stick tables (not per entry though).

Then calling stktable_register_data_store() with the new keyword will
either register a new keyword or fail if the desired entry was already
taken or the keyword already registered.

Note that this patch does not dictate how the data will be used, it only
offers the possibility to create new keywords and have an index to
reference them in the config and in the tables. The caller will not be
able to use stktable_data_cast() and will have to explicitly cast the
stable pointers to the expected types. It can be used for experimentation
as well.

include/common/defaults.h
include/proto/stick_table.h
include/types/stick_table.h
src/stick_table.c

index 6e5840ee0f24edc8eace5378ac77320dbafee9a7..cc1fbbd87cf9038ca7557e5d3b1ca36baca5b1ea 100644 (file)
 #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
index a121ad5dc6b46678cecec3035c2b518eab3e74d8..a5e7520bfa26ee64bd42907055ae3b769c63149e 100644 (file)
@@ -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);
index e28492cd5120493122954a4949d57ccf97e35e04..6fdc58e65342cde0882c6806c6196cd2bcef9ca0 100644 (file)
@@ -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 */
index a2a86885c8dd6ff2c3c3f9a46a3faef03ba4cd72..a6ee77fd4b54bbca119b23cff174f56533511712 100644 (file)
@@ -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 <idx>, name <name>, type
+ * <std_type> and arg type <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 <name> was already registered. The <name> 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 <name>,
  * 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;
        }