Attention is currently required from: plaisthos.
Hello plaisthos,
I'd like you to reexamine a change. Please visit
http://gerrit.openvpn.net/c/openvpn/+/1786?usp=email
to look at the new patch set (#2).
Change subject: multi: assign IPv6 addresses from a tagged subnet-pool
......................................................................
multi: assign IPv6 addresses from a tagged subnet-pool
Add the IPv6 counterpart of --subnet-pool:
subnet-pool-ipv6 <tag> <network>/<bits> [<gateway>] (main config)
selected by the same per-client --subnet-pool-tag. A client's tag is
resolved against the IPv6 pool list too and, when it matches, an IPv6
address is handed out from the group's pool alongside any IPv4 one (a
single dual-stack ifconfig_pool per tag). A tag matching neither family
is still declined with AUTH_FAILED.
Change-Id: I64e0850d48647a2c0e3d385c2f20a9f445931727
GitHub: closes openvpn/OpenVPN#987
Signed-off-by: Antonio Quartulli <[email protected]>
---
M doc/man-sections/server-options.rst
M src/openvpn/multi.c
M src/openvpn/options.c
M src/openvpn/options.h
M src/openvpn/options_util.c
M src/openvpn/options_util.h
6 files changed, 138 insertions(+), 25 deletions(-)
git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/86/1786/2
diff --git a/doc/man-sections/server-options.rst
b/doc/man-sections/server-options.rst
index 8800b98..cf92905 100644
--- a/doc/man-sections/server-options.rst
+++ b/doc/man-sections/server-options.rst
@@ -349,11 +349,24 @@
``--route-gateway`` inside the subnet, and a host route back to the server's
VPN IP, so it is reachable without manual per-client route pushes.
+--subnet-pool-ipv6 args
+ The IPv6 counterpart of ``--subnet-pool``. Repeatable main-config directive.
+
+ Valid syntax:
+ ::
+
+ subnet-pool-ipv6 tag network/bits [gateway]
+
+ ``bits`` must be between 64 and 124; ``gateway`` defaults to the first
+ address of the network. A tag may name an IPv4 pool, an IPv6 pool, or both;
+ a client referencing it with ``--subnet-pool-tag`` is then assigned an
+ address from each family the tag defines.
+
--subnet-pool-tag tag
- Assign this client to the ``--subnet-pool`` named ``tag``. Must be
- associated with a specific client instance via ``--client-config-dir`` or
- ``--client-connect``. Several clients may reference the same tag and are
- then served from the same shared pool.
+ Assign this client to the ``--subnet-pool`` / ``--subnet-pool-ipv6`` named
+ ``tag``. Must be associated with a specific client instance via
+ ``--client-config-dir`` or ``--client-connect``. Several clients may
+ reference the same tag and are then served from the same shared pool(s).
--ifconfig-ipv6-push args
for ``--client-config-dir`` per-client static IPv6 interface
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index da46cf4..1cd84b6 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -1438,11 +1438,14 @@
}
const struct subnet_pool_def *d4 =
subnet_pool_by_tag(m->top.options.subnet_pools, tag);
+ const struct subnet_pool6_def *d6 =
subnet_pool6_by_tag(m->top.options.subnet_pools_ipv6, tag);
ALLOC_OBJ_CLEAR(sp, struct subnet_pool);
- sp->tag = d4->tag;
- sp->pool = ifconfig_pool_init(true, IFCONFIG_POOL_INDIV, d4->network + 2,
- (d4->network | ~d4->netmask) - 1,
m->top.options.duplicate_cn,
- false, in6addr_any, 0);
+ sp->tag = d4 ? d4->tag : d6->tag;
+ sp->pool = ifconfig_pool_init(d4 != NULL, IFCONFIG_POOL_INDIV, d4 ?
d4->network + 2 : 0,
+ d4 ? (d4->network | ~d4->netmask) - 1 : 0,
+ m->top.options.duplicate_cn, d6 != NULL,
+ d6 ? add_in6_addr(d6->network, 2) :
in6addr_any,
+ d6 ? (int)d6->netbits : 0);
sp->next = m->subnet_pools;
m->subnet_pools = sp;
return sp->pool;
@@ -1472,6 +1475,18 @@
mi->context.options.subnet_pool_gateway = d->gateway;
}
}
+ if (mi->context.options.subnet_pool_tag &&
!mi->context.options.subnet_pool_ipv6_defined)
+ {
+ const struct subnet_pool6_def *d = subnet_pool6_by_tag(
+ m->top.options.subnet_pools_ipv6,
mi->context.options.subnet_pool_tag);
+ if (d)
+ {
+ mi->context.options.subnet_pool_ipv6_defined = true;
+ mi->context.options.subnet_pool_ipv6_network = d->network;
+ mi->context.options.subnet_pool_ipv6_netbits = d->netbits;
+ mi->context.options.subnet_pool_ipv6_gateway = d->gateway;
+ }
+ }
/*
* If ifconfig addresses were set by dynamic config file,
@@ -1506,42 +1521,60 @@
"MULTI_sva: WARNING: if --ifconfig-push is used for IPv4,
automatic IPv6 assignment from --ifconfig-ipv6-pool does not work. Use
--ifconfig-ipv6-push for IPv6 then.");
}
}
- else if (mi->context.options.subnet_pool_defined)
+ else if (mi->context.options.subnet_pool_tag)
{
- /* dynamic address from this client's --subnet-pool group */
+ /* dynamic address(es) from this client's --subnet-pool group */
/* the CCD is read after a global-pool address may already have been
- * acquired; drop it so we can serve this client from its group */
+ * acquired; drop it so we serve this client from its group only */
if (mi->vaddr_handle >= 0 && !mi->vaddr_pool)
{
ifconfig_pool_release(m->ifconfig_pool, mi->vaddr_handle, true);
mi->vaddr_handle = -1;
+ mi->context.c2.push_ifconfig_defined = false;
+ mi->context.c2.push_ifconfig_ipv6_defined = false;
}
- if (mi->vaddr_handle < 0)
+ if ((mi->context.options.subnet_pool_defined
+ || mi->context.options.subnet_pool_ipv6_defined)
+ && mi->vaddr_handle < 0)
{
in_addr_t local = 0, remote = 0;
+ struct in6_addr remote_ipv6;
const char *cn = NULL;
+ CLEAR(remote_ipv6);
if (!mi->context.options.duplicate_cn)
{
cn = tls_common_name(mi->context.c2.tls_multi, true);
}
mi->vaddr_pool = multi_get_group_pool(m,
mi->context.options.subnet_pool_tag);
- mi->vaddr_handle = ifconfig_pool_acquire(mi->vaddr_pool, &local,
&remote, NULL, cn);
- if (mi->vaddr_handle >= 0)
- {
- mi->context.c2.push_ifconfig_local = remote;
- mi->context.c2.push_ifconfig_remote_netmask =
- mi->context.options.subnet_pool_netmask;
- mi->context.c2.push_ifconfig_defined = true;
- }
- else
+ mi->vaddr_handle =
+ ifconfig_pool_acquire(mi->vaddr_pool, &local, &remote,
&remote_ipv6, cn);
+ if (mi->vaddr_handle < 0)
{
msg(D_MULTI_ERRORS, "MULTI: no free --subnet-pool addresses
are available for %s",
multi_instance_string(mi, false, &gc));
}
+ else
+ {
+ if (mi->context.options.subnet_pool_defined)
+ {
+ mi->context.c2.push_ifconfig_local = remote;
+ mi->context.c2.push_ifconfig_remote_netmask =
+ mi->context.options.subnet_pool_netmask;
+ mi->context.c2.push_ifconfig_defined = true;
+ }
+ if (mi->context.options.subnet_pool_ipv6_defined)
+ {
+ mi->context.c2.push_ifconfig_ipv6_local = remote_ipv6;
+ mi->context.c2.push_ifconfig_ipv6_remote =
mi->context.c1.tuntap->local_ipv6;
+ mi->context.c2.push_ifconfig_ipv6_netbits =
+ mi->context.options.subnet_pool_ipv6_netbits;
+ mi->context.c2.push_ifconfig_ipv6_defined = true;
+ }
+ }
}
}
else if (m->ifconfig_pool && mi->vaddr_handle < 0) /* otherwise, choose a
pool address */
@@ -2852,7 +2885,9 @@
}
if (mi->context.options.subnet_pool_tag
- && !subnet_pool_by_tag(m->top.options.subnet_pools,
mi->context.options.subnet_pool_tag))
+ && !subnet_pool_by_tag(m->top.options.subnet_pools,
mi->context.options.subnet_pool_tag)
+ && !subnet_pool6_by_tag(m->top.options.subnet_pools_ipv6,
+ mi->context.options.subnet_pool_tag))
{
msg(D_MULTI_ERRORS, "MULTI: client has been rejected due to unknown
--subnet-pool-tag '%s'",
mi->context.options.subnet_pool_tag);
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 3f9f7de..b4485ca 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -446,6 +446,8 @@
"--subnet-pool tag network netmask [gateway] : Define a named pool of\n"
" addresses outside the --server network, selected per\n"
" client with --subnet-pool-tag.\n"
+ "--subnet-pool-ipv6 tag network/bits [gateway] : IPv6 counterpart of\n"
+ " --subnet-pool.\n"
"--subnet-pool-tag tag : Assign this client to the --subnet-pool named
tag.\n"
" Only valid in a client-specific config file.\n"
"--ifconfig-push local remote-netmask : Push an ifconfig option to
remote,\n"
@@ -7658,6 +7660,37 @@
sp->next = options->subnet_pools;
options->subnet_pools = sp;
}
+ else if (streq(p[0], "subnet-pool-ipv6") && p[1] && p[2] && !p[4])
+ {
+ struct subnet_pool6_def *sp;
+ struct in6_addr network, gateway;
+ unsigned int netbits = 0;
+
+ VERIFY_PERMISSION(OPT_P_GENERAL);
+ if (!get_ipv6_addr(p[2], &network, &netbits, msglevel))
+ {
+ msg(msglevel, "cannot parse --subnet-pool-ipv6 network");
+ goto err;
+ }
+ if (netbits < 64 || netbits > 124)
+ {
+ msg(msglevel, "--subnet-pool-ipv6 network must be between /64 and
/124 (not /%d)",
+ netbits);
+ goto err;
+ }
+ if (p[3] && !get_ipv6_addr(p[3], &gateway, NULL, msglevel))
+ {
+ msg(msglevel, "cannot parse --subnet-pool-ipv6 gateway");
+ goto err;
+ }
+ ALLOC_OBJ_GC(sp, struct subnet_pool6_def, &options->gc);
+ sp->tag = p[1];
+ sp->network = network;
+ sp->netbits = netbits;
+ sp->gateway = p[3] ? gateway : add_in6_addr(network, 1);
+ sp->next = options->subnet_pools_ipv6;
+ options->subnet_pools_ipv6 = sp;
+ }
else if (streq(p[0], "subnet-pool-tag") && p[1] && !p[2])
{
VERIFY_PERMISSION(OPT_P_INSTANCE);
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index 0c810b3..7f0e3ce 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -261,6 +261,16 @@
in_addr_t gateway;
};
+/* The IPv6 counterpart of struct subnet_pool_def (--subnet-pool-ipv6). */
+struct subnet_pool6_def
+{
+ struct subnet_pool6_def *next;
+ const char *tag;
+ struct in6_addr network;
+ unsigned int netbits;
+ struct in6_addr gateway;
+};
+
/* Command line options */
struct options
{
@@ -526,12 +536,17 @@
bool push_ifconfig_constraint_defined;
in_addr_t push_ifconfig_constraint_network;
in_addr_t push_ifconfig_constraint_netmask;
- struct subnet_pool_def *subnet_pools; /* named pools (server config) */
- const char *subnet_pool_tag; /* which pool this client uses (CCD)
*/
- bool subnet_pool_defined; /* resolved from the tag at connect
*/
+ struct subnet_pool_def *subnet_pools; /* named IPv4 pools (server
config) */
+ struct subnet_pool6_def *subnet_pools_ipv6; /* named IPv6 pools (server
config) */
+ const char *subnet_pool_tag; /* which pool this client uses
(CCD) */
+ bool subnet_pool_defined; /* resolved from the tag at
connect */
in_addr_t subnet_pool_network;
in_addr_t subnet_pool_netmask;
in_addr_t subnet_pool_gateway;
+ bool subnet_pool_ipv6_defined; /* resolved from the tag at connect */
+ struct in6_addr subnet_pool_ipv6_network;
+ unsigned int subnet_pool_ipv6_netbits;
+ struct in6_addr subnet_pool_ipv6_gateway;
bool push_ifconfig_ipv4_blocked; /* IPv4 */
bool push_ifconfig_ipv6_defined; /* IPv6 */
struct in6_addr push_ifconfig_ipv6_local; /* IPv6 */
diff --git a/src/openvpn/options_util.c b/src/openvpn/options_util.c
index ba04917..7826458 100644
--- a/src/openvpn/options_util.c
+++ b/src/openvpn/options_util.c
@@ -44,6 +44,19 @@
return NULL;
}
+const struct subnet_pool6_def *
+subnet_pool6_by_tag(const struct subnet_pool6_def *pools, const char *tag)
+{
+ for (const struct subnet_pool6_def *d = pools; d; d = d->next)
+ {
+ if (!strcmp(d->tag, tag))
+ {
+ return d;
+ }
+ }
+ return NULL;
+}
+
const char *
parse_auth_failed_temp(struct options *o, const char *reason)
{
diff --git a/src/openvpn/options_util.h b/src/openvpn/options_util.h
index c54357c..ed2017a 100644
--- a/src/openvpn/options_util.h
+++ b/src/openvpn/options_util.h
@@ -38,6 +38,10 @@
const struct subnet_pool_def *subnet_pool_by_tag(const struct subnet_pool_def
*pools,
const char *tag);
+/** IPv6 counterpart of subnet_pool_by_tag(). */
+const struct subnet_pool6_def *subnet_pool6_by_tag(const struct
subnet_pool6_def *pools,
+ const char *tag);
+
/** Checks if the string is a valid integer by checking if it can be
* converted to an integer */
--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/1786?usp=email
To unsubscribe, or for help writing mail filters, visit
http://gerrit.openvpn.net/settings?usp=email
Gerrit-MessageType: newpatchset
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I64e0850d48647a2c0e3d385c2f20a9f445931727
Gerrit-Change-Number: 1786
Gerrit-PatchSet: 2
Gerrit-Owner: ordex <[email protected]>
Gerrit-Reviewer: plaisthos <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: plaisthos <[email protected]>
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel