]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tcp: add support for the "v4v6" bind option
authorWilly Tarreau <w@1wt.eu>
Sat, 24 Nov 2012 14:07:23 +0000 (15:07 +0100)
committerWilly Tarreau <w@1wt.eu>
Sat, 24 Nov 2012 14:07:23 +0000 (15:07 +0100)
Commit 9b6700f added "v6only". As suggested by Vincent Bernat, it is
sometimes useful to have the opposite option to force binding to the
two protocols when the system is configured to bind to v6 only by
default. This option does exactly this. v6only still has precedence.

doc/configuration.txt
include/types/listener.h
src/proto_tcp.c

index aa2121289b659728d57283f8e98bc3f2411fa7c2..223d479b796f53bdc7b7673e8edc5933c62156dc 100644 (file)
@@ -7156,11 +7156,19 @@ transparent
   kernel version. Some distribution kernels include backports of the feature,
   so check for support with your vendor.
 
+v4v6
+  Is an optional keyword which is supported only on most recent systems
+  including Linux kernels >= 2.4.21. It is used to bind a socket to both IPv4
+  and IPv6 when it uses the default address. Doing so is sometimes necessary
+  on systems which bind to IPv6 only by default. It has no effect on non-IPv6
+  sockets, and is overriden by the "v6only" option.
+
 v6only
   Is an optional keyword which is supported only on most recent systems
   including Linux kernels >= 2.4.21. It is used to bind a socket to IPv6 only
   when it uses the default address. Doing so is sometimes preferred to doing it
-  system-wide as it is per-listener. It has no effect on non-IPv6 sockets.
+  system-wide as it is per-listener. It has no effect on non-IPv6 sockets and
+  has precedence over the "v4v6" option.
 
 uid <uid>
   Sets the owner of the UNIX sockets to the designated system uid. It can also
index 0bdde76b7b6b624d546db3f3b58751dc705d3f2f..d5d91f43f8722875fc16943732f6c89e9e605f0b 100644 (file)
@@ -91,6 +91,7 @@ enum {
 #define LI_O_UNLIMITED  0x0080  /* listener not subject to global limits (peers & stats socket) */
 #define LI_O_TCP_FO     0x0100  /* enable TCP Fast Open (linux >= 3.6) */
 #define LI_O_V6ONLY     0x0200  /* bind to IPv6 only on Linux >= 2.4.21 */
+#define LI_O_V4V6       0x0400  /* bind to IPv4/IPv6 on Linux >= 2.4.21 */
 
 /* Note: if a listener uses LI_O_UNLIMITED, it is highly recommended that it adds its own
  * maxconn setting to the global.maxsock value so that its resources are reserved.
index 86073a41fef4132fc165e829521529af3b672e6f..551603677af887431b14467038b09db2061f69f9 100644 (file)
@@ -703,6 +703,8 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
 #if defined(IPV6_V6ONLY)
        if (listener->options & LI_O_V6ONLY)
                 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
+       else if (listener->options & LI_O_V4V6)
+                setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero));
 #endif
 
        if (bind(fd, (struct sockaddr *)&listener->addr, listener->proto->sock_addrlen) == -1) {
@@ -1727,6 +1729,19 @@ static int val_payload_lv(struct arg *arg, char **err_msg)
 }
 
 #ifdef IPV6_V6ONLY
+/* parse the "v4v6" bind keyword */
+static int bind_parse_v4v6(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
+{
+       struct listener *l;
+
+       list_for_each_entry(l, &conf->listeners, by_bind) {
+               if (l->addr.ss_family == AF_INET6)
+                       l->options |= LI_O_V4V6;
+       }
+
+       return 0;
+}
+
 /* parse the "v6only" bind keyword */
 static int bind_parse_v6only(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
 {
@@ -1899,6 +1914,7 @@ static struct bind_kw_list bind_kws = { "TCP", { }, {
        { "transparent",   bind_parse_transparent,  0 }, /* transparently bind to the specified addresses */
 #endif
 #ifdef IPV6_V6ONLY
+       { "v4v6",          bind_parse_v4v6,         0 }, /* force socket to bind to IPv4+IPv6 */
        { "v6only",        bind_parse_v6only,       0 }, /* force socket to bind to IPv6 only */
 #endif
        /* the versions with the NULL parse function*/
@@ -1906,6 +1922,7 @@ static struct bind_kw_list bind_kws = { "TCP", { }, {
        { "interface",     NULL,  1 },
        { "mss",           NULL,  1 },
        { "transparent",   NULL,  0 },
+       { "v4v6",          NULL,  0 },
        { "v6only",        NULL,  0 },
        { NULL, NULL, 0 },
 }};