diff --git a/doc/man-sections/server-options.rst b/doc/man-sections/server-options.rst index fe0e6a96..c0b22a53 100644 --- a/doc/man-sections/server-options.rst +++ b/doc/man-sections/server-options.rst @@ -204,7 +204,8 @@ fast hardware. SSL/TLS authentication must be used in this mode. ifconfig-ipv6-pool ipv6addr/bits The pool starts at ``ipv6addr`` and matches the offset determined from - the start of the IPv4 pool. + the start of the IPv4 pool. If the host part of the given IPv6 + address is ``0``, the pool starts at ``ipv6addr`` +1. --ifconfig-pool-persist args Persist/unpersist ifconfig-pool data to ``file``, at ``seconds`` diff --git a/src/openvpn/pool.c b/src/openvpn/pool.c index 1f74ac57..ece0784f 100644 --- a/src/openvpn/pool.c +++ b/src/openvpn/pool.c @@ -224,6 +224,24 @@ ifconfig_pool_init(const bool ipv4_pool, enum pool_type type, in_addr_t start, } pool->ipv6.base = ipv6_base; + + /* if a pool starts at a base address that has all-zero in the + * host part, that first IPv6 address must not be assigned to + * clients because it is not usable (subnet anycast address). + * Start with 1, then. + * + * NOTE: this will also (mis-)fire for something like + * ifconfig-ipv6-pool 2001:db8:0:1:1234::0/64 + * as we only check the rightmost 32 bits of the host part. So be it. + */ + if (base == 0) + { + msg(D_IFCONFIG_POOL, "IFCONFIG POOL IPv6: incrementing pool start " + "to avoid ::0 assignment"); + base++; + pool->ipv6.base.s6_addr[15]++; + } + pool_ipv6_size = ipv6_netbits >= 112 ? (1 << (128 - ipv6_netbits)) - base : IFCONFIG_POOL_MAX;