mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
MINOR: stick-table: allow sc-set-gpt0 to set value from an expression
Allow the sc-set-gpt0 action to set GPT0 to a value dynamically evaluated from its <expr> argument (in addition to the existing static <int> alternative).
This commit is contained in:
parent
869efd5eeb
commit
0d7712dff0
@ -4471,11 +4471,13 @@ http-request sc-inc-gpc1(<sc-id>) [ { if | unless } <condition> ]
|
|||||||
counter designated by <sc-id>. If an error occurs, this action silently fails
|
counter designated by <sc-id>. If an error occurs, this action silently fails
|
||||||
and the actions evaluation continues.
|
and the actions evaluation continues.
|
||||||
|
|
||||||
http-request sc-set-gpt0(<sc-id>) <int> [ { if | unless } <condition> ]
|
http-request sc-set-gpt0(<sc-id>) { <int> | <expr> }
|
||||||
|
[ { if | unless } <condition> ]
|
||||||
|
|
||||||
This action sets the GPT0 tag according to the sticky counter designated by
|
This action sets the 32-bit unsigned GPT0 tag according to the sticky counter
|
||||||
<sc-id> and the value of <int>. The expected result is a boolean. If an error
|
designated by <sc-id> and the value of <int>/<expr>. The expected result is a
|
||||||
occurs, this action silently fails and the actions evaluation continues.
|
boolean. If an error occurs, this action silently fails and the actions
|
||||||
|
evaluation continues.
|
||||||
|
|
||||||
http-request set-dst <expr> [ { if | unless } <condition> ]
|
http-request set-dst <expr> [ { if | unless } <condition> ]
|
||||||
|
|
||||||
@ -4980,11 +4982,13 @@ http-response sc-inc-gpc1(<sc-id>) [ { if | unless } <condition> ]
|
|||||||
counter designated by <sc-id>. If an error occurs, this action silently fails
|
counter designated by <sc-id>. If an error occurs, this action silently fails
|
||||||
and the actions evaluation continues.
|
and the actions evaluation continues.
|
||||||
|
|
||||||
http-response sc-set-gpt0(<sc-id>) <int> [ { if | unless } <condition> ]
|
http-response sc-set-gpt0(<sc-id>) { <int> | <expr> }
|
||||||
|
[ { if | unless } <condition> ]
|
||||||
|
|
||||||
This action sets the GPT0 tag according to the sticky counter designated by
|
This action sets the 32-bit unsigned GPT0 tag according to the sticky counter
|
||||||
<sc-id> and the value of <int>. The expected result is a boolean. If an error
|
designated by <sc-id> and the value of <int>/<expr>. The expected result is a
|
||||||
occurs, this action silently fails and the actions evaluation continues.
|
boolean. If an error occurs, this action silently fails and the actions
|
||||||
|
evaluation continues.
|
||||||
|
|
||||||
http-response send-spoe-group [ { if | unless } <condition> ]
|
http-response send-spoe-group [ { if | unless } <condition> ]
|
||||||
|
|
||||||
@ -9398,11 +9402,11 @@ tcp-request connection <action> [{if | unless} <condition>]
|
|||||||
counter designated by <sc-id>. If an error occurs, this action silently
|
counter designated by <sc-id>. If an error occurs, this action silently
|
||||||
fails and the actions evaluation continues.
|
fails and the actions evaluation continues.
|
||||||
|
|
||||||
- sc-set-gpt0(<sc-id>) <int>:
|
- sc-set-gpt0(<sc-id>) { <int> | <expr> }:
|
||||||
This action sets the GPT0 tag according to the sticky counter designated
|
This action sets the 32-bit unsigned GPT0 tag according to the sticky
|
||||||
by <sc-id> and the value of <int>. The expected result is a boolean. If
|
counter designated by <sc-id> and the value of <int>/<expr>. The
|
||||||
an error occurs, this action silently fails and the actions evaluation
|
expected result is a boolean. If an error occurs, this action silently
|
||||||
continues.
|
fails and the actions evaluation continues.
|
||||||
|
|
||||||
- set-src <expr> :
|
- set-src <expr> :
|
||||||
Is used to set the source IP address to the value of specified
|
Is used to set the source IP address to the value of specified
|
||||||
@ -9560,7 +9564,7 @@ tcp-request content <action> [{if | unless} <condition>]
|
|||||||
- { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>]
|
- { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>]
|
||||||
- sc-inc-gpc0(<sc-id>)
|
- sc-inc-gpc0(<sc-id>)
|
||||||
- sc-inc-gpc1(<sc-id>)
|
- sc-inc-gpc1(<sc-id>)
|
||||||
- sc-set-gpt0(<sc-id>) <int>
|
- sc-set-gpt0(<sc-id>) { <int> | <expr> }
|
||||||
- set-dst <expr>
|
- set-dst <expr>
|
||||||
- set-dst-port <expr>
|
- set-dst-port <expr>
|
||||||
- set-var(<var-name>) <expr>
|
- set-var(<var-name>) <expr>
|
||||||
@ -9824,11 +9828,11 @@ tcp-response content <action> [{if | unless} <condition>]
|
|||||||
counter designated by <sc-id>. If an error occurs, this action fails
|
counter designated by <sc-id>. If an error occurs, this action fails
|
||||||
silently and the actions evaluation continues.
|
silently and the actions evaluation continues.
|
||||||
|
|
||||||
- sc-set-gpt0(<sc-id>) <int> :
|
- sc-set-gpt0(<sc-id>) { <int> | <expr> }
|
||||||
This action sets the GPT0 tag according to the sticky counter designated
|
This action sets the 32-bit unsigned GPT0 tag according to the sticky
|
||||||
by <sc-id> and the value of <int>. The expected result is a boolean. If
|
counter designated by <sc-id> and the value of <int>/<expr>. The
|
||||||
an error occurs, this action silently fails and the actions evaluation
|
expected result is a boolean. If an error occurs, this action silently
|
||||||
continues.
|
fails and the actions evaluation continues.
|
||||||
|
|
||||||
- "silent-drop" :
|
- "silent-drop" :
|
||||||
This stops the evaluation of the rules and makes the client-facing
|
This stops the evaluation of the rules and makes the client-facing
|
||||||
@ -9949,7 +9953,7 @@ tcp-request session <action> [{if | unless} <condition>]
|
|||||||
- { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>]
|
- { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>]
|
||||||
- sc-inc-gpc0(<sc-id>)
|
- sc-inc-gpc0(<sc-id>)
|
||||||
- sc-inc-gpc1(<sc-id>)
|
- sc-inc-gpc1(<sc-id>)
|
||||||
- sc-set-gpt0(<sc-id>) <int>
|
- sc-set-gpt0(<sc-id>) { <int> | <expr> }
|
||||||
- set-var(<var-name>) <expr>
|
- set-var(<var-name>) <expr>
|
||||||
- unset-var(<var-name>)
|
- unset-var(<var-name>)
|
||||||
- silent-drop
|
- silent-drop
|
||||||
|
@ -168,6 +168,7 @@ struct act_rule {
|
|||||||
struct {
|
struct {
|
||||||
int sc;
|
int sc;
|
||||||
long long int value;
|
long long int value;
|
||||||
|
struct sample_expr *expr;
|
||||||
} gpt;
|
} gpt;
|
||||||
struct track_ctr_prm trk_ctr;
|
struct track_ctr_prm trk_ctr;
|
||||||
struct {
|
struct {
|
||||||
|
@ -2016,6 +2016,9 @@ static enum act_return action_set_gpt0(struct act_rule *rule, struct proxy *px,
|
|||||||
void *ptr;
|
void *ptr;
|
||||||
struct stksess *ts;
|
struct stksess *ts;
|
||||||
struct stkctr *stkctr;
|
struct stkctr *stkctr;
|
||||||
|
unsigned int value = 0;
|
||||||
|
struct sample *smp;
|
||||||
|
int smp_opt_dir;
|
||||||
|
|
||||||
/* Extract the stksess, return OK if no stksess available. */
|
/* Extract the stksess, return OK if no stksess available. */
|
||||||
if (s)
|
if (s)
|
||||||
@ -2030,9 +2033,36 @@ static enum act_return action_set_gpt0(struct act_rule *rule, struct proxy *px,
|
|||||||
/* Store the sample in the required sc, and ignore errors. */
|
/* Store the sample in the required sc, and ignore errors. */
|
||||||
ptr = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_GPT0);
|
ptr = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_GPT0);
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
|
if (!rule->arg.gpt.expr)
|
||||||
|
value = (unsigned int)(rule->arg.gpt.value);
|
||||||
|
else {
|
||||||
|
switch (rule->from) {
|
||||||
|
case ACT_F_TCP_REQ_SES: smp_opt_dir = SMP_OPT_DIR_REQ; break;
|
||||||
|
case ACT_F_TCP_REQ_CNT: smp_opt_dir = SMP_OPT_DIR_REQ; break;
|
||||||
|
case ACT_F_TCP_RES_CNT: smp_opt_dir = SMP_OPT_DIR_RES; break;
|
||||||
|
case ACT_F_HTTP_REQ: smp_opt_dir = SMP_OPT_DIR_REQ; break;
|
||||||
|
case ACT_F_HTTP_RES: smp_opt_dir = SMP_OPT_DIR_RES; break;
|
||||||
|
default:
|
||||||
|
send_log(px, LOG_ERR, "stick table: internal error while setting gpt0.");
|
||||||
|
if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
|
||||||
|
ha_alert("stick table: internal error while executing setting gpt0.\n");
|
||||||
|
return ACT_RET_CONT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fetch and cast the expression. */
|
||||||
|
smp = sample_fetch_as_type(px, sess, s, smp_opt_dir|SMP_OPT_FINAL, rule->arg.gpt.expr, SMP_T_SINT);
|
||||||
|
if (!smp) {
|
||||||
|
send_log(px, LOG_WARNING, "stick table: invalid expression or data type while setting gpt0.");
|
||||||
|
if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))
|
||||||
|
ha_alert("stick table: invalid expression or data type while setting gpt0.\n");
|
||||||
|
return ACT_RET_CONT;
|
||||||
|
}
|
||||||
|
value = (unsigned int)(smp->data.u.sint);
|
||||||
|
}
|
||||||
|
|
||||||
HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
|
HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
|
||||||
|
|
||||||
stktable_data_cast(ptr, gpt0) = rule->arg.gpt.value;
|
stktable_data_cast(ptr, gpt0) = value;
|
||||||
|
|
||||||
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
||||||
|
|
||||||
@ -2058,6 +2088,7 @@ static enum act_parse_ret parse_set_gpt0(const char **args, int *arg, struct pro
|
|||||||
{
|
{
|
||||||
const char *cmd_name = args[*arg-1];
|
const char *cmd_name = args[*arg-1];
|
||||||
char *error;
|
char *error;
|
||||||
|
int smp_val;
|
||||||
|
|
||||||
cmd_name += strlen("sc-set-gpt0");
|
cmd_name += strlen("sc-set-gpt0");
|
||||||
if (*cmd_name == '\0') {
|
if (*cmd_name == '\0') {
|
||||||
@ -2083,10 +2114,30 @@ static enum act_parse_ret parse_set_gpt0(const char **args, int *arg, struct pro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rule->arg.gpt.expr = NULL;
|
||||||
rule->arg.gpt.value = strtol(args[*arg], &error, 10);
|
rule->arg.gpt.value = strtol(args[*arg], &error, 10);
|
||||||
if (*error != '\0') {
|
if (*error != '\0') {
|
||||||
memprintf(err, "invalid integer value '%s'", args[*arg]);
|
rule->arg.gpt.expr = sample_parse_expr((char **)args, arg, px->conf.args.file,
|
||||||
return ACT_RET_PRS_ERR;
|
px->conf.args.line, err, &px->conf.args);
|
||||||
|
if (!rule->arg.gpt.expr)
|
||||||
|
return ACT_RET_PRS_ERR;
|
||||||
|
|
||||||
|
switch (rule->from) {
|
||||||
|
case ACT_F_TCP_REQ_SES: smp_val = SMP_VAL_FE_SES_ACC; break;
|
||||||
|
case ACT_F_TCP_REQ_CNT: smp_val = SMP_VAL_FE_REQ_CNT; break;
|
||||||
|
case ACT_F_TCP_RES_CNT: smp_val = SMP_VAL_BE_RES_CNT; break;
|
||||||
|
case ACT_F_HTTP_REQ: smp_val = SMP_VAL_FE_HRQ_HDR; break;
|
||||||
|
case ACT_F_HTTP_RES: smp_val = SMP_VAL_BE_HRS_HDR; break;
|
||||||
|
default:
|
||||||
|
memprintf(err, "internal error, unexpected rule->from=%d, please report this bug!", rule->from);
|
||||||
|
return ACT_RET_PRS_ERR;
|
||||||
|
}
|
||||||
|
if (!(rule->arg.gpt.expr->fetch->val & smp_val)) {
|
||||||
|
memprintf(err, "fetch method '%s' extracts information from '%s', none of which is available here", args[*arg-1],
|
||||||
|
sample_src_names(rule->arg.gpt.expr->fetch->use));
|
||||||
|
free(rule->arg.gpt.expr);
|
||||||
|
return ACT_RET_PRS_ERR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(*arg)++;
|
(*arg)++;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user