mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-19 04:07:04 +00:00
MEDIUM: http: add the "set-mark" action on http-request/http-response rules
"set-mark" is used to set the Netfilter MARK on all packets sent to the client to the value passed in <mark> on platforms which support it. This value is an unsigned 32 bit value which can be matched by netfilter and by the routing table. It can be expressed both in decimal or hexadecimal format (prefixed by "0x"). This can be useful to force certain packets to take a different route (for example a cheaper network path for bulk downloads). This works on Linux kernels 2.6.32 and above and requires admin privileges.
This commit is contained in:
parent
42cf39e3b9
commit
51347ed94c
@ -2669,7 +2669,8 @@ http-check send-state
|
||||
|
||||
http-request { allow | deny | tarpit | auth [realm <realm>] | redirect <rule> |
|
||||
add-header <name> <fmt> | set-header <name> <fmt> |
|
||||
set-nice <nice> | set-log-level <level> | set-tos <tos> }
|
||||
set-nice <nice> | set-log-level <level> | set-tos <tos> |
|
||||
set-mark <mark> }
|
||||
[ { if | unless } <condition> ]
|
||||
Access control for Layer 7 requests
|
||||
|
||||
@ -2752,6 +2753,15 @@ http-request { allow | deny | tarpit | auth [realm <realm>] | redirect <rule> |
|
||||
border routers based on some information from the request. See RFC 2474,
|
||||
2597, 3260 and 4594 for more information.
|
||||
|
||||
- "set-mark" is used to set the Netfilter MARK on all packets sent to the
|
||||
client to the value passed in <mark> on platforms which support it. This
|
||||
value is an unsigned 32 bit value which can be matched by netfilter and
|
||||
by the routing table. It can be expressed both in decimal or hexadecimal
|
||||
format (prefixed by "0x"). This can be useful to force certain packets to
|
||||
take a different route (for example a cheaper network path for bulk
|
||||
downloads). This works on Linux kernels 2.6.32 and above and requires
|
||||
admin privileges.
|
||||
|
||||
There is no limit to the number of http-request statements per instance.
|
||||
|
||||
It is important to know that http-request rules are processed very early in
|
||||
@ -2788,8 +2798,8 @@ http-request { allow | deny | tarpit | auth [realm <realm>] | redirect <rule> |
|
||||
about ACL usage.
|
||||
|
||||
http-response { allow | deny | add-header <name> <fmt> | set-nice <nice> |
|
||||
set-header <name> <fmt> | set-log-level <level> }
|
||||
[ { if | unless } <condition> ]
|
||||
set-header <name> <fmt> | set-log-level <level> |
|
||||
set-mark <mark> } [ { if | unless } <condition> ]
|
||||
Access control for Layer 7 responses
|
||||
|
||||
May be used in sections: defaults | frontend | listen | backend
|
||||
@ -2849,6 +2859,15 @@ http-response { allow | deny | add-header <name> <fmt> | set-nice <nice> |
|
||||
border routers based on some information from the request. See RFC 2474,
|
||||
2597, 3260 and 4594 for more information.
|
||||
|
||||
- "set-mark" is used to set the Netfilter MARK on all packets sent to the
|
||||
client to the value passed in <mark> on platforms which support it. This
|
||||
value is an unsigned 32 bit value which can be matched by netfilter and
|
||||
by the routing table. It can be expressed both in decimal or hexadecimal
|
||||
format (prefixed by "0x"). This can be useful to force certain packets to
|
||||
take a different route (for example a cheaper network path for bulk
|
||||
downloads). This works on Linux kernels 2.6.32 and above and requires
|
||||
admin privileges.
|
||||
|
||||
There is no limit to the number of http-response statements per instance.
|
||||
|
||||
It is important to know that http-reqsponse rules are processed very early in
|
||||
|
@ -249,6 +249,7 @@ enum {
|
||||
HTTP_REQ_ACT_SET_NICE,
|
||||
HTTP_REQ_ACT_SET_LOGL,
|
||||
HTTP_REQ_ACT_SET_TOS,
|
||||
HTTP_REQ_ACT_SET_MARK,
|
||||
HTTP_REQ_ACT_MAX /* must always be last */
|
||||
};
|
||||
|
||||
@ -262,6 +263,7 @@ enum {
|
||||
HTTP_RES_ACT_SET_NICE,
|
||||
HTTP_RES_ACT_SET_LOGL,
|
||||
HTTP_RES_ACT_SET_TOS,
|
||||
HTTP_RES_ACT_SET_MARK,
|
||||
HTTP_RES_ACT_MAX /* must always be last */
|
||||
};
|
||||
|
||||
@ -377,6 +379,7 @@ struct http_req_rule {
|
||||
int nice; /* nice value for HTTP_REQ_ACT_SET_NICE */
|
||||
int loglevel; /* log-level value for HTTP_REQ_ACT_SET_LOGL */
|
||||
int tos; /* tos value for HTTP_REQ_ACT_SET_TOS */
|
||||
int mark; /* nfmark value for HTTP_REQ_ACT_SET_MARK */
|
||||
} arg; /* arguments used by some actions */
|
||||
};
|
||||
|
||||
@ -393,6 +396,7 @@ struct http_res_rule {
|
||||
int nice; /* nice value for HTTP_RES_ACT_SET_NICE */
|
||||
int loglevel; /* log-level value for HTTP_RES_ACT_SET_LOGL */
|
||||
int tos; /* tos value for HTTP_RES_ACT_SET_TOS */
|
||||
int mark; /* nfmark value for HTTP_RES_ACT_SET_MARK */
|
||||
} arg; /* arguments used by some actions */
|
||||
};
|
||||
|
||||
|
@ -3218,6 +3218,12 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct session
|
||||
#endif
|
||||
break;
|
||||
|
||||
case HTTP_REQ_ACT_SET_MARK:
|
||||
#ifdef SO_MARK
|
||||
setsockopt(s->req->prod->conn->t.sock.fd, SOL_SOCKET, SO_MARK, &rule->arg.mark, sizeof(rule->arg.mark));
|
||||
#endif
|
||||
break;
|
||||
|
||||
case HTTP_REQ_ACT_SET_LOGL:
|
||||
s->logs.level = rule->arg.loglevel;
|
||||
break;
|
||||
@ -3298,6 +3304,12 @@ http_res_get_intercept_rule(struct proxy *px, struct list *rules, struct session
|
||||
#endif
|
||||
break;
|
||||
|
||||
case HTTP_RES_ACT_SET_MARK:
|
||||
#ifdef SO_MARK
|
||||
setsockopt(s->req->prod->conn->t.sock.fd, SOL_SOCKET, SO_MARK, &rule->arg.mark, sizeof(rule->arg.mark));
|
||||
#endif
|
||||
break;
|
||||
|
||||
case HTTP_RES_ACT_SET_LOGL:
|
||||
s->logs.level = rule->arg.loglevel;
|
||||
break;
|
||||
@ -8457,6 +8469,31 @@ struct http_req_rule *parse_http_req_cond(const char **args, const char *file, i
|
||||
#else
|
||||
Alert("parsing [%s:%d]: 'http-request %s' is not supported on this platform (IP_TOS undefined).\n", file, linenum, args[0]);
|
||||
goto out_err;
|
||||
#endif
|
||||
} else if (!strcmp(args[0], "set-mark")) {
|
||||
#ifdef SO_MARK
|
||||
char *err;
|
||||
rule->action = HTTP_REQ_ACT_SET_MARK;
|
||||
cur_arg = 1;
|
||||
|
||||
if (!*args[cur_arg] ||
|
||||
(*args[cur_arg + 1] && strcmp(args[cur_arg + 1], "if") != 0 && strcmp(args[cur_arg + 1], "unless") != 0)) {
|
||||
Alert("parsing [%s:%d]: 'http-request %s' expects exactly 1 argument (integer/hex value).\n",
|
||||
file, linenum, args[0]);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
rule->arg.mark = strtoul(args[cur_arg], &err, 0);
|
||||
if (err && *err != '\0') {
|
||||
Alert("parsing [%s:%d]: invalid character starting at '%s' in 'http-request %s' (integer/hex value expected).\n",
|
||||
file, linenum, err, args[0]);
|
||||
goto out_err;
|
||||
}
|
||||
cur_arg++;
|
||||
global.last_checks |= LSTCHK_NETADM;
|
||||
#else
|
||||
Alert("parsing [%s:%d]: 'http-request %s' is not supported on this platform (SO_MARK undefined).\n", file, linenum, args[0]);
|
||||
goto out_err;
|
||||
#endif
|
||||
} else if (!strcmp(args[0], "set-log-level")) {
|
||||
rule->action = HTTP_REQ_ACT_SET_LOGL;
|
||||
@ -8513,7 +8550,7 @@ struct http_req_rule *parse_http_req_cond(const char **args, const char *file, i
|
||||
cur_arg = 2;
|
||||
return rule;
|
||||
} else {
|
||||
Alert("parsing [%s:%d]: 'http-request' expects 'allow', 'deny', 'auth', 'redirect', 'tarpit', 'add-header', 'set-header', 'set-nice', 'set-tos', 'set-log-level', but got '%s'%s.\n",
|
||||
Alert("parsing [%s:%d]: 'http-request' expects 'allow', 'deny', 'auth', 'redirect', 'tarpit', 'add-header', 'set-header', 'set-nice', 'set-tos', 'set-mark', 'set-log-level', but got '%s'%s.\n",
|
||||
file, linenum, args[0], *args[0] ? "" : " (missing argument)");
|
||||
goto out_err;
|
||||
}
|
||||
@ -8600,6 +8637,31 @@ struct http_res_rule *parse_http_res_cond(const char **args, const char *file, i
|
||||
#else
|
||||
Alert("parsing [%s:%d]: 'http-response %s' is not supported on this platform (IP_TOS undefined).\n", file, linenum, args[0]);
|
||||
goto out_err;
|
||||
#endif
|
||||
} else if (!strcmp(args[0], "set-mark")) {
|
||||
#ifdef SO_MARK
|
||||
char *err;
|
||||
rule->action = HTTP_RES_ACT_SET_MARK;
|
||||
cur_arg = 1;
|
||||
|
||||
if (!*args[cur_arg] ||
|
||||
(*args[cur_arg + 1] && strcmp(args[cur_arg + 1], "if") != 0 && strcmp(args[cur_arg + 1], "unless") != 0)) {
|
||||
Alert("parsing [%s:%d]: 'http-response %s' expects exactly 1 argument (integer/hex value).\n",
|
||||
file, linenum, args[0]);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
rule->arg.mark = strtoul(args[cur_arg], &err, 0);
|
||||
if (err && *err != '\0') {
|
||||
Alert("parsing [%s:%d]: invalid character starting at '%s' in 'http-response %s' (integer/hex value expected).\n",
|
||||
file, linenum, err, args[0]);
|
||||
goto out_err;
|
||||
}
|
||||
cur_arg++;
|
||||
global.last_checks |= LSTCHK_NETADM;
|
||||
#else
|
||||
Alert("parsing [%s:%d]: 'http-response %s' is not supported on this platform (SO_MARK undefined).\n", file, linenum, args[0]);
|
||||
goto out_err;
|
||||
#endif
|
||||
} else if (!strcmp(args[0], "set-log-level")) {
|
||||
rule->action = HTTP_RES_ACT_SET_LOGL;
|
||||
@ -8637,7 +8699,7 @@ struct http_res_rule *parse_http_res_cond(const char **args, const char *file, i
|
||||
(proxy->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR);
|
||||
cur_arg += 2;
|
||||
} else {
|
||||
Alert("parsing [%s:%d]: 'http-response' expects 'allow', 'deny', 'redirect', 'add-header', 'set-header', 'set-nice', 'set-tos', 'set-log-level', but got '%s'%s.\n",
|
||||
Alert("parsing [%s:%d]: 'http-response' expects 'allow', 'deny', 'redirect', 'add-header', 'set-header', 'set-nice', 'set-tos', 'set-mark', 'set-log-level', but got '%s'%s.\n",
|
||||
file, linenum, args[0], *args[0] ? "" : " (missing argument)");
|
||||
goto out_err;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user