Hi Mark,

Probably this wasn't needed at the time, but it makes sense to be able
to decrement gpc0 and not just increment it.
Here is a patch adding sc_dec_gpc0 and since gpc0 is a counter it can't
be decremented below zero.
If the patch is useful and clean, we can consider merging it.


Regards,


On 19/08/2017 14:15, Mark Staudinger wrote:
> Hi Folks,
>
> Probably a question for Willy, but perhaps others worked on this code
> so to the mailing list it goes.
>
> I was curious as to why there is no sc_dec_gpc0 implemented in the
> sample fetch / ACL code.
>
> sc_inc_gpc0 does exist of course, and it's well-documented how it can
> be used to mark an event(s) and use the value as a threshold for ACLs.
>
> I had an idea of using that value as a counterbalance of two types of
> traffic so as to use the gpc0 value as the differential between the two.
>
> Request type A -> sc0_inc_gpc0
> Request type B -> sc0_dec_gpc0
>
> after which two requests, the gpc0 value would remain unchanged from
> the original value.
>
> However I quickly determined that there was no sc_dec_gpc0 feature.
>
> Is there some architectural reason why this would be difficult or
> impractical to do?  Or is it just something that didn't seem
> necessary/useful at the time?
>
> Regards,
> Mark Staudinger
>

-- 
Moemen MHEDHBI

From 66707e9fc90fb2726c8e7dd9f060a52325b780bd Mon Sep 17 00:00:00 2001
From: Moemen MHEDHBI <mmhed...@haproxy.com>
Date: Mon, 28 Aug 2017 17:55:38 +0200
Subject: [PATCH] MINOR: add sc-dec-gpc0 to decrement gpc0 counter.

Since GPC0 is a general purpose counter, it should be possible
to decrement it with sc-dec-gpc0 besides incrementing it with
sc-inc-gpc0. Decrementing GPC0 counter won't update gpc0_rate.
---
 doc/configuration.txt |  59 +++++++++++++++++++++----
 src/stick_table.c     | 118 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 166 insertions(+), 11 deletions(-)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 9f7f9ff..aef7c7a 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -3765,6 +3765,7 @@ http-request { allow | auth [realm <realm>] | redirect <rule> |
               unset-var(<var name>) |
               { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>] |
               sc-inc-gpc0(<sc-id>) |
+              sc-dec-gpc0(<sc-id>) |
               sc-set-gpt0(<sc-id>) <int> |
               silent-drop |
              }
@@ -4046,6 +4047,11 @@ http-request { allow | auth [realm <realm>] | redirect <rule> |
       designated by <sc-id>. If an error occurs, this action silently fails and
       the actions evaluation continues.
 
+    - sc-dec-gpc0(<sc-id>):
+      This action decrements the GPC0 counter according with the sticky counter
+      designated by <sc-id>. If an error occurs, this action silently fails and
+      the actions evaluation continues.
+
     - set-var(<var-name>) <expr> :
       Is used to set the contents of a variable. The variable is declared
       inline.
@@ -4238,6 +4244,7 @@ http-response { allow | deny | add-header <name> <fmt> | set-nice <nice> |
                 unset-var(<var-name>) |
                 { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>] |
                 sc-inc-gpc0(<sc-id>) |
+                sc-dec-gpc0(<sc-id>) |
                 sc-set-gpt0(<sc-id>) <int> |
                 silent-drop |
               }
@@ -4474,6 +4481,11 @@ http-response { allow | deny | add-header <name> <fmt> | set-nice <nice> |
       designated by <sc-id>. If an error occurs, this action silently fails and
       the actions evaluation continues.
 
+    - sc-dec-gpc0(<sc-id>):
+      This action decrements the GPC0 counter according with the sticky counter
+      designated by <sc-id>. If an error occurs, this action silently fails and
+      the actions evaluation continues.
+
     - "silent-drop" : this stops the evaluation of the rules and makes the
       client-facing connection suddenly disappear using a system-dependant way
       that tries to prevent the client from being notified. The effect it then
@@ -9069,6 +9081,11 @@ tcp-request connection <action> [{if | unless} <condition>]
         counter designated by <sc-id>. If an error occurs, this action silently
         fails and the actions evaluation continues.
 
+    - sc-dec-gpc0(<sc-id>):
+        The "sc-dec-gpc0" decrements the GPC0 counter according to the sticky
+        counter designated by <sc-id>. If an error occurs, this action silently
+        fails and the actions evaluation continues.
+
     - sc-set-gpt0(<sc-id>) <int>:
         This action sets the GPT0 tag according to the sticky counter designated
         by <sc-id> and the value of <int>. The expected result is a boolean. If
@@ -9228,6 +9245,7 @@ tcp-request content <action> [{if | unless} <condition>]
     - capture : the specified sample expression is captured
     - { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>]
     - sc-inc-gpc0(<sc-id>)
+    - sc-dec-gpc0(<sc-id>)
     - sc-set-gpt0(<sc-id>) <int>
     - set-var(<var-name>) <expr>
     - unset-var(<var-name>)
@@ -9451,6 +9469,11 @@ tcp-response content <action> [{if | unless} <condition>]
         counter designated by <sc-id>. If an error occurs, this action fails
         silently and the actions evaluation continues.
 
+    - sc-dec-gpc0(<sc-id>):
+        This action decrements the GPC0 counter according to the sticky
+        counter designated by <sc-id>. If an error occurs, this action fails
+        silently and the actions evaluation continues.
+
     - sc-set-gpt0(<sc-id>) <int> :
         This action sets the GPT0 tag according to the sticky counter designated
         by <sc-id> and the value of <int>. The expected result is a boolean. If
@@ -9562,6 +9585,7 @@ tcp-request session <action> [{if | unless} <condition>]
     - reject : the request is rejected and the connection is closed
     - { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>]
     - sc-inc-gpc0(<sc-id>)
+    - sc-dec-gpc0(<sc-id>)
     - sc-set-gpt0(<sc-id>) <int>
     - set-var(<var-name>) <expr>
     - unset-var(<var-name>)
@@ -13589,7 +13613,8 @@ sc0_get_gpc0([<table>]) : integer
 sc1_get_gpc0([<table>]) : integer
 sc2_get_gpc0([<table>]) : integer
   Returns the value of the first General Purpose Counter associated to the
-  currently tracked counters. See also src_get_gpc0 and sc/sc0/sc1/sc2_inc_gpc0.
+  currently tracked counters. See also src_get_gpc0, sc/sc0/sc1/sc2_inc_gpc0
+  and sc/sc0/sc1/sc2_dec_gpc0.
 
 sc_get_gpt0(<ctr>[,<table>]) : integer
 sc0_get_gpt0([<table>]) : integer
@@ -13604,10 +13629,11 @@ sc1_gpc0_rate([<table>]) : integer
 sc2_gpc0_rate([<table>]) : integer
   Returns the average increment rate of the first General Purpose Counter
   associated to the currently tracked counters. It reports the frequency
-  which the gpc0 counter was incremented over the configured period. See also
-  src_gpc0_rate, sc/sc0/sc1/sc2_get_gpc0, and sc/sc0/sc1/sc2_inc_gpc0. Note
-  that the "gpc0_rate" counter must be stored in the stick-table for a value to
-  be returned, as "gpc0" only holds the event count.
+  which the gpc0 counter was incremented over the configured period.
+  See also src_gpc0_rate, sc/sc0/sc1/sc2_get_gpc0, sc/sc0/sc1/sc2_inc_gpc0
+  and sc/sc0/sc1/sc2_dec_gpc0. Note that the "gpc0_rate" counter must be
+  stored in the stick-table for a value to be returned, as "gpc0" only
+  holds the event count.
 
 sc_http_err_cnt(<ctr>[,<table>]) : integer
 sc0_http_err_cnt([<table>]) : integer
@@ -13658,6 +13684,15 @@ sc2_inc_gpc0([<table>]) : integer
         acl kill  sc0_inc_gpc0 gt 0
         tcp-request connection reject if abuse kill
 
+sc_dec_gpc0(<ctr>[,<table>]) : integer
+sc0_dec_gpc0([<table>]) : integer
+sc1_dec_gpc0([<table>]) : integer
+sc2_dec_gpc0([<table>]) : integer
+  Decrements the first General Purpose Counter associated to the currently
+  tracked counters, and returns its new value. Before the first invocation,
+  the stored value is zero which is the minimum, so unless the counter was
+  already incremented more than once, the returned value will be 0.
+
 sc_kbytes_in(<ctr>[,<table>]) : integer
 sc0_kbytes_in([<table>]) : integer
 sc1_kbytes_in([<table>]) : integer
@@ -13787,7 +13822,7 @@ src_get_gpc0([<table>]) : integer
   Returns the value of the first General Purpose Counter associated to the
   incoming connection's source address in the current proxy's stick-table or in
   the designated stick-table. If the address is not found, zero is returned.
-  See also sc/sc0/sc1/sc2_get_gpc0 and src_inc_gpc0.
+  See also sc/sc0/sc1/sc2_get_gpc0, src_inc_gpc0 and src_dec_gpc0.
 
 src_get_gpt0([<table>]) : integer
   Returns the value of the first General Purpose Tag associated to the
@@ -13800,9 +13835,9 @@ src_gpc0_rate([<table>]) : integer
   associated to the incoming connection's source address in the current proxy's
   stick-table or in the designated stick-table. It reports the frequency
   which the gpc0 counter was incremented over the configured period. See also
-  sc/sc0/sc1/sc2_gpc0_rate, src_get_gpc0, and sc/sc0/sc1/sc2_inc_gpc0. Note
-  that the "gpc0_rate" counter must be stored in the stick-table for a value to
-  be returned, as "gpc0" only holds the event count.
+  sc/sc0/sc1/sc2_gpc0_rate, src_get_gpc0, sc/sc0/sc1/sc2_inc_gpc0 and
+  sc/sc0/sc1/sc2_dec_gpc0. Note that the "gpc0_rate" counter must be stored in
+  the stick-table for a value to be returned, as "gpc0" only holds the event count.
 
 src_http_err_cnt([<table>]) : integer
   Returns the cumulated number of HTTP errors from the incoming connection's
@@ -13844,6 +13879,12 @@ src_inc_gpc0([<table>]) : integer
         acl kill  src_inc_gpc0 gt 0
         tcp-request connection reject if abuse kill
 
+src_dec_gpc0([<table>]) : integer
+  Decrements the first General Purpose Counter associated to the incoming
+  connection's source address in the current proxy's stick-table or in the
+  designated stick-table, and returns its new value. If the address is not
+  found, an entry is created and 0 is returned. See also sc0/sc2/sc2_dec_gpc0.
+
 src_is_local : boolean
   Returns true if the source address of the incoming connection is local to the
   system, or false if the address doesn't exist on the system, meaning that it
diff --git a/src/stick_table.c b/src/stick_table.c
index a00f1b6..b64eab5 100644
--- a/src/stick_table.c
+++ b/src/stick_table.c
@@ -1439,6 +1439,76 @@ static enum act_parse_ret parse_inc_gpc0(const char **args, int *arg, struct pro
 }
 
 /* Always returns 1. */
+static enum act_return action_dec_gpc0(struct act_rule *rule, struct proxy *px,
+                                       struct session *sess, struct stream *s, int flags)
+{
+	struct stksess *ts;
+	struct stkctr *stkctr;
+
+	/* Extract the stksess, return OK if no stksess available. */
+	if (s)
+		stkctr = &s->stkctr[rule->arg.gpc.sc];
+	else
+		stkctr = &sess->stkctr[rule->arg.gpc.sc];
+
+	ts = stkctr_entry(stkctr);
+	if (ts) {
+		void *ptr1;
+
+		ptr1 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_GPC0);
+		if (ptr1) {
+			if (stktable_data_cast(ptr1, gpc0) > 0)
+				stktable_data_cast(ptr1, gpc0)--;
+			stktable_touch(stkctr->table, ts, 1);
+		}
+	}
+	return ACT_RET_CONT;
+}
+
+/* This function is a common parser for using variables. It understands
+ * the formats:
+ *
+ *   sc-dec-gpc0(<stick-table ID>)
+ *
+ * It returns 0 if fails and <err> is filled with an error message. Otherwise,
+ * it returns 1 and the variable <expr> is filled with the pointer to the
+ * expression to execute.
+ */
+static enum act_parse_ret parse_dec_gpc0(const char **args, int *arg, struct proxy *px,
+                                         struct act_rule *rule, char **err)
+{
+	const char *cmd_name = args[*arg-1];
+	char *error;
+
+	cmd_name += strlen("sc-dec-gpc0");
+	if (*cmd_name == '\0') {
+		/* default stick table id. */
+		rule->arg.gpc.sc = 0;
+	} else {
+		/* parse the stick table id. */
+		if (*cmd_name != '(') {
+			memprintf(err, "invalid stick table track ID. Expects %s(<Track ID>)", args[*arg-1]);
+			return ACT_RET_PRS_ERR;
+		}
+		cmd_name++; /* jump the '(' */
+		rule->arg.gpc.sc = strtol(cmd_name, &error, 10); /* Convert stick table id. */
+		if (*error != ')') {
+			memprintf(err, "invalid stick table track ID. Expects %s(<Track ID>)", args[*arg-1]);
+			return ACT_RET_PRS_ERR;
+		}
+
+		if (rule->arg.gpc.sc >= ACT_ACTION_TRK_SCMAX) {
+			memprintf(err, "invalid stick table track ID. The max allowed ID is %d",
+			          ACT_ACTION_TRK_SCMAX-1);
+			return ACT_RET_PRS_ERR;
+		}
+	}
+	rule->action = ACT_CUSTOM;
+	rule->action_ptr = action_dec_gpc0;
+	return ACT_RET_PRS_OK;
+}
+
+/* Always returns 1. */
 static enum act_return action_set_gpt0(struct act_rule *rule, struct proxy *px,
                                        struct session *sess, struct stream *s, int flags)
 {
@@ -1630,8 +1700,8 @@ smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg
 
 /* 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*.
+ * functions which need to create an entry, such as src_inc_gpc*, 
+ * src_dec_gpc* and src_clr_gpc*.
  */
 struct stkctr *
 smp_create_src_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw)
@@ -1802,6 +1872,39 @@ smp_fetch_sc_inc_gpc0(const struct arg *args, struct sample *smp, const char *kw
 	return 1;
 }
 
+/* Decrement 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]_dec_gpc0" or "src_dec_gpc0" only.
+ */
+static int
+smp_fetch_sc_dec_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;
+
+		ptr1 = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC0);
+		if (ptr1) {
+			if (stktable_data_cast(ptr1, gpc0) > 0)
+				smp->data.u.sint = --stktable_data_cast(ptr1, gpc0);
+			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.
@@ -2780,36 +2883,42 @@ static struct cli_kw_list cli_kws = {{ },{
 
 
 static struct action_kw_list tcp_conn_kws = { { }, {
+	{ "sc-dec-gpc0", parse_dec_gpc0, 1 },
 	{ "sc-inc-gpc0", parse_inc_gpc0, 1 },
 	{ "sc-set-gpt0", parse_set_gpt0, 1 },
 	{ /* END */ }
 }};
 
 static struct action_kw_list tcp_sess_kws = { { }, {
+	{ "sc-dec-gpc0", parse_dec_gpc0, 1 },
 	{ "sc-inc-gpc0", parse_inc_gpc0, 1 },
 	{ "sc-set-gpt0", parse_set_gpt0, 1 },
 	{ /* END */ }
 }};
 
 static struct action_kw_list tcp_req_kws = { { }, {
+	{ "sc-dec-gpc0", parse_dec_gpc0, 1 },
 	{ "sc-inc-gpc0", parse_inc_gpc0, 1 },
 	{ "sc-set-gpt0", parse_set_gpt0, 1 },
 	{ /* END */ }
 }};
 
 static struct action_kw_list tcp_res_kws = { { }, {
+	{ "sc-dec-gpc0", parse_dec_gpc0, 1 },
 	{ "sc-inc-gpc0", parse_inc_gpc0, 1 },
 	{ "sc-set-gpt0", parse_set_gpt0, 1 },
 	{ /* END */ }
 }};
 
 static struct action_kw_list http_req_kws = { { }, {
+	{ "sc-dec-gpc0", parse_dec_gpc0, 1 },
 	{ "sc-inc-gpc0", parse_inc_gpc0, 1 },
 	{ "sc-set-gpt0", parse_set_gpt0, 1 },
 	{ /* END */ }
 }};
 
 static struct action_kw_list http_res_kws = { { }, {
+	{ "sc-dec-gpc0", parse_dec_gpc0, 1 },
 	{ "sc-inc-gpc0", parse_inc_gpc0, 1 },
 	{ "sc-set-gpt0", parse_set_gpt0, 1 },
 	{ /* END */ }
@@ -2840,6 +2949,7 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
 	{ "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_dec_gpc0",        smp_fetch_sc_dec_gpc0,       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, },
@@ -2860,6 +2970,7 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
 	{ "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_dec_gpc0",       smp_fetch_sc_dec_gpc0,       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, },
@@ -2880,6 +2991,7 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
 	{ "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_dec_gpc0",       smp_fetch_sc_dec_gpc0,       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, },
@@ -2900,6 +3012,7 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
 	{ "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_dec_gpc0",       smp_fetch_sc_dec_gpc0,       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, },
@@ -2920,6 +3033,7 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
 	{ "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_dec_gpc0",       smp_fetch_sc_dec_gpc0,       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, },
-- 
2.1.4

  • sc_dec_gpc0? Mark Staudinger
    • Re:[PATCH] sc_dec_gpc0? Moemen MHEDHBI

Reply via email to