]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stick-tables: Adds support for new "gpc1" and "gpc1_rate" counters.
authorFrédéric Lécaille <flecaille@haproxy.com>
Mon, 29 Jan 2018 14:22:53 +0000 (15:22 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 31 Jan 2018 08:40:05 +0000 (09:40 +0100)
Implement exactly the same code as this has been done for "gpc0" and "gpc0_rate"
counters.

doc/configuration.txt
doc/peers-v2.0.txt
include/types/stick_table.h
src/stick_table.c

index 1ce423babf16d2154c369ee96aaf50974bcdca3f..3665fe0f7185e3b38428e7ffb80dc6be054d7154 100644 (file)
@@ -3903,6 +3903,7 @@ http-request { allow | auth [realm <realm>] | redirect <rule> | reject |
               unset-var(<var name>) |
               { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>] |
               sc-inc-gpc0(<sc-id>) |
+              sc-inc-gpc1(<sc-id>) |
               sc-set-gpt0(<sc-id>) <int> |
               silent-drop |
               send-spoe-group |
@@ -4194,6 +4195,9 @@ http-request { allow | auth [realm <realm>] | redirect <rule> | reject |
       designated by <sc-id>. If an error occurs, this action silently fails and
       the actions evaluation continues.
 
+    - sc-inc-gpc1(<sc-id>):
+         Same as "sc-inc-gpc0" action above but for GPC1 counter.
+
     - set-var(<var-name>) <expr> :
       Is used to set the contents of a variable. The variable is declared
       inline.
@@ -4403,6 +4407,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-inc-gpc1(<sc-id>) |
                 sc-set-gpt0(<sc-id>) <int> |
                 silent-drop |
                 send-spoe-group |
@@ -4644,6 +4649,9 @@ 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-inc-gpc1(<sc-id>):
+         Same as "sc-inc-gpc0" action above but for GPC1 counter.
+
     - "silent-drop" : this stops the evaluation of the rules and makes the
       client-facing connection suddenly disappear using a system-dependent way
       that tries to prevent the client from being notified. The effect it then
@@ -8743,6 +8751,18 @@ stick-table type {ip | integer | string [len <length>] | binary [len <length>]}
       incremented. Most of the time it will be used to measure the frequency of
       occurrence of certain events (e.g. requests to a specific URL).
 
+    - gpc1 : second General Purpose Counter. It is a positive 32-bit integer
+      integer which may be used for anything. Most of the time it will be used
+      to put a special tag on some entries, for instance to note that a
+      specific behavior was detected and must be known for future matches.
+
+    - gpc1_rate(<period>) : increment rate of the second General Purpose Counter
+      over a period. It is a positive 32-bit integer integer which may be used
+      for anything. Just like <gpc1>, it counts events, but instead of keeping
+      a cumulative number, it maintains the rate at which the counter is
+      incremented. Most of the time it will be used to measure the frequency of
+      occurrence of certain events (e.g. requests to a specific URL).
+
     - conn_cnt : Connection Count. It is a positive 32-bit integer which counts
       the absolute number of connections received from clients which matched
       this entry. It does not mean the connections were accepted, just that
@@ -9255,6 +9275,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-inc-gpc1(<sc-id>):
+        The "sc-inc-gpc1" increments the GPC1 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
@@ -9414,6 +9439,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-inc-gpc1(<sc-id>)
     - sc-set-gpt0(<sc-id>) <int>
     - set-var(<var-name>) <expr>
     - unset-var(<var-name>)
@@ -9648,6 +9674,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-inc-gpc1(<sc-id>):
+        This action increments the GPC1 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
@@ -9772,6 +9803,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-inc-gpc1(<sc-id>)
     - sc-set-gpt0(<sc-id>) <int>
     - set-var(<var-name>) <expr>
     - unset-var(<var-name>)
@@ -13237,6 +13269,21 @@ table_gpc0_rate(<table>)
   with the input sample in the designated table. See also the sc_get_gpc0_rate
   sample fetch keyword.
 
+table_gpc1(<table>)
+  Uses the string representation of the input sample to perform a look up in
+  the specified table. If the key is not found in the table, integer value zero
+  is returned. Otherwise the converter returns the current value of the second
+  general purpose counter associated with the input sample in the designated
+  table. See also the sc_get_gpc1 sample fetch keyword.
+
+table_gpc1_rate(<table>)
+  Uses the string representation of the input sample to perform a look up in
+  the specified table. If the key is not found in the table, integer value zero
+  is returned. Otherwise the converter returns the frequency which the gpc1
+  counter was incremented over the configured period in the table, associated
+  with the input sample in the designated table. See also the sc_get_gpc1_rate
+  sample fetch keyword.
+
 table_http_err_cnt(<table>)
   Uses the string representation of the input sample to perform a look up in
   the specified table. If the key is not found in the table, integer value zero
@@ -13880,6 +13927,16 @@ sc2_clr_gpc0([<table>]) : integer
         tcp-request connection accept if !abuse save
         tcp-request connection reject if abuse kill
 
+sc_clr_gpc1(<ctr>[,<table>]) : integer
+sc0_clr_gpc1([<table>]) : integer
+sc1_clr_gpc1([<table>]) : integer
+sc2_clr_gpc1([<table>]) : integer
+  Clears the second General Purpose Counter associated to the currently tracked
+  counters, and returns its previous value. Before the first invocation, the
+  stored value is zero, so first invocation will always return zero. This is
+  typically used as a second ACL in an expression in order to mark a connection
+  when a first ACL was verified.
+
 sc_conn_cnt(<ctr>[,<table>]) : integer
 sc0_conn_cnt([<table>]) : integer
 sc1_conn_cnt([<table>]) : integer
@@ -13910,6 +13967,13 @@ 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.
 
+sc_get_gpc1(<ctr>[,<table>]) : integer
+sc0_get_gpc1([<table>]) : integer
+sc1_get_gpc1([<table>]) : integer
+sc2_get_gpc1([<table>]) : integer
+  Returns the value of the second General Purpose Counter associated to the
+  currently tracked counters. See also src_get_gpc1 and sc/sc0/sc1/sc2_inc_gpc1.
+
 sc_get_gpt0(<ctr>[,<table>]) : integer
 sc0_get_gpt0([<table>]) : integer
 sc1_get_gpt0([<table>]) : integer
@@ -13928,6 +13992,17 @@ sc2_gpc0_rate([<table>]) : integer
   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_gpc1_rate(<ctr>[,<table>]) : integer
+sc0_gpc1_rate([<table>]) : integer
+sc1_gpc1_rate([<table>]) : integer
+sc2_gpc1_rate([<table>]) : integer
+  Returns the average increment rate of the second General Purpose Counter
+  associated to the currently tracked counters. It reports the frequency
+  which the gpc1 counter was incremented over the configured period. See also
+  src_gpcA_rate, sc/sc0/sc1/sc2_get_gpc1, and sc/sc0/sc1/sc2_inc_gpc1. Note
+  that the "gpc1_rate" counter must be stored in the stick-table for a value to
+  be returned, as "gpc1" only holds the event count.
+
 sc_http_err_cnt(<ctr>[,<table>]) : integer
 sc0_http_err_cnt([<table>]) : integer
 sc1_http_err_cnt([<table>]) : integer
@@ -13977,6 +14052,16 @@ sc2_inc_gpc0([<table>]) : integer
         acl kill  sc0_inc_gpc0 gt 0
         tcp-request connection reject if abuse kill
 
+sc_inc_gpc1(<ctr>[,<table>]) : integer
+sc0_inc_gpc1([<table>]) : integer
+sc1_inc_gpc1([<table>]) : integer
+sc2_inc_gpc1([<table>]) : integer
+  Increments the second General Purpose Counter associated to the currently
+  tracked counters, and returns its new value. Before the first invocation,
+  the stored value is zero, so first invocation will increase it to 1 and will
+  return 1. This is typically used as a second ACL in an expression in order
+  to mark a connection when a first ACL was verified.
+
 sc_kbytes_in(<ctr>[,<table>]) : integer
 sc0_kbytes_in([<table>]) : integer
 sc1_kbytes_in([<table>]) : integer
@@ -14084,6 +14169,14 @@ src_clr_gpc0([<table>]) : integer
         tcp-request connection accept if !abuse save
         tcp-request connection reject if abuse kill
 
+src_clr_gpc1([<table>]) : integer
+  Clears the second 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 previous value. If the address is not
+  found, an entry is created and 0 is returned. This is typically used as a
+  second ACL in an expression in order to mark a connection when a first ACL
+  was verified.
+
 src_conn_cnt([<table>]) : integer
   Returns the cumulative number of connections initiated from the current
   incoming connection's source address in the current proxy's stick-table or in
@@ -14108,6 +14201,12 @@ src_get_gpc0([<table>]) : integer
   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.
 
+src_get_gpc1([<table>]) : integer
+  Returns the value of the second 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_gpc1 and src_inc_gpc1.
+
 src_get_gpt0([<table>]) : integer
   Returns the value of the first General Purpose Tag associated to the
   incoming connection's source address in the current proxy's stick-table or in
@@ -14123,6 +14222,15 @@ src_gpc0_rate([<table>]) : integer
   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_gpc1_rate([<table>]) : integer
+  Returns the average increment rate of the second General Purpose Counter
+  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 gpc1 counter was incremented over the configured period. See also
+  sc/sc0/sc1/sc2_gpc1_rate, src_get_gpc1, and sc/sc0/sc1/sc2_inc_gpc1. Note
+  that the "gpc1_rate" counter must be stored in the stick-table for a value to
+  be returned, as "gpc1" only holds the event count.
+
 src_http_err_cnt([<table>]) : integer
   Returns the cumulative number of HTTP errors from the incoming connection's
   source address in the current proxy's stick-table or in the designated
@@ -14163,6 +14271,14 @@ src_inc_gpc0([<table>]) : integer
         acl kill  src_inc_gpc0 gt 0
         tcp-request connection reject if abuse kill
 
+src_inc_gpc1([<table>]) : integer
+  Increments the second 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 1 is returned. See also sc0/sc2/sc2_inc_gpc1.
+  This is typically used as a second ACL in an expression in order to mark a
+  connection when a first ACL was verified.
+
 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
index 767721eb37b79f64d261e6a5f1c002ab0e73ff74..6812c85a069de1dfb79536851839d19210e2261c 100644 (file)
@@ -219,6 +219,8 @@ bit
  14: bytes in rate
  15: bytes out rate
  16: bytes out rate
+ 17: gpc1
+ 18: gpc1 rate
 
 d) Table Switch Message
 
index 4a8d8c7db2fa08098997a97904803156e219bd82..28e255fb83c44c533eaea1d9452b5d7afe80ae09 100644 (file)
@@ -52,6 +52,8 @@ enum {
        STKTABLE_DT_BYTES_IN_RATE,/* bytes rate from client to servers */
        STKTABLE_DT_BYTES_OUT_CNT,/* cumulated bytes count from servers to client */
        STKTABLE_DT_BYTES_OUT_RATE,/* bytes rate from servers to client */
+       STKTABLE_DT_GPC1,         /* General Purpose Counter 1 (unsigned 32-bit integer) */
+       STKTABLE_DT_GPC1_RATE,    /* General Purpose Counter 1's event rate */
        STKTABLE_STATIC_DATA_TYPES,/* number of types above */
        /* up to STKTABLE_EXTRA_DATA_TYPES types may be registered here, always
         * followed by the number of data types, must always be last.
@@ -87,6 +89,8 @@ union stktable_data {
        unsigned int gpt0;
        unsigned int gpc0;
        struct freq_ctr_period gpc0_rate;
+       unsigned int gpc1;
+       struct freq_ctr_period gpc1_rate;
        unsigned int conn_cnt;
        struct freq_ctr_period conn_rate;
        unsigned int conn_cur;
index 40c9258a0f00b8aeb0420765c60e2ea9196d1939..fe26e31214181d22cbf6be2a07150d4e078e1c7d 100644 (file)
@@ -800,6 +800,8 @@ struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES] = {
        [STKTABLE_DT_BYTES_IN_RATE] = { .name = "bytes_in_rate",  .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY },
        [STKTABLE_DT_BYTES_OUT_CNT] = { .name = "bytes_out_cnt",  .std_type = STD_T_ULL   },
        [STKTABLE_DT_BYTES_OUT_RATE]= { .name = "bytes_out_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY },
+       [STKTABLE_DT_GPC1]          = { .name = "gpc1",           .std_type = STD_T_UINT  },
+       [STKTABLE_DT_GPC1_RATE]     = { .name = "gpc1_rate",      .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY  },
 };
 
 /* Registers stick-table extra data type with index <idx>, name <name>, type
@@ -1168,6 +1170,79 @@ static int sample_conv_table_gpc0_rate(const struct arg *arg_p, struct sample *s
        return 1;
 }
 
+/* Casts sample <smp> to the type of the table specified in arg(0), and looks
+ * it up into this table. Returns the value of the GPC1 counter for the key
+ * if the key is present in the table, otherwise zero, so that comparisons can
+ * be easily performed. If the inspected parameter is not stored in the table,
+ * <not found> is returned.
+ */
+static int sample_conv_table_gpc1(const struct arg *arg_p, struct sample *smp, void *private)
+{
+       struct stktable *t;
+       struct stktable_key *key;
+       struct stksess *ts;
+       void *ptr;
+
+       t = &arg_p[0].data.prx->table;
+
+       key = smp_to_stkey(smp, t);
+       if (!key)
+               return 0;
+
+       ts = stktable_lookup_key(t, key);
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+
+       if (!ts) /* key not present */
+               return 1;
+
+       ptr = stktable_data_ptr(t, ts, STKTABLE_DT_GPC1);
+       if (!ptr)
+               return 0; /* parameter not stored */
+
+       smp->data.u.sint = stktable_data_cast(ptr, gpc1);
+       return 1;
+}
+
+/* Casts sample <smp> to the type of the table specified in arg(0), and looks
+ * it up into this table. Returns the event rate of the GPC1 counter for the key
+ * if the key is present in the table, otherwise zero, so that comparisons can
+ * be easily performed. If the inspected parameter is not stored in the table,
+ * <not found> is returned.
+ */
+static int sample_conv_table_gpc1_rate(const struct arg *arg_p, struct sample *smp, void *private)
+{
+       struct stktable *t;
+       struct stktable_key *key;
+       struct stksess *ts;
+       void *ptr;
+
+       t = &arg_p[0].data.prx->table;
+
+       key = smp_to_stkey(smp, t);
+       if (!key)
+               return 0;
+
+       ts = stktable_lookup_key(t, key);
+
+       smp->flags = SMP_F_VOL_TEST;
+       smp->data.type = SMP_T_SINT;
+       smp->data.u.sint = 0;
+
+       if (!ts) /* key not present */
+               return 1;
+
+       ptr = stktable_data_ptr(t, ts, STKTABLE_DT_GPC1_RATE);
+       if (!ptr)
+               return 0; /* parameter not stored */
+
+       smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc1_rate),
+                                             t->data_arg[STKTABLE_DT_GPC1_RATE].u);
+       return 1;
+}
+
 /* Casts sample <smp> to the type of the table specified in arg(0), and looks
  * it up into this table. Returns the cumulated number of HTTP request errors
  * for the key if the key is present in the table, otherwise zero, so that
@@ -1607,6 +1682,88 @@ static enum act_parse_ret parse_inc_gpc0(const char **args, int *arg, struct pro
        return ACT_RET_PRS_OK;
 }
 
+/* Always returns 1. */
+static enum act_return action_inc_gpc1(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, *ptr2;
+
+               /* First, update gpc1_rate if it's tracked. Second, update its gpc1 if tracked. */
+               ptr1 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_GPC1_RATE);
+               ptr2 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_GPC1);
+               if (ptr1 || ptr2) {
+                       HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
+
+                       if (ptr1)
+                               update_freq_ctr_period(&stktable_data_cast(ptr1, gpc1_rate),
+                                              stkctr->table->data_arg[STKTABLE_DT_GPC1_RATE].u, 1);
+
+                       if (ptr2)
+                               stktable_data_cast(ptr2, gpc1)++;
+
+                       HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
+
+                       /* If data was modified, we need to touch to re-schedule sync */
+                       stktable_touch_local(stkctr->table, ts, 0);
+               }
+       }
+       return ACT_RET_CONT;
+}
+
+/* This function is a common parser for using variables. It understands
+ * the formats:
+ *
+ *   sc-inc-gpc1(<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_inc_gpc1(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-inc-gpc1");
+       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_inc_gpc1;
+       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)
@@ -1940,6 +2097,47 @@ smp_fetch_sc_get_gpc0(const struct arg *args, struct sample *smp, const char *kw
        return 1;
 }
 
+/* set <smp> to the General Purpose Counter 1 value from the stream's tracked
+ * frontend counters or from the src.
+ * Supports being called as "sc[0-9]_get_gpc1" or "src_get_gpc1" only. Value
+ * zero is returned if the key is new.
+ */
+static int
+smp_fetch_sc_get_gpc1(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr tmpstkctr;
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr);
+       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;
+
+               ptr  = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC1);
+               if (!ptr) {
+                       if (stkctr == &tmpstkctr)
+                               stktable_release(stkctr->table, stkctr_entry(stkctr));
+                       return 0; /* parameter not stored */
+               }
+
+               HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
+
+               smp->data.u.sint = stktable_data_cast(ptr, gpc1);
+
+               HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
+
+               if (stkctr == &tmpstkctr)
+                       stktable_release(stkctr->table, stkctr_entry(stkctr));
+       }
+       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.
@@ -1981,6 +2179,47 @@ smp_fetch_sc_gpc0_rate(const struct arg *args, struct sample *smp, const char *k
        return 1;
 }
 
+/* set <smp> to the General Purpose Counter 1's event rate from the stream's
+ * tracked frontend counters or from the src.
+ * Supports being called as "sc[0-9]_gpc1_rate" or "src_gpc1_rate" only.
+ * Value zero is returned if the key is new.
+ */
+static int
+smp_fetch_sc_gpc1_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr tmpstkctr;
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr);
+       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;
+
+               ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC1_RATE);
+               if (!ptr) {
+                       if (stkctr == &tmpstkctr)
+                               stktable_release(stkctr->table, stkctr_entry(stkctr));
+                       return 0; /* parameter not stored */
+               }
+
+               HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
+
+               smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc1_rate),
+                                 stkctr->table->data_arg[STKTABLE_DT_GPC1_RATE].u);
+
+               HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
+
+               if (stkctr == &tmpstkctr)
+                       stktable_release(stkctr->table, stkctr_entry(stkctr));
+       }
+       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.
@@ -2034,6 +2273,59 @@ smp_fetch_sc_inc_gpc0(const struct arg *args, struct sample *smp, const char *kw
        return 1;
 }
 
+/* Increment the General Purpose Counter 1 value from the stream's tracked
+ * frontend counters and return it into temp integer.
+ * Supports being called as "sc[0-9]_inc_gpc1" or "src_inc_gpc1" only.
+ */
+static int
+smp_fetch_sc_inc_gpc1(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr tmpstkctr;
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr);
+       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))
+               stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr);
+
+       if (stkctr && stkctr_entry(stkctr)) {
+               void *ptr1,*ptr2;
+
+
+               /* First, update gpc1_rate if it's tracked. Second, update its
+                * gpc1 if tracked. Returns gpc1's value otherwise the curr_ctr.
+                */
+               ptr1 = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC1_RATE);
+               ptr2 = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC1);
+               if (ptr1 || ptr2) {
+                       HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
+
+                       if (ptr1) {
+                               update_freq_ctr_period(&stktable_data_cast(ptr1, gpc1_rate),
+                                                      stkctr->table->data_arg[STKTABLE_DT_GPC1_RATE].u, 1);
+                               smp->data.u.sint = (&stktable_data_cast(ptr1, gpc1_rate))->curr_ctr;
+                       }
+
+                       if (ptr2)
+                               smp->data.u.sint = ++stktable_data_cast(ptr2, gpc1);
+
+                       HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
+
+                       /* If data was modified, we need to touch to re-schedule sync */
+                       stktable_touch_local(stkctr->table, stkctr_entry(stkctr), (stkctr == &tmpstkctr) ? 1 : 0);
+               }
+               else if (stkctr == &tmpstkctr)
+                       stktable_release(stkctr->table, stkctr_entry(stkctr));
+       }
+       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.
@@ -2078,6 +2370,50 @@ smp_fetch_sc_clr_gpc0(const struct arg *args, struct sample *smp, const char *kw
        return 1;
 }
 
+/* Clear the General Purpose Counter 1 value from the stream's tracked
+ * frontend counters and return its previous value into temp integer.
+ * Supports being called as "sc[0-9]_clr_gpc1" or "src_clr_gpc1" only.
+ */
+static int
+smp_fetch_sc_clr_gpc1(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       struct stkctr tmpstkctr;
+       struct stkctr *stkctr;
+
+       stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr);
+       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))
+               stkctr = smp_create_src_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr);
+
+       if (stkctr && stkctr_entry(stkctr)) {
+               void *ptr;
+
+               ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_GPC1);
+               if (!ptr) {
+                       if (stkctr == &tmpstkctr)
+                               stktable_release(stkctr->table, stkctr_entry(stkctr));
+                       return 0; /* parameter not stored */
+               }
+
+               HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
+
+               smp->data.u.sint = stktable_data_cast(ptr, gpc1);
+               stktable_data_cast(ptr, gpc1) = 0;
+
+               HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
+
+               /* If data was modified, we need to touch to re-schedule sync */
+               stktable_touch_local(stkctr->table, stkctr_entry(stkctr), (stkctr == &tmpstkctr) ? 1 : 0);
+       }
+       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.
@@ -3281,36 +3617,42 @@ static struct cli_kw_list cli_kws = {{ },{
 
 static struct action_kw_list tcp_conn_kws = { { }, {
        { "sc-inc-gpc0", parse_inc_gpc0, 1 },
+       { "sc-inc-gpc1", parse_inc_gpc1, 1 },
        { "sc-set-gpt0", parse_set_gpt0, 1 },
        { /* END */ }
 }};
 
 static struct action_kw_list tcp_sess_kws = { { }, {
        { "sc-inc-gpc0", parse_inc_gpc0, 1 },
+       { "sc-inc-gpc1", parse_inc_gpc1, 1 },
        { "sc-set-gpt0", parse_set_gpt0, 1 },
        { /* END */ }
 }};
 
 static struct action_kw_list tcp_req_kws = { { }, {
        { "sc-inc-gpc0", parse_inc_gpc0, 1 },
+       { "sc-inc-gpc1", parse_inc_gpc1, 1 },
        { "sc-set-gpt0", parse_set_gpt0, 1 },
        { /* END */ }
 }};
 
 static struct action_kw_list tcp_res_kws = { { }, {
        { "sc-inc-gpc0", parse_inc_gpc0, 1 },
+       { "sc-inc-gpc1", parse_inc_gpc1, 1 },
        { "sc-set-gpt0", parse_set_gpt0, 1 },
        { /* END */ }
 }};
 
 static struct action_kw_list http_req_kws = { { }, {
        { "sc-inc-gpc0", parse_inc_gpc0, 1 },
+       { "sc-inc-gpc1", parse_inc_gpc1, 1 },
        { "sc-set-gpt0", parse_set_gpt0, 1 },
        { /* END */ }
 }};
 
 static struct action_kw_list http_res_kws = { { }, {
        { "sc-inc-gpc0", parse_inc_gpc0, 1 },
+       { "sc-inc-gpc1", parse_inc_gpc1, 1 },
        { "sc-set-gpt0", parse_set_gpt0, 1 },
        { /* END */ }
 }};
@@ -3330,17 +3672,21 @@ 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_clr_gpc1",        smp_fetch_sc_clr_gpc1,       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_SINT, SMP_USE_INTRN, },
        { "sc_get_gpc0",        smp_fetch_sc_get_gpc0,       ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc_get_gpc1",        smp_fetch_sc_get_gpc1,       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_gpc1_rate",       smp_fetch_sc_gpc1_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_inc_gpc1",        smp_fetch_sc_inc_gpc1,       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, },
@@ -3350,17 +3696,21 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
        { "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_clr_gpc1",       smp_fetch_sc_clr_gpc1,       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_SINT, SMP_USE_INTRN, },
        { "sc0_get_gpc0",       smp_fetch_sc_get_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc0_get_gpc1",       smp_fetch_sc_get_gpc1,       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_gpc1_rate",      smp_fetch_sc_gpc1_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_inc_gpc1",       smp_fetch_sc_inc_gpc1,       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, },
@@ -3370,17 +3720,21 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
        { "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_clr_gpc1",       smp_fetch_sc_clr_gpc1,       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_SINT, SMP_USE_INTRN, },
        { "sc1_get_gpc0",       smp_fetch_sc_get_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc1_get_gpc1",       smp_fetch_sc_get_gpc1,       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_gpc1_rate",      smp_fetch_sc_gpc1_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_inc_gpc1",       smp_fetch_sc_inc_gpc1,       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, },
@@ -3390,17 +3744,21 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
        { "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_clr_gpc1",       smp_fetch_sc_clr_gpc1,       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_SINT, SMP_USE_INTRN, },
        { "sc2_get_gpc0",       smp_fetch_sc_get_gpc0,       ARG1(0,TAB),      NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "sc2_get_gpc1",       smp_fetch_sc_get_gpc1,       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_gpc1_rate",      smp_fetch_sc_gpc1_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_inc_gpc1",       smp_fetch_sc_inc_gpc1,       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, },
@@ -3410,17 +3768,21 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
        { "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_clr_gpc1",       smp_fetch_sc_clr_gpc1,       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_SINT, SMP_USE_L4CLI, },
        { "src_get_gpc0",       smp_fetch_sc_get_gpc0,       ARG1(1,TAB),      NULL, SMP_T_SINT, SMP_USE_L4CLI, },
+       { "src_get_gpc1",       smp_fetch_sc_get_gpc1,       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_gpc1_rate",      smp_fetch_sc_gpc1_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_inc_gpc1",       smp_fetch_sc_inc_gpc1,       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, },
@@ -3442,7 +3804,9 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, {
        { "table_conn_rate",      sample_conv_table_conn_rate,      ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_gpt0",           sample_conv_table_gpt0,           ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_gpc0",           sample_conv_table_gpc0,           ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
+       { "table_gpc1",           sample_conv_table_gpc1,           ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_gpc0_rate",      sample_conv_table_gpc0_rate,      ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
+       { "table_gpc1_rate",      sample_conv_table_gpc1_rate,      ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_http_err_cnt",   sample_conv_table_http_err_cnt,   ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_http_err_rate",  sample_conv_table_http_err_rate,  ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },
        { "table_http_req_cnt",   sample_conv_table_http_req_cnt,   ARG1(1,TAB),  NULL, SMP_T_ANY,  SMP_T_SINT  },