Hi!
I have situation where i should pass different type of requests over
different routes (so they will go thru transparent proxy). I found
option for mark for client connections, but didn't found for backend
connections.
Interface option won't work here, since i need to put specific gateway
and to be able change in on fly (add additional routes for example or
firewall rules), so i did following patch(attached).
Please let me know if it is ok.
Configuration example:
Networking:
ip rule add fwmark 0x11 table 111
ip rule add fwmark 0x12 table 112
ip rule add fwmark 0x13 table 113
ip rule add fwmark 0x14 table 114
ip route add table 111 default via 10.0.253.129
ip route add table 112 default via 10.0.253.133
ip route add table 113 default via 10.0.253.137
ip route add table 114 default via 10.0.253.141
Part of haproxy config:
backend transparent-cache1
option transparent
option tcp-smart-connect
source 10.0.253.26 usesrc clientip set-mark 0x11
backend transparent-cache2
option transparent
option tcp-smart-connect
source 10.0.253.26 usesrc clientip set-mark 0x12
backend transparent-cache3
option transparent
option tcp-smart-connect
source 10.0.253.26 usesrc clientip set-mark 0x13
backend transparent-cache4
option transparent
option tcp-smart-connect
source 10.0.253.26 usesrc clientip set-mark 0x14
frontend http-in
bind :80 transparent
option tcp-smart-accept
default_backend transparent-cache1
acl all src 0.0.0.0/0
acl url_video hdr_dom(host) -i youtube.com googlevideo.com
acl url_xxx hdr_dom(host) -i test.com test2.com test3.com
acl url_downloads path_sub .exe .zip .flv .dmg .gz .tar .bin
.pdf .mp3 .msi .npk .iso .rar .cab .sft .ipsw .ipa .bz2 .ver .f4v .mp4
.wmv .mov .avi .wav .wma .psf .deb .swf
use_backend transparent-cache2 if url_video
use_backend transparent-cache3 if url_xxx
use_backend transparent-cache4 if url_downloads
use_backend transparent-cache1 if all
diff -Naur haproxy-1.5-dev21/include/types/connection.h haproxy-1.5-dev21-new/include/types/connection.h
--- haproxy-1.5-dev21/include/types/connection.h 2013-12-17 01:45:49.000000000 +0200
+++ haproxy-1.5-dev21-new/include/types/connection.h 2013-12-21 01:46:42.894200958 +0200
@@ -221,6 +221,7 @@
struct conn_src {
unsigned int opts; /* CO_SRC_* */
+ int mark; /* outgoing connection mark or zero */
int iface_len; /* bind interface name length */
char *iface_name; /* bind interface name or NULL */
struct port_range *sport_range; /* optional per-server TCP source ports */
diff -Naur haproxy-1.5-dev21/src/cfgparse.c haproxy-1.5-dev21-new/src/cfgparse.c
--- haproxy-1.5-dev21/src/cfgparse.c 2013-12-17 01:45:49.000000000 +0200
+++ haproxy-1.5-dev21-new/src/cfgparse.c 2013-12-21 01:52:12.820215506 +0200
@@ -5335,6 +5335,7 @@
free(curproxy->conn_src.iface_name);
curproxy->conn_src.iface_name = NULL;
curproxy->conn_src.iface_len = 0;
+ curproxy->conn_src.mark = 0;
sk = str2sa_range(args[1], &port1, &port2, &errmsg, NULL);
if (!sk) {
@@ -5489,6 +5490,33 @@
cur_arg += 2;
continue;
}
+ if (!strcmp(args[cur_arg], "set-mark")) { /* assign mark */
+#ifdef SO_MARK
+ char *err;
+ if (*(args[cur_arg + 1]) == 0) {
+ Alert("parsing [%s:%d] : '%s' : expects an integer argument.\n",
+ file, linenum, args[0]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ curproxy->conn_src.mark = (int) strtol(args[cur_arg + 1], &err, 0);
+ if (err && *err != '\0') {
+ Alert("parsing [%s:%d]: invalid character starting at '%s' in 'set-mark %s' (integer/hex value expected).\n",
+ file, linenum, err, args[0]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+ }
+ global.last_checks |= LSTCHK_NETADM;
+#else
+ Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n",
+ file, linenum, args[0], args[cur_arg]);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ goto out;
+#endif
+ cur_arg += 2;
+ continue;
+ }
+
Alert("parsing [%s:%d] : '%s' only supports optional keywords '%s' and '%s'.\n",
file, linenum, args[0], "interface", "usesrc");
err_code |= ERR_ALERT | ERR_FATAL;
diff -Naur haproxy-1.5-dev21/src/proto_tcp.c haproxy-1.5-dev21-new/src/proto_tcp.c
--- haproxy-1.5-dev21/src/proto_tcp.c 2013-12-17 01:45:49.000000000 +0200
+++ haproxy-1.5-dev21-new/src/proto_tcp.c 2013-12-21 01:16:48.210121822 +0200
@@ -363,6 +363,11 @@
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, src->iface_name, src->iface_len + 1);
#endif
+#ifdef SO_MARK
+ if (src->mark)
+ setsockopt(fd, SOL_SOCKET, SO_MARK, &src->mark, sizeof(src->mark));
+#endif
+
if (src->sport_range) {
int attempts = 10; /* should be more than enough to find a spare port */
struct sockaddr_storage sa;