]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stick-tables: Add GPC0 actions
authorThierry FOURNIER <tfournier@arpalert.org>
Tue, 4 Aug 2015 06:20:33 +0000 (08:20 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 20 Aug 2015 15:13:47 +0000 (17:13 +0200)
This patch adds access to GPC0 through http and tcp actions

doc/configuration.txt
include/types/action.h
src/stick_table.c

index 8447ff1d38d382535cd0e4ee0a2634e401994593..ab8884d7fa90e2e51e6868a9e3ad4a1a9cac4af0 100644 (file)
@@ -3365,6 +3365,7 @@ http-request { allow | deny | tarpit | auth [realm <realm>] | redirect <rule> |
               set-map(<file name>) <key fmt> <value fmt> |
               set-var(<var name>) <expr> |
               { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>] |
+              sc-inc-gpc0(<sc-id>) |
               sc-set-gpt0(<sc-id>) <int> |
               lua <function name>
              }
@@ -3635,6 +3636,11 @@ http-request { allow | deny | tarpit | auth [realm <realm>] | redirect <rule> |
       an error occurs, this action silently fails and the actions evaluation
       continues.
 
+    - sc-inc-gpc0(<sc-id>):
+      This action increments 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.
+
     - "lua" is used to run a Lua function if the action is executed. The single
       parameter is the name of the function to run. The prototype of the
       function is documented in the API documentation.
@@ -3745,6 +3751,7 @@ http-response { allow | deny | add-header <name> <fmt> | set-nice <nice> |
                 del-map(<file name>) <key fmt> |
                 set-map(<file name>) <key fmt> <value fmt> |
                 set-var(<var-name>) <expr> |
+                sc-inc-gpc0(<sc-id>) |
                 sc-set-gpt0(<sc-id>) <int> |
                 lua <function name>
               }
@@ -3950,6 +3957,11 @@ http-response { allow | deny | add-header <name> <fmt> | set-nice <nice> |
       an error occurs, this action silently fails and the actions evaluation
       continues.
 
+    - sc-inc-gpc0(<sc-id>):
+      This action increments 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.
+
   There is no limit to the number of http-response statements per instance.
 
   It is important to know that http-response rules are processed very early in
@@ -8312,6 +8324,11 @@ tcp-request connection <action> [{if | unless} <condition>]
         advantage over just checking the keys, because only one table lookup is
         performed for all ACL checks that make use of it.
 
+    - sc-inc-gpc0(<sc-id>):
+        The "sc-inc-gpc0" increments 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
@@ -8354,8 +8371,8 @@ tcp-request content <action> [{if | unless} <condition>]
   Arguments :
     <action>    defines the action to perform if the condition applies. Valid
                 actions include : "accept", "reject", "track-sc0", "track-sc1",
-                "track-sc2", "sc-set-gpt0", "capture" and "lua". See
-                "tcp-request connection" above for their signification.
+                "track-sc2", "sc-inc-gpc0", "sc-set-gpt0", "capture" and "lua".
+                See "tcp-request connection" above for their signification.
 
     <condition> is a standard layer 4-7 ACL-based condition (see section 7).
 
@@ -8388,6 +8405,7 @@ tcp-request content <action> [{if | unless} <condition>]
     - reject : the request is rejected and the connection is closed
     - capture : the specified sample expression is captured
     - { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>]
+    - sc-inc-gpc0(<sc-id>)
     - set-gpt0(<sc-id>) <int>
     - lua <function>
     - set-var(<var-name>) <expr>
@@ -8556,8 +8574,8 @@ tcp-response content <action> [{if | unless} <condition>]
                                  no    |    no    |   yes  |   yes
   Arguments :
     <action>    defines the action to perform if the condition applies. Valid
-                actions include : "accept", "close", "reject", "lua", and
-                "sc-set-gpt0".
+                actions include : "accept", "close", "reject", "lua",
+                "sc-inc-gpc0" and "sc-set-gpt0".
 
     <condition> is a standard layer 4-7 ACL-based condition (see section 7).
 
@@ -8601,6 +8619,11 @@ tcp-response content <action> [{if | unless} <condition>]
     - set-var(<var-name>) <expr>
         Sets a variable.
 
+    - sc-inc-gpc0(<sc-id>):
+        This action increments 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
index 5d1b2501f1120d2018ba6a7b08c96f6da462ec16..4d438c108970b598fcb3464b79a98e09d1557d42 100644 (file)
@@ -130,6 +130,9 @@ struct act_rule {
                        const char *name;
                        enum vars_scope scope;
                } vars;
+               struct {
+                       int sc;
+               } gpc;
                struct {
                        int sc;
                        long long int value;
index 623667f29eed7232a3f4a1d6507bb7ed7321c47a..7f3a5a75266c1aa031398bccad22d2bb5405d47b 100644 (file)
@@ -1309,6 +1309,75 @@ static int sample_conv_table_trackers(const struct arg *arg_p, struct sample *sm
        return 1;
 }
 
+/* Always returns 1. */
+static enum act_return action_inc_gpc0(struct act_rule *rule, struct proxy *px,
+                                       struct session *sess, struct stream *s)
+{
+       void *ptr;
+       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)
+               return ACT_RET_CONT;
+
+       /* Store the sample in the required sc, and ignore errors. */
+       ptr = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_GPC0);
+       if (!ptr)
+               return ACT_RET_CONT;
+
+       stktable_data_cast(ptr, gpc0)++;
+       return ACT_RET_CONT;
+}
+
+/* This function is a common parser for using variables. It understands
+ * the formats:
+ *
+ *   sc-inc-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_inc_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-inc-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_ACTION_CONT;
+       rule->action_ptr = action_inc_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)
@@ -1388,26 +1457,31 @@ static enum act_parse_ret parse_set_gpt0(const char **args, int *arg, struct pro
 }
 
 static struct action_kw_list tcp_conn_kws = { { }, {
+       { "sc-inc-gpc0", parse_inc_gpc0, 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-set-gpt0", parse_set_gpt0, 1 },
        { /* END */ }
 }};
 
 static struct action_kw_list tcp_res_kws = { { }, {
+       { "sc-inc-gpc0", parse_inc_gpc0, 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-set-gpt0", parse_set_gpt0, 1 },
        { /* END */ }
 }};
 
 static struct action_kw_list http_res_kws = { { }, {
+       { "sc-inc-gpc0", parse_inc_gpc0, 1 },
        { "sc-set-gpt0", parse_set_gpt0, 1 },
        { /* END */ }
 }};