]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG: stkctr: move all the stick counters processing to stick-tables.c
authorWilly Tarreau <w@1wt.eu>
Fri, 25 Nov 2016 15:10:05 +0000 (16:10 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 25 Nov 2016 15:10:05 +0000 (16:10 +0100)
Historically we used to have the stick counters processing put into
session.c which became stream.c. But a big part of it is now in
stick-table.c (eg: converters) but despite this we still have all
the sample fetch functions in stream.c

These parts do not depend on the stream anymore, so let's move the
remaining chunks to stick-table.c and have cleaner files.

What remains in stream.c is everything needed to attach/detach
trackers to the stream and to update the counters while the stream
is being processed.

include/proto/stick_table.h
include/proto/stream.h
src/stick_table.c
src/stream.c

index 941e2ff72d1c129911e91481b6dc20e864c96718..a5fd4000c541150752d1170e4c14b9468624709b 100644 (file)
@@ -54,6 +54,8 @@ struct stktable_key *smp_to_stkey(struct sample *smp, struct stktable *t);
 struct stktable_key *stktable_fetch_key(struct stktable *t, struct proxy *px, struct session *sess,
                                         struct stream *strm, unsigned int opt,
                                         struct sample_expr *expr, struct sample *smp);
+struct stkctr *smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw);
+struct stkctr *smp_create_src_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw);
 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);
index 02ac0f8fc1076d7ed69ae0f7769c96e1faca067b..db239566a914ef18834e90c6dc65cb9c9119b182 100644 (file)
@@ -48,8 +48,6 @@ void stream_process_counters(struct stream *s);
 void sess_change_server(struct stream *sess, struct server *newsrv);
 struct task *process_stream(struct task *t);
 void default_srv_error(struct stream *s, struct stream_interface *si);
-struct stkctr *smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw);
-struct stkctr *smp_create_src_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw);
 int parse_track_counters(char **args, int *arg,
                         int section_type, struct proxy *curpx,
                         struct track_ctr_prm *prm,
index 383ec00e29cc7cd8526cf0cb9dd7025be9af9671..909b8c55a8e22db0362def0de11f837bbcee3e13 100644 (file)
@@ -30,6 +30,7 @@
 #include <proto/arg.h>
 #include <proto/cli.h>
 #include <proto/proto_http.h>
+#include <proto/proto_tcp.h>
 #include <proto/proxy.h>
 #include <proto/sample.h>
 #include <proto/stream.h>
@@ -1520,6 +1521,710 @@ static enum act_parse_ret parse_set_gpt0(const char **args, int *arg, struct pro
        return ACT_RET_PRS_OK;
 }
 
+/* set temp integer to the number of used entries in the table pointed to by expr.
+ * Accepts exactly 1 argument of type table.
+ */
+static int
+smp_fetch_table_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = args->data.prx->table.current;
+       return 1;
+}
+
+/* set temp integer to the number of free entries in the table pointed to by expr.
+ * Accepts exactly 1 argument of type table.
+ */
+static int
+smp_fetch_table_avl(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct proxy *px;
+
+       px = args->data.prx;
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = px->table.size - px->table.current;
+       return 1;
+}
+
+/* Returns a pointer to a stkctr depending on the fetch keyword name.
+ * It is designed to be called as sc[0-9]_* sc_* or src_* exclusively.
+ * sc[0-9]_* will return a pointer to the respective field in the
+ * stream <l4>. sc_* requires an UINT argument specifying the stick
+ * counter number. src_* will fill a locally allocated structure with
+ * the table and entry corresponding to what is specified with src_*.
+ * NULL may be returned if the designated stkctr is not tracked. For
+ * the sc_* and sc[0-9]_* forms, an optional table argument may be
+ * passed. When present, the currently tracked key is then looked up
+ * in the specified table instead of the current table. The purpose is
+ * to be able to convery multiple values per key (eg: have gpc0 from
+ * multiple tables). <strm> is allowed to be NULL, in which case only
+ * the session will be consulted.
+ */
+struct stkctr *
+smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw)
+{
+       static struct stkctr stkctr;
+       struct stkctr *stkptr;
+       struct stksess *stksess;
+       unsigned int num = kw[2] - '0';
+       int arg = 0;
+
+       if (num == '_' - '0') {
+               /* sc_* variant, args[0] = ctr# (mandatory) */
+               num = args[arg++].data.sint;
+               if (num >= MAX_SESS_STKCTR)
+                       return NULL;
+       }
+       else if (num > 9) { /* src_* variant, args[0] = table */
+               struct stktable_key *key;
+               struct connection *conn = objt_conn(sess->origin);
+               struct sample smp;
+
+               if (!conn)
+                       return NULL;
+
+               /* Fetch source adress in a sample. */
+               smp.px = NULL;
+               smp.sess = sess;
+               smp.strm = strm;
+               if (!smp_fetch_src(NULL, &smp, NULL, NULL))
+                       return NULL;
+
+               /* Converts into key. */
+               key = smp_to_stkey(&smp, &args->data.prx->table);
+               if (!key)
+                       return NULL;
+
+               stkctr.table = &args->data.prx->table;
+               stkctr_set_entry(&stkctr, stktable_lookup_key(stkctr.table, key));
+               return &stkctr;
+       }
+
+       /* Here, <num> contains the counter number from 0 to 9 for
+        * the sc[0-9]_ form, or even higher using sc_(num) if needed.
+        * args[arg] is the first optional argument. We first lookup the
+        * ctr form the stream, then from the session if it was not there.
+        */
+
+       if (strm)
+               stkptr = &strm->stkctr[num];
+       if (!strm || !stkctr_entry(stkptr)) {
+               stkptr = &sess->stkctr[num];
+               if (!stkctr_entry(stkptr))
+                       return NULL;
+       }
+
+       stksess = stkctr_entry(stkptr);
+       if (!stksess)
+               return NULL;
+
+       if (unlikely(args[arg].type == ARGT_TAB)) {
+               /* an alternate table was specified, let's look up the same key there */
+               stkctr.table = &args[arg].data.prx->table;
+               stkctr_set_entry(&stkctr, stktable_lookup(stkctr.table, stksess));
+               return &stkctr;
+       }
+       return stkptr;
+}
+
+/* same as smp_fetch_sc_stkctr() but dedicated to src_* and can create
+ * the entry if it doesn't exist yet. This is needed for a few fetch
+ * functions which need to create an entry, such as src_inc_gpc* and
+ * src_clr_gpc*.
+ */
+struct stkctr *
+smp_create_src_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw)
+{
+       static struct stkctr stkctr;
+       struct stktable_key *key;
+       struct connection *conn = objt_conn(sess->origin);
+       struct sample smp;
+
+       if (strncmp(kw, "src_", 4) != 0)
+               return NULL;
+
+       if (!conn)
+               return NULL;
+
+       /* Fetch source adress in a sample. */
+       smp.px = NULL;
+       smp.sess = sess;
+       smp.strm = strm;
+       if (!smp_fetch_src(NULL, &smp, NULL, NULL))
+               return NULL;
+
+       /* Converts into key. */
+       key = smp_to_stkey(&smp, &args->data.prx->table);
+       if (!key)
+               return NULL;
+
+       stkctr.table = &args->data.prx->table;
+       stkctr_set_entry(&stkctr, stktable_update_key(stkctr.table, key));
+       return &stkctr;
+}
+
+/* set return a boolean indicating if the requested stream counter is
+ * currently being tracked or not.
+ * Supports being called as "sc[0-9]_tracked" only.
+ */
+static int
+smp_fetch_sc_tracked(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_BOOL;
+       smp->data.u.sint = !!smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       return 1;
+}
+
+/* set <smp> to the General Purpose Flag 0 value from the stream's tracked
+ * frontend counters or from the src.
+ * Supports being called as "sc[0-9]_get_gpc0" or "src_get_gpt0" only. Value
+ * zero is returned if the key is new.
+ */
+static int
+smp_fetch_sc_get_gpt0(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPT0);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = stktable_data_cast(ptr, gpt0);
+       }
+       return 1;
+}
+
+/* set <smp> to the General Purpose Counter 0 value from the stream's tracked
+ * frontend counters or from the src.
+ * Supports being called as "sc[0-9]_get_gpc0" or "src_get_gpc0" only. Value
+ * zero is returned if the key is new.
+ */
+static int
+smp_fetch_sc_get_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = stktable_data_cast(ptr, gpc0);
+       }
+       return 1;
+}
+
+/* set <smp> to the General Purpose Counter 0's event rate from the stream's
+ * tracked frontend counters or from the src.
+ * Supports being called as "sc[0-9]_gpc0_rate" or "src_gpc0_rate" only.
+ * Value zero is returned if the key is new.
+ */
+static int
+smp_fetch_sc_gpc0_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0_RATE);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc0_rate),
+                                 stkctr->table->data_arg[STKTABLE_DT_GPC0_RATE].u);
+       }
+       return 1;
+}
+
+/* Increment the General Purpose Counter 0 value from the stream's tracked
+ * frontend counters and return it into temp integer.
+ * Supports being called as "sc[0-9]_inc_gpc0" or "src_inc_gpc0" only.
+ */
+static int
+smp_fetch_sc_inc_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+
+       if (stkctr_entry(stkctr) == NULL)
+               stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw);
+
+       if (stkctr && stkctr_entry(stkctr)) {
+               void *ptr1,*ptr2;
+
+               /* First, update gpc0_rate if it's tracked. Second, update its
+                * gpc0 if tracked. Returns gpc0's value otherwise the curr_ctr.
+                */
+               ptr1 = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0_RATE);
+               if (ptr1) {
+                       update_freq_ctr_period(&stktable_data_cast(ptr1, gpc0_rate),
+                                              stkctr->table->data_arg[STKTABLE_DT_GPC0_RATE].u, 1);
+                       smp->data.u.sint = (&stktable_data_cast(ptr1, gpc0_rate))->curr_ctr;
+               }
+
+               ptr2 = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0);
+               if (ptr2)
+                       smp->data.u.sint = ++stktable_data_cast(ptr2, gpc0);
+
+               /* If data was modified, we need to touch to re-schedule sync */
+               if (ptr1 || ptr2)
+                       stktable_touch(stkctr->table, stkctr_entry(stkctr), 1);
+       }
+       return 1;
+}
+
+/* Clear the General Purpose Counter 0 value from the stream's tracked
+ * frontend counters and return its previous value into temp integer.
+ * Supports being called as "sc[0-9]_clr_gpc0" or "src_clr_gpc0" only.
+ */
+static int
+smp_fetch_sc_clr_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+
+       if (stkctr_entry(stkctr) == NULL)
+               stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw);
+
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = stktable_data_cast(ptr, gpc0);
+               stktable_data_cast(ptr, gpc0) = 0;
+               /* If data was modified, we need to touch to re-schedule sync */
+               stktable_touch(stkctr->table, stkctr_entry(stkctr), 1);
+       }
+       return 1;
+}
+
+/* set <smp> to the cumulated number of connections from the stream's tracked
+ * frontend counters. Supports being called as "sc[0-9]_conn_cnt" or
+ * "src_conn_cnt" only.
+ */
+static int
+smp_fetch_sc_conn_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CNT);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = stktable_data_cast(ptr, conn_cnt);
+       }
+       return 1;
+}
+
+/* set <smp> to the connection rate from the stream's tracked frontend
+ * counters. Supports being called as "sc[0-9]_conn_rate" or "src_conn_rate"
+ * only.
+ */
+static int
+smp_fetch_sc_conn_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_RATE);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, conn_rate),
+                                              stkctr->table->data_arg[STKTABLE_DT_CONN_RATE].u);
+       }
+       return 1;
+}
+
+/* set temp integer to the number of connections from the stream's source address
+ * in the table pointed to by expr, after updating it.
+ * Accepts exactly 1 argument of type table.
+ */
+static int
+smp_fetch_src_updt_conn_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct connection *conn = objt_conn(smp->sess->origin);
+       struct stksess *ts;
+       struct stktable_key *key;
+       void *ptr;
+       struct proxy *px;
+
+       if (!conn)
+               return 0;
+
+       /* Fetch source adress in a sample. */
+       if (!smp_fetch_src(NULL, smp, NULL, NULL))
+               return 0;
+
+       /* Converts into key. */
+       key = smp_to_stkey(smp, &args->data.prx->table);
+       if (!key)
+               return 0;
+
+       px = args->data.prx;
+
+       if ((ts = stktable_update_key(&px->table, key)) == NULL)
+               /* entry does not exist and could not be created */
+               return 0;
+
+       ptr = stktable_data_ptr(&px->table, ts, STKTABLE_DT_CONN_CNT);
+       if (!ptr)
+               return 0; /* parameter not stored in this table */
+
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = ++stktable_data_cast(ptr, conn_cnt);
+       /* Touch was previously performed by stktable_update_key */
+       smp->flags = SMP_F_VOL_TEST;
+       return 1;
+}
+
+/* set <smp> to the number of concurrent connections from the stream's tracked
+ * frontend counters. Supports being called as "sc[0-9]_conn_cur" or
+ * "src_conn_cur" only.
+ */
+static int
+smp_fetch_sc_conn_cur(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CUR);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = stktable_data_cast(ptr, conn_cur);
+       }
+       return 1;
+}
+
+/* set <smp> to the cumulated number of streams from the stream's tracked
+ * frontend counters. Supports being called as "sc[0-9]_sess_cnt" or
+ * "src_sess_cnt" only.
+ */
+static int
+smp_fetch_sc_sess_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_CNT);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = stktable_data_cast(ptr, sess_cnt);
+       }
+       return 1;
+}
+
+/* set <smp> to the stream rate from the stream's tracked frontend counters.
+ * Supports being called as "sc[0-9]_sess_rate" or "src_sess_rate" only.
+ */
+static int
+smp_fetch_sc_sess_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_RATE);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, sess_rate),
+                                              stkctr->table->data_arg[STKTABLE_DT_SESS_RATE].u);
+       }
+       return 1;
+}
+
+/* set <smp> to the cumulated number of HTTP requests from the stream's tracked
+ * frontend counters. Supports being called as "sc[0-9]_http_req_cnt" or
+ * "src_http_req_cnt" only.
+ */
+static int
+smp_fetch_sc_http_req_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_CNT);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = stktable_data_cast(ptr, http_req_cnt);
+       }
+       return 1;
+}
+
+/* set <smp> to the HTTP request rate from the stream's tracked frontend
+ * counters. Supports being called as "sc[0-9]_http_req_rate" or
+ * "src_http_req_rate" only.
+ */
+static int
+smp_fetch_sc_http_req_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_RATE);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate),
+                                              stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u);
+       }
+       return 1;
+}
+
+/* set <smp> to the cumulated number of HTTP requests errors from the stream's
+ * tracked frontend counters. Supports being called as "sc[0-9]_http_err_cnt" or
+ * "src_http_err_cnt" only.
+ */
+static int
+smp_fetch_sc_http_err_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_CNT);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = stktable_data_cast(ptr, http_err_cnt);
+       }
+       return 1;
+}
+
+/* set <smp> to the HTTP request error rate from the stream's tracked frontend
+ * counters. Supports being called as "sc[0-9]_http_err_rate" or
+ * "src_http_err_rate" only.
+ */
+static int
+smp_fetch_sc_http_err_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_RATE);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate),
+                                              stkctr->table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u);
+       }
+       return 1;
+}
+
+/* set <smp> to the number of kbytes received from clients, as found in the
+ * stream's tracked frontend counters. Supports being called as
+ * "sc[0-9]_kbytes_in" or "src_kbytes_in" only.
+ */
+static int
+smp_fetch_sc_kbytes_in(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_CNT);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = stktable_data_cast(ptr, bytes_in_cnt) >> 10;
+       }
+       return 1;
+}
+
+/* set <smp> to the data rate received from clients in bytes/s, as found
+ * in the stream's tracked frontend counters. Supports being called as
+ * "sc[0-9]_bytes_in_rate" or "src_bytes_in_rate" only.
+ */
+static int
+smp_fetch_sc_bytes_in_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_RATE);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate),
+                                              stkctr->table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u);
+       }
+       return 1;
+}
+
+/* set <smp> to the number of kbytes sent to clients, as found in the
+ * stream's tracked frontend counters. Supports being called as
+ * "sc[0-9]_kbytes_out" or "src_kbytes_out" only.
+ */
+static int
+smp_fetch_sc_kbytes_out(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_CNT);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = stktable_data_cast(ptr, bytes_out_cnt) >> 10;
+       }
+       return 1;
+}
+
+/* set <smp> to the data rate sent to clients in bytes/s, as found in the
+ * stream's tracked frontend counters. Supports being called as
+ * "sc[0-9]_bytes_out_rate" or "src_bytes_out_rate" only.
+ */
+static int
+smp_fetch_sc_bytes_out_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+       if (stkctr_entry(stkctr) != NULL) {
+               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_RATE);
+               if (!ptr)
+                       return 0; /* parameter not stored */
+               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate),
+                                              stkctr->table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u);
+       }
+       return 1;
+}
+
+/* set <smp> to the number of active trackers on the SC entry in the stream's
+ * tracked frontend counters. Supports being called as "sc[0-9]_trackers" only.
+ */
+static int
+smp_fetch_sc_trackers(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+       if (!stkctr)
+               return 0;
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = stkctr_entry(stkctr) ? stkctr_entry(stkctr)->ref_cnt : 0;
+       return 1;
+}
+
 
 /* The functions below are used to manipulate table contents from the CLI.
  * There are 3 main actions, "clear", "set" and "show". The code is shared
@@ -2117,6 +2822,123 @@ static struct action_kw_list http_res_kws = { { }, {
        { /* END */ }
 }};
 
+///* Note: must not be declared <const> as its list will be overwritten.
+// * Please take care of keeping this list alphabetically sorted.
+// */
+//static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
+//     { "table_avl",          smp_fetch_table_avl,         ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+//     { "table_cnt",          smp_fetch_table_cnt,         ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+//     { /* END */ },
+//}};
+/* Note: must not be declared <const> as its list will be overwritten.
+ * Please take care of keeping this list alphabetically sorted.
+ */
+static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
+       { "sc_bytes_in_rate",   smp_fetch_sc_bytes_in_rate,  ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_bytes_out_rate",  smp_fetch_sc_bytes_out_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_clr_gpc0",        smp_fetch_sc_clr_gpc0,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_conn_cnt",        smp_fetch_sc_conn_cnt,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_conn_cur",        smp_fetch_sc_conn_cur,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_conn_rate",       smp_fetch_sc_conn_rate,      ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_get_gpt0",        smp_fetch_sc_get_gpt0,       ARG2(1,SINT,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, },
+       { "sc_get_gpc0",        smp_fetch_sc_get_gpc0,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_gpc0_rate",       smp_fetch_sc_gpc0_rate,      ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_http_err_cnt",    smp_fetch_sc_http_err_cnt,   ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_http_err_rate",   smp_fetch_sc_http_err_rate,  ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_http_req_cnt",    smp_fetch_sc_http_req_cnt,   ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_http_req_rate",   smp_fetch_sc_http_req_rate,  ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_inc_gpc0",        smp_fetch_sc_inc_gpc0,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_kbytes_in",       smp_fetch_sc_kbytes_in,      ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "sc_kbytes_out",      smp_fetch_sc_kbytes_out,     ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "sc_sess_cnt",        smp_fetch_sc_sess_cnt,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_sess_rate",       smp_fetch_sc_sess_rate,      ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_tracked",         smp_fetch_sc_tracked,        ARG2(1,SINT,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, },
+       { "sc_trackers",        smp_fetch_sc_trackers,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_bytes_in_rate",  smp_fetch_sc_bytes_in_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_clr_gpc0",       smp_fetch_sc_clr_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_conn_cnt",       smp_fetch_sc_conn_cnt,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_conn_cur",       smp_fetch_sc_conn_cur,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_conn_rate",      smp_fetch_sc_conn_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_get_gpt0",       smp_fetch_sc_get_gpt0,       ARG1(0,TAB),      NULL, SMP_T_BOOL, SMP_USE_INTRN, },
+       { "sc0_get_gpc0",       smp_fetch_sc_get_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_gpc0_rate",      smp_fetch_sc_gpc0_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_http_err_cnt",   smp_fetch_sc_http_err_cnt,   ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_http_err_rate",  smp_fetch_sc_http_err_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_http_req_cnt",   smp_fetch_sc_http_req_cnt,   ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_http_req_rate",  smp_fetch_sc_http_req_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_inc_gpc0",       smp_fetch_sc_inc_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_kbytes_in",      smp_fetch_sc_kbytes_in,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "sc0_kbytes_out",     smp_fetch_sc_kbytes_out,     ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "sc0_sess_cnt",       smp_fetch_sc_sess_cnt,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_sess_rate",      smp_fetch_sc_sess_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_tracked",        smp_fetch_sc_tracked,        ARG1(0,TAB),      NULL, SMP_T_BOOL, SMP_USE_INTRN, },
+       { "sc0_trackers",       smp_fetch_sc_trackers,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_bytes_in_rate",  smp_fetch_sc_bytes_in_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_clr_gpc0",       smp_fetch_sc_clr_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_conn_cnt",       smp_fetch_sc_conn_cnt,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_conn_cur",       smp_fetch_sc_conn_cur,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_conn_rate",      smp_fetch_sc_conn_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_get_gpt0",       smp_fetch_sc_get_gpt0,       ARG1(0,TAB),      NULL, SMP_T_BOOL, SMP_USE_INTRN, },
+       { "sc1_get_gpc0",       smp_fetch_sc_get_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_gpc0_rate",      smp_fetch_sc_gpc0_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_http_err_cnt",   smp_fetch_sc_http_err_cnt,   ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_http_err_rate",  smp_fetch_sc_http_err_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_http_req_cnt",   smp_fetch_sc_http_req_cnt,   ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_http_req_rate",  smp_fetch_sc_http_req_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_inc_gpc0",       smp_fetch_sc_inc_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_kbytes_in",      smp_fetch_sc_kbytes_in,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "sc1_kbytes_out",     smp_fetch_sc_kbytes_out,     ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "sc1_sess_cnt",       smp_fetch_sc_sess_cnt,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_sess_rate",      smp_fetch_sc_sess_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_tracked",        smp_fetch_sc_tracked,        ARG1(0,TAB),      NULL, SMP_T_BOOL, SMP_USE_INTRN, },
+       { "sc1_trackers",       smp_fetch_sc_trackers,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_bytes_in_rate",  smp_fetch_sc_bytes_in_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_clr_gpc0",       smp_fetch_sc_clr_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_conn_cnt",       smp_fetch_sc_conn_cnt,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_conn_cur",       smp_fetch_sc_conn_cur,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_conn_rate",      smp_fetch_sc_conn_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_get_gpt0",       smp_fetch_sc_get_gpt0,       ARG1(0,TAB),      NULL, SMP_T_BOOL, SMP_USE_INTRN, },
+       { "sc2_get_gpc0",       smp_fetch_sc_get_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_gpc0_rate",      smp_fetch_sc_gpc0_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_http_err_cnt",   smp_fetch_sc_http_err_cnt,   ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_http_err_rate",  smp_fetch_sc_http_err_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_http_req_cnt",   smp_fetch_sc_http_req_cnt,   ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_http_req_rate",  smp_fetch_sc_http_req_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_inc_gpc0",       smp_fetch_sc_inc_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_kbytes_in",      smp_fetch_sc_kbytes_in,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "sc2_kbytes_out",     smp_fetch_sc_kbytes_out,     ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "sc2_sess_cnt",       smp_fetch_sc_sess_cnt,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_sess_rate",      smp_fetch_sc_sess_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_tracked",        smp_fetch_sc_tracked,        ARG1(0,TAB),      NULL, SMP_T_BOOL, SMP_USE_INTRN, },
+       { "sc2_trackers",       smp_fetch_sc_trackers,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "src_bytes_in_rate",  smp_fetch_sc_bytes_in_rate,  ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_clr_gpc0",       smp_fetch_sc_clr_gpc0,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_conn_cnt",       smp_fetch_sc_conn_cnt,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_conn_cur",       smp_fetch_sc_conn_cur,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_conn_rate",      smp_fetch_sc_conn_rate,      ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_get_gpt0",       smp_fetch_sc_get_gpt0,       ARG1(1,TAB),      NULL, SMP_T_BOOL, SMP_USE_L4CLI, },
+       { "src_get_gpc0",       smp_fetch_sc_get_gpc0,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_gpc0_rate",      smp_fetch_sc_gpc0_rate,      ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_http_err_cnt",   smp_fetch_sc_http_err_cnt,   ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_http_err_rate",  smp_fetch_sc_http_err_rate,  ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_http_req_cnt",   smp_fetch_sc_http_req_cnt,   ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_http_req_rate",  smp_fetch_sc_http_req_rate,  ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_inc_gpc0",       smp_fetch_sc_inc_gpc0,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_kbytes_in",      smp_fetch_sc_kbytes_in,      ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_kbytes_out",     smp_fetch_sc_kbytes_out,     ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_sess_cnt",       smp_fetch_sc_sess_cnt,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_sess_rate",      smp_fetch_sc_sess_rate,      ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_updt_conn_cnt",  smp_fetch_src_updt_conn_cnt, ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "table_avl",          smp_fetch_table_avl,         ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "table_cnt",          smp_fetch_table_cnt,         ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { /* END */ },
+}};
+
+
 /* Note: must not be declared <const> as its list will be overwritten */
 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  },
@@ -2153,6 +2975,7 @@ static void __stick_table_init(void)
        http_res_keywords_register(&http_res_kws);
 
        /* register sample fetch and format conversion keywords */
+       sample_register_fetches(&smp_fetch_keywords);
        sample_register_convs(&sample_conv_kws);
        cli_register_kw(&cli_kws);
 }
index 0f8483416fe66c209277251aacffa7bb7493a49a..b333dec628c8dcae822bb5964410babd06f57f4e 100644 (file)
@@ -49,7 +49,6 @@
 #include <proto/stream.h>
 #include <proto/pipe.h>
 #include <proto/proto_http.h>
-#include <proto/proto_tcp.h>
 #include <proto/proxy.h>
 #include <proto/queue.h>
 #include <proto/server.h>
@@ -2611,710 +2610,6 @@ void stream_shutdown(struct stream *stream, int why)
 /*           All supported ACL keywords must be declared here.          */
 /************************************************************************/
 
-/* Returns a pointer to a stkctr depending on the fetch keyword name.
- * It is designed to be called as sc[0-9]_* sc_* or src_* exclusively.
- * sc[0-9]_* will return a pointer to the respective field in the
- * stream <l4>. sc_* requires an UINT argument specifying the stick
- * counter number. src_* will fill a locally allocated structure with
- * the table and entry corresponding to what is specified with src_*.
- * NULL may be returned if the designated stkctr is not tracked. For
- * the sc_* and sc[0-9]_* forms, an optional table argument may be
- * passed. When present, the currently tracked key is then looked up
- * in the specified table instead of the current table. The purpose is
- * to be able to convery multiple values per key (eg: have gpc0 from
- * multiple tables). <strm> is allowed to be NULL, in which case only
- * the session will be consulted.
- */
-struct stkctr *
-smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw)
-{
-       static struct stkctr stkctr;
-       struct stkctr *stkptr;
-       struct stksess *stksess;
-       unsigned int num = kw[2] - '0';
-       int arg = 0;
-
-       if (num == '_' - '0') {
-               /* sc_* variant, args[0] = ctr# (mandatory) */
-               num = args[arg++].data.sint;
-               if (num >= MAX_SESS_STKCTR)
-                       return NULL;
-       }
-       else if (num > 9) { /* src_* variant, args[0] = table */
-               struct stktable_key *key;
-               struct connection *conn = objt_conn(sess->origin);
-               struct sample smp;
-
-               if (!conn)
-                       return NULL;
-
-               /* Fetch source adress in a sample. */
-               smp.px = NULL;
-               smp.sess = sess;
-               smp.strm = strm;
-               if (!smp_fetch_src(NULL, &smp, NULL, NULL))
-                       return NULL;
-
-               /* Converts into key. */
-               key = smp_to_stkey(&smp, &args->data.prx->table);
-               if (!key)
-                       return NULL;
-
-               stkctr.table = &args->data.prx->table;
-               stkctr_set_entry(&stkctr, stktable_lookup_key(stkctr.table, key));
-               return &stkctr;
-       }
-
-       /* Here, <num> contains the counter number from 0 to 9 for
-        * the sc[0-9]_ form, or even higher using sc_(num) if needed.
-        * args[arg] is the first optional argument. We first lookup the
-        * ctr form the stream, then from the session if it was not there.
-        */
-
-       if (strm)
-               stkptr = &strm->stkctr[num];
-       if (!strm || !stkctr_entry(stkptr)) {
-               stkptr = &sess->stkctr[num];
-               if (!stkctr_entry(stkptr))
-                       return NULL;
-       }
-
-       stksess = stkctr_entry(stkptr);
-       if (!stksess)
-               return NULL;
-
-       if (unlikely(args[arg].type == ARGT_TAB)) {
-               /* an alternate table was specified, let's look up the same key there */
-               stkctr.table = &args[arg].data.prx->table;
-               stkctr_set_entry(&stkctr, stktable_lookup(stkctr.table, stksess));
-               return &stkctr;
-       }
-       return stkptr;
-}
-
-/* same as smp_fetch_sc_stkctr() but dedicated to src_* and can create
- * the entry if it doesn't exist yet. This is needed for a few fetch
- * functions which need to create an entry, such as src_inc_gpc* and
- * src_clr_gpc*.
- */
-struct stkctr *
-smp_create_src_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw)
-{
-       static struct stkctr stkctr;
-       struct stktable_key *key;
-       struct connection *conn = objt_conn(sess->origin);
-       struct sample smp;
-
-       if (strncmp(kw, "src_", 4) != 0)
-               return NULL;
-
-       if (!conn)
-               return NULL;
-
-       /* Fetch source adress in a sample. */
-       smp.px = NULL;
-       smp.sess = sess;
-       smp.strm = strm;
-       if (!smp_fetch_src(NULL, &smp, NULL, NULL))
-               return NULL;
-
-       /* Converts into key. */
-       key = smp_to_stkey(&smp, &args->data.prx->table);
-       if (!key)
-               return NULL;
-
-       stkctr.table = &args->data.prx->table;
-       stkctr_set_entry(&stkctr, stktable_update_key(stkctr.table, key));
-       return &stkctr;
-}
-
-/* set return a boolean indicating if the requested stream counter is
- * currently being tracked or not.
- * Supports being called as "sc[0-9]_tracked" only.
- */
-static int
-smp_fetch_sc_tracked(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_BOOL;
-       smp->data.u.sint = !!smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       return 1;
-}
-
-/* set <smp> to the General Purpose Flag 0 value from the stream's tracked
- * frontend counters or from the src.
- * Supports being called as "sc[0-9]_get_gpc0" or "src_get_gpt0" only. Value
- * zero is returned if the key is new.
- */
-static int
-smp_fetch_sc_get_gpt0(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPT0);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = stktable_data_cast(ptr, gpt0);
-       }
-       return 1;
-}
-
-/* set <smp> to the General Purpose Counter 0 value from the stream's tracked
- * frontend counters or from the src.
- * Supports being called as "sc[0-9]_get_gpc0" or "src_get_gpc0" only. Value
- * zero is returned if the key is new.
- */
-static int
-smp_fetch_sc_get_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = stktable_data_cast(ptr, gpc0);
-       }
-       return 1;
-}
-
-/* set <smp> to the General Purpose Counter 0's event rate from the stream's
- * tracked frontend counters or from the src.
- * Supports being called as "sc[0-9]_gpc0_rate" or "src_gpc0_rate" only.
- * Value zero is returned if the key is new.
- */
-static int
-smp_fetch_sc_gpc0_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0_RATE);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc0_rate),
-                                 stkctr->table->data_arg[STKTABLE_DT_GPC0_RATE].u);
-       }
-       return 1;
-}
-
-/* Increment the General Purpose Counter 0 value from the stream's tracked
- * frontend counters and return it into temp integer.
- * Supports being called as "sc[0-9]_inc_gpc0" or "src_inc_gpc0" only.
- */
-static int
-smp_fetch_sc_inc_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-
-       if (stkctr_entry(stkctr) == NULL)
-               stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw);
-
-       if (stkctr && stkctr_entry(stkctr)) {
-               void *ptr1,*ptr2;
-
-               /* First, update gpc0_rate if it's tracked. Second, update its
-                * gpc0 if tracked. Returns gpc0's value otherwise the curr_ctr.
-                */
-               ptr1 = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0_RATE);
-               if (ptr1) {
-                       update_freq_ctr_period(&stktable_data_cast(ptr1, gpc0_rate),
-                                              stkctr->table->data_arg[STKTABLE_DT_GPC0_RATE].u, 1);
-                       smp->data.u.sint = (&stktable_data_cast(ptr1, gpc0_rate))->curr_ctr;
-               }
-
-               ptr2 = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0);
-               if (ptr2)
-                       smp->data.u.sint = ++stktable_data_cast(ptr2, gpc0);
-
-               /* If data was modified, we need to touch to re-schedule sync */
-               if (ptr1 || ptr2)
-                       stktable_touch(stkctr->table, stkctr_entry(stkctr), 1);
-       }
-       return 1;
-}
-
-/* Clear the General Purpose Counter 0 value from the stream's tracked
- * frontend counters and return its previous value into temp integer.
- * Supports being called as "sc[0-9]_clr_gpc0" or "src_clr_gpc0" only.
- */
-static int
-smp_fetch_sc_clr_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-
-       if (stkctr_entry(stkctr) == NULL)
-               stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw);
-
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = stktable_data_cast(ptr, gpc0);
-               stktable_data_cast(ptr, gpc0) = 0;
-               /* If data was modified, we need to touch to re-schedule sync */
-               stktable_touch(stkctr->table, stkctr_entry(stkctr), 1);
-       }
-       return 1;
-}
-
-/* set <smp> to the cumulated number of connections from the stream's tracked
- * frontend counters. Supports being called as "sc[0-9]_conn_cnt" or
- * "src_conn_cnt" only.
- */
-static int
-smp_fetch_sc_conn_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CNT);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = stktable_data_cast(ptr, conn_cnt);
-       }
-       return 1;
-}
-
-/* set <smp> to the connection rate from the stream's tracked frontend
- * counters. Supports being called as "sc[0-9]_conn_rate" or "src_conn_rate"
- * only.
- */
-static int
-smp_fetch_sc_conn_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_RATE);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, conn_rate),
-                                              stkctr->table->data_arg[STKTABLE_DT_CONN_RATE].u);
-       }
-       return 1;
-}
-
-/* set temp integer to the number of connections from the stream's source address
- * in the table pointed to by expr, after updating it.
- * Accepts exactly 1 argument of type table.
- */
-static int
-smp_fetch_src_updt_conn_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct connection *conn = objt_conn(smp->sess->origin);
-       struct stksess *ts;
-       struct stktable_key *key;
-       void *ptr;
-       struct proxy *px;
-
-       if (!conn)
-               return 0;
-
-       /* Fetch source adress in a sample. */
-       if (!smp_fetch_src(NULL, smp, NULL, NULL))
-               return 0;
-
-       /* Converts into key. */
-       key = smp_to_stkey(smp, &args->data.prx->table);
-       if (!key)
-               return 0;
-
-       px = args->data.prx;
-
-       if ((ts = stktable_update_key(&px->table, key)) == NULL)
-               /* entry does not exist and could not be created */
-               return 0;
-
-       ptr = stktable_data_ptr(&px->table, ts, STKTABLE_DT_CONN_CNT);
-       if (!ptr)
-               return 0; /* parameter not stored in this table */
-
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = ++stktable_data_cast(ptr, conn_cnt);
-       /* Touch was previously performed by stktable_update_key */
-       smp->flags = SMP_F_VOL_TEST;
-       return 1;
-}
-
-/* set <smp> to the number of concurrent connections from the stream's tracked
- * frontend counters. Supports being called as "sc[0-9]_conn_cur" or
- * "src_conn_cur" only.
- */
-static int
-smp_fetch_sc_conn_cur(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_CONN_CUR);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = stktable_data_cast(ptr, conn_cur);
-       }
-       return 1;
-}
-
-/* set <smp> to the cumulated number of streams from the stream's tracked
- * frontend counters. Supports being called as "sc[0-9]_sess_cnt" or
- * "src_sess_cnt" only.
- */
-static int
-smp_fetch_sc_sess_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_CNT);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = stktable_data_cast(ptr, sess_cnt);
-       }
-       return 1;
-}
-
-/* set <smp> to the stream rate from the stream's tracked frontend counters.
- * Supports being called as "sc[0-9]_sess_rate" or "src_sess_rate" only.
- */
-static int
-smp_fetch_sc_sess_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_RATE);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, sess_rate),
-                                              stkctr->table->data_arg[STKTABLE_DT_SESS_RATE].u);
-       }
-       return 1;
-}
-
-/* set <smp> to the cumulated number of HTTP requests from the stream's tracked
- * frontend counters. Supports being called as "sc[0-9]_http_req_cnt" or
- * "src_http_req_cnt" only.
- */
-static int
-smp_fetch_sc_http_req_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_CNT);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = stktable_data_cast(ptr, http_req_cnt);
-       }
-       return 1;
-}
-
-/* set <smp> to the HTTP request rate from the stream's tracked frontend
- * counters. Supports being called as "sc[0-9]_http_req_rate" or
- * "src_http_req_rate" only.
- */
-static int
-smp_fetch_sc_http_req_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_RATE);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate),
-                                              stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u);
-       }
-       return 1;
-}
-
-/* set <smp> to the cumulated number of HTTP requests errors from the stream's
- * tracked frontend counters. Supports being called as "sc[0-9]_http_err_cnt" or
- * "src_http_err_cnt" only.
- */
-static int
-smp_fetch_sc_http_err_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_CNT);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = stktable_data_cast(ptr, http_err_cnt);
-       }
-       return 1;
-}
-
-/* set <smp> to the HTTP request error rate from the stream's tracked frontend
- * counters. Supports being called as "sc[0-9]_http_err_rate" or
- * "src_http_err_rate" only.
- */
-static int
-smp_fetch_sc_http_err_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_RATE);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate),
-                                              stkctr->table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u);
-       }
-       return 1;
-}
-
-/* set <smp> to the number of kbytes received from clients, as found in the
- * stream's tracked frontend counters. Supports being called as
- * "sc[0-9]_kbytes_in" or "src_kbytes_in" only.
- */
-static int
-smp_fetch_sc_kbytes_in(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_CNT);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = stktable_data_cast(ptr, bytes_in_cnt) >> 10;
-       }
-       return 1;
-}
-
-/* set <smp> to the data rate received from clients in bytes/s, as found
- * in the stream's tracked frontend counters. Supports being called as
- * "sc[0-9]_bytes_in_rate" or "src_bytes_in_rate" only.
- */
-static int
-smp_fetch_sc_bytes_in_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_RATE);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate),
-                                              stkctr->table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u);
-       }
-       return 1;
-}
-
-/* set <smp> to the number of kbytes sent to clients, as found in the
- * stream's tracked frontend counters. Supports being called as
- * "sc[0-9]_kbytes_out" or "src_kbytes_out" only.
- */
-static int
-smp_fetch_sc_kbytes_out(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_CNT);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = stktable_data_cast(ptr, bytes_out_cnt) >> 10;
-       }
-       return 1;
-}
-
-/* set <smp> to the data rate sent to clients in bytes/s, as found in the
- * stream's tracked frontend counters. Supports being called as
- * "sc[0-9]_bytes_out_rate" or "src_bytes_out_rate" only.
- */
-static int
-smp_fetch_sc_bytes_out_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = 0;
-       if (stkctr_entry(stkctr) != NULL) {
-               void *ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_RATE);
-               if (!ptr)
-                       return 0; /* parameter not stored */
-               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate),
-                                              stkctr->table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u);
-       }
-       return 1;
-}
-
-/* set <smp> to the number of active trackers on the SC entry in the stream's
- * tracked frontend counters. Supports being called as "sc[0-9]_trackers" only.
- */
-static int
-smp_fetch_sc_trackers(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct stkctr *stkctr;
-
-       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
-       if (!stkctr)
-               return 0;
-
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = stkctr_entry(stkctr) ? stkctr_entry(stkctr)->ref_cnt : 0;
-       return 1;
-}
-
-/* set temp integer to the number of used entries in the table pointed to by expr.
- * Accepts exactly 1 argument of type table.
- */
-static int
-smp_fetch_table_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = args->data.prx->table.current;
-       return 1;
-}
-
-/* set temp integer to the number of free entries in the table pointed to by expr.
- * Accepts exactly 1 argument of type table.
- */
-static int
-smp_fetch_table_avl(const struct arg *args, struct sample *smp, const char *kw, void *private)
-{
-       struct proxy *px;
-
-       px = args->data.prx;
-       smp->flags = SMP_F_VOL_TEST;
-       smp->data.type = SMP_T_SINT;
-       smp->data.u.sint = px->table.size - px->table.current;
-       return 1;
-}
-
 /* 0=OK, <0=Alert, >0=Warning */
 static enum act_parse_ret stream_parse_use_service(const char **args, int *cur_arg,
                                                    struct proxy *px, struct act_rule *rule,
@@ -3986,126 +3281,9 @@ static struct action_kw_list stream_http_keywords = { ILH, {
        { /* END */ }
 }};
 
-/* Note: must not be declared <const> as its list will be overwritten.
- * Please take care of keeping this list alphabetically sorted.
- */
-static struct acl_kw_list acl_kws = {ILH, {
-       { /* END */ },
-}};
-
-/* Note: must not be declared <const> as its list will be overwritten.
- * Please take care of keeping this list alphabetically sorted.
- */
-static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
-       { "sc_bytes_in_rate",   smp_fetch_sc_bytes_in_rate,  ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_bytes_out_rate",  smp_fetch_sc_bytes_out_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_clr_gpc0",        smp_fetch_sc_clr_gpc0,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_conn_cnt",        smp_fetch_sc_conn_cnt,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_conn_cur",        smp_fetch_sc_conn_cur,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_conn_rate",       smp_fetch_sc_conn_rate,      ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_get_gpt0",        smp_fetch_sc_get_gpt0,       ARG2(1,SINT,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, },
-       { "sc_get_gpc0",        smp_fetch_sc_get_gpc0,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_gpc0_rate",       smp_fetch_sc_gpc0_rate,      ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_http_err_cnt",    smp_fetch_sc_http_err_cnt,   ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_http_err_rate",   smp_fetch_sc_http_err_rate,  ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_http_req_cnt",    smp_fetch_sc_http_req_cnt,   ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_http_req_rate",   smp_fetch_sc_http_req_rate,  ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_inc_gpc0",        smp_fetch_sc_inc_gpc0,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_kbytes_in",       smp_fetch_sc_kbytes_in,      ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "sc_kbytes_out",      smp_fetch_sc_kbytes_out,     ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "sc_sess_cnt",        smp_fetch_sc_sess_cnt,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_sess_rate",       smp_fetch_sc_sess_rate,      ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc_tracked",         smp_fetch_sc_tracked,        ARG2(1,SINT,TAB), NULL, SMP_T_BOOL, SMP_USE_INTRN, },
-       { "sc_trackers",        smp_fetch_sc_trackers,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_bytes_in_rate",  smp_fetch_sc_bytes_in_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_clr_gpc0",       smp_fetch_sc_clr_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_conn_cnt",       smp_fetch_sc_conn_cnt,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_conn_cur",       smp_fetch_sc_conn_cur,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_conn_rate",      smp_fetch_sc_conn_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_get_gpt0",       smp_fetch_sc_get_gpt0,       ARG1(0,TAB),      NULL, SMP_T_BOOL, SMP_USE_INTRN, },
-       { "sc0_get_gpc0",       smp_fetch_sc_get_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_gpc0_rate",      smp_fetch_sc_gpc0_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_http_err_cnt",   smp_fetch_sc_http_err_cnt,   ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_http_err_rate",  smp_fetch_sc_http_err_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_http_req_cnt",   smp_fetch_sc_http_req_cnt,   ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_http_req_rate",  smp_fetch_sc_http_req_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_inc_gpc0",       smp_fetch_sc_inc_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_kbytes_in",      smp_fetch_sc_kbytes_in,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "sc0_kbytes_out",     smp_fetch_sc_kbytes_out,     ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "sc0_sess_cnt",       smp_fetch_sc_sess_cnt,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_sess_rate",      smp_fetch_sc_sess_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc0_tracked",        smp_fetch_sc_tracked,        ARG1(0,TAB),      NULL, SMP_T_BOOL, SMP_USE_INTRN, },
-       { "sc0_trackers",       smp_fetch_sc_trackers,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_bytes_in_rate",  smp_fetch_sc_bytes_in_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_clr_gpc0",       smp_fetch_sc_clr_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_conn_cnt",       smp_fetch_sc_conn_cnt,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_conn_cur",       smp_fetch_sc_conn_cur,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_conn_rate",      smp_fetch_sc_conn_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_get_gpt0",       smp_fetch_sc_get_gpt0,       ARG1(0,TAB),      NULL, SMP_T_BOOL, SMP_USE_INTRN, },
-       { "sc1_get_gpc0",       smp_fetch_sc_get_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_gpc0_rate",      smp_fetch_sc_gpc0_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_http_err_cnt",   smp_fetch_sc_http_err_cnt,   ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_http_err_rate",  smp_fetch_sc_http_err_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_http_req_cnt",   smp_fetch_sc_http_req_cnt,   ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_http_req_rate",  smp_fetch_sc_http_req_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_inc_gpc0",       smp_fetch_sc_inc_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_kbytes_in",      smp_fetch_sc_kbytes_in,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "sc1_kbytes_out",     smp_fetch_sc_kbytes_out,     ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "sc1_sess_cnt",       smp_fetch_sc_sess_cnt,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_sess_rate",      smp_fetch_sc_sess_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc1_tracked",        smp_fetch_sc_tracked,        ARG1(0,TAB),      NULL, SMP_T_BOOL, SMP_USE_INTRN, },
-       { "sc1_trackers",       smp_fetch_sc_trackers,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_bytes_in_rate",  smp_fetch_sc_bytes_in_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_clr_gpc0",       smp_fetch_sc_clr_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_conn_cnt",       smp_fetch_sc_conn_cnt,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_conn_cur",       smp_fetch_sc_conn_cur,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_conn_rate",      smp_fetch_sc_conn_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_get_gpt0",       smp_fetch_sc_get_gpt0,       ARG1(0,TAB),      NULL, SMP_T_BOOL, SMP_USE_INTRN, },
-       { "sc2_get_gpc0",       smp_fetch_sc_get_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_gpc0_rate",      smp_fetch_sc_gpc0_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_http_err_cnt",   smp_fetch_sc_http_err_cnt,   ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_http_err_rate",  smp_fetch_sc_http_err_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_http_req_cnt",   smp_fetch_sc_http_req_cnt,   ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_http_req_rate",  smp_fetch_sc_http_req_rate,  ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_inc_gpc0",       smp_fetch_sc_inc_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_kbytes_in",      smp_fetch_sc_kbytes_in,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "sc2_kbytes_out",     smp_fetch_sc_kbytes_out,     ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "sc2_sess_cnt",       smp_fetch_sc_sess_cnt,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_sess_rate",      smp_fetch_sc_sess_rate,      ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "sc2_tracked",        smp_fetch_sc_tracked,        ARG1(0,TAB),      NULL, SMP_T_BOOL, SMP_USE_INTRN, },
-       { "sc2_trackers",       smp_fetch_sc_trackers,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "src_bytes_in_rate",  smp_fetch_sc_bytes_in_rate,  ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_bytes_out_rate", smp_fetch_sc_bytes_out_rate, ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_clr_gpc0",       smp_fetch_sc_clr_gpc0,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_conn_cnt",       smp_fetch_sc_conn_cnt,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_conn_cur",       smp_fetch_sc_conn_cur,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_conn_rate",      smp_fetch_sc_conn_rate,      ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_get_gpt0",       smp_fetch_sc_get_gpt0,       ARG1(1,TAB),      NULL, SMP_T_BOOL, SMP_USE_L4CLI, },
-       { "src_get_gpc0",       smp_fetch_sc_get_gpc0,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_gpc0_rate",      smp_fetch_sc_gpc0_rate,      ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_http_err_cnt",   smp_fetch_sc_http_err_cnt,   ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_http_err_rate",  smp_fetch_sc_http_err_rate,  ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_http_req_cnt",   smp_fetch_sc_http_req_cnt,   ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_http_req_rate",  smp_fetch_sc_http_req_rate,  ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_inc_gpc0",       smp_fetch_sc_inc_gpc0,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_kbytes_in",      smp_fetch_sc_kbytes_in,      ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_kbytes_out",     smp_fetch_sc_kbytes_out,     ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_sess_cnt",       smp_fetch_sc_sess_cnt,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_sess_rate",      smp_fetch_sc_sess_rate,      ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "src_updt_conn_cnt",  smp_fetch_src_updt_conn_cnt, ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
-       { "table_avl",          smp_fetch_table_avl,         ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { "table_cnt",          smp_fetch_table_cnt,         ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
-       { /* END */ },
-}};
-
 __attribute__((constructor))
 static void __stream_init(void)
 {
-       sample_register_fetches(&smp_fetch_keywords);
-       acl_register_keywords(&acl_kws);
        tcp_req_cont_keywords_register(&stream_tcp_keywords);
        http_req_keywords_register(&stream_http_keywords);
        cli_register_kw(&cli_kws);