Push-remove (introduced in commit 970312f1850) did not handle "ifconfig"
yet, as both "ifconfig" and "ifconfig-ipv6" are handled differently from
all other pushed options. Since there was no valid use-case to not-push
"ifconfig" (no support on the client side for running IPv6-only) this
was not an issue so far - but with the recent commits to enable ipv6-only
operation it can be a desirable feature.
The implementation is similar to "push-remove ifconfig-ipv6" - namely,
flagging via a new context option (c->options.push_ifconfig_ipv4_blocked)
and then not creating the push statement in "send_push_reply()".
While not truly elegant, it's much less invasive than the alternatives
(storing the list of "push-remove" statements somewhere and then checking
in push_option_ex())
Trac: #1072
Signed-off-by: Gert Doering <gert@greenie.muc.de>
Acked-by: Antonio Quartulli <antonio@openvpn.net>
Message-Id: <20180701195938.2541-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg17169.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -3045,6 +3045,11 @@ an option, |
3045 | 3045 |
can be used to first remove the old value, and then add a new |
3046 | 3046 |
.B \-\-push |
3047 | 3047 |
option with the new value. |
3048 |
+ |
|
3049 |
+NOTE2: due to implementation details, 'ifconfig' and 'ifconfig-ipv6' |
|
3050 |
+can only be removed with an exact match on the option ("push-remove ifconfig"), |
|
3051 |
+no substring matching and no matching on the IPv4/IPv6 address argument |
|
3052 |
+is possible. |
|
3048 | 3053 |
.\"********************************************************* |
3049 | 3054 |
.TP |
3050 | 3055 |
.B \-\-push\-peer\-info |
... | ... |
@@ -425,6 +425,7 @@ struct options |
425 | 425 |
bool push_ifconfig_constraint_defined; |
426 | 426 |
in_addr_t push_ifconfig_constraint_network; |
427 | 427 |
in_addr_t push_ifconfig_constraint_netmask; |
428 |
+ bool push_ifconfig_ipv4_blocked; /* IPv4 */ |
|
428 | 429 |
bool push_ifconfig_ipv6_defined; /* IPv6 */ |
429 | 430 |
struct in6_addr push_ifconfig_ipv6_local; /* IPv6 */ |
430 | 431 |
int push_ifconfig_ipv6_netbits; /* IPv6 */ |
... | ... |
@@ -342,7 +342,8 @@ prepare_push_reply(struct context *c, struct gc_arena *gc, |
342 | 342 |
|
343 | 343 |
/* ipv4 */ |
344 | 344 |
if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local |
345 |
- && c->c2.push_ifconfig_remote_netmask) |
|
345 |
+ && c->c2.push_ifconfig_remote_netmask |
|
346 |
+ && !o->push_ifconfig_ipv4_blocked) |
|
346 | 347 |
{ |
347 | 348 |
in_addr_t ifconfig_local = c->c2.push_ifconfig_local; |
348 | 349 |
if (c->c2.push_ifconfig_local_alias) |
... | ... |
@@ -602,6 +603,13 @@ push_remove_option(struct options *o, const char *p) |
602 | 602 |
{ |
603 | 603 |
msg(D_PUSH_DEBUG, "PUSH_REMOVE searching for: '%s'", p); |
604 | 604 |
|
605 |
+ /* ifconfig is special, as not part of the push list */ |
|
606 |
+ if (streq(p, "ifconfig")) |
|
607 |
+ { |
|
608 |
+ o->push_ifconfig_ipv4_blocked = true; |
|
609 |
+ return; |
|
610 |
+ } |
|
611 |
+ |
|
605 | 612 |
/* ifconfig-ipv6 is special, as not part of the push list */ |
606 | 613 |
if (streq( p, "ifconfig-ipv6" )) |
607 | 614 |
{ |