From: David du Colombier Date: Fri, 13 Jul 2012 12:34:59 +0000 (+0200) Subject: MINOR: IPv6 support for transparent proxy X-Git-Tag: v1.5-dev12~135 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=65c1796c4aeb54fc10430ba89f15141702f42eee;p=thirdparty%2Fhaproxy.git MINOR: IPv6 support for transparent proxy Set socket option IPV6_TRANSPARENT on binding to enable transparent proxy on IPv6. This option is available from Linux 2.6.37. --- diff --git a/include/common/compat.h b/include/common/compat.h index 80e1dd2936..c4ac08cf6c 100644 --- a/include/common/compat.h +++ b/include/common/compat.h @@ -88,6 +88,9 @@ #if !defined(IP_TRANSPARENT) #define IP_TRANSPARENT 19 #endif /* !IP_TRANSPARENT */ +#if !defined(IPV6_TRANSPARENT) +#define IPV6_TRANSPARENT 75 +#endif /* !IPV6_TRANSPARENT */ #endif /* CONFIG_HAP_LINUX_TPROXY */ /* We'll try to enable SO_REUSEPORT on Linux 2.4 and 2.6 if not defined. diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 59b8bc555a..1d38b3caa6 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -128,12 +128,25 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so #ifdef CONFIG_HAP_LINUX_TPROXY static int ip_transp_working = 1; - if (flags && ip_transp_working) { - if (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == 0 - || setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0) - foreign_ok = 1; - else - ip_transp_working = 0; + static int ip6_transp_working = 1; + switch (local->ss_family) { + case AF_INET: + if (flags && ip_transp_working) { + if (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == 0 + || setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0) + foreign_ok = 1; + else + ip_transp_working = 0; + } + break; + case AF_INET6: + if (flags && ip6_transp_working) { + if (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == 0) + foreign_ok = 1; + else + ip6_transp_working = 0; + } + break; } #endif if (flags) { @@ -736,11 +749,22 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen) setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)); #endif #ifdef CONFIG_HAP_LINUX_TPROXY - if ((listener->options & LI_O_FOREIGN) - && (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == -1) - && (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == -1)) { - msg = "cannot make listening socket transparent"; - err |= ERR_ALERT; + if (listener->options & LI_O_FOREIGN) { + switch (listener->addr.ss_family) { + case AF_INET: + if ((setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == -1) + && (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == -1)) { + msg = "cannot make listening socket transparent"; + err |= ERR_ALERT; + } + break; + case AF_INET6: + if (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == -1) { + msg = "cannot make listening socket transparent"; + err |= ERR_ALERT; + } + break; + } } #endif #ifdef SO_BINDTODEVICE