mirror of
https://github.com/OpenVPN/openvpn.git
synced 2026-05-28 04:03:29 -04:00
Don't "undo" ifconfig on exit if it wasn't done
When running with --ifconfig-noexec, OpenVPN does not execute ifconfig,
but on exit, it still tries to "undo" the configuration it would have
done. This patch fixes it by extracting an undo_ifconfig() function from
close_tun(). The undo function is called before close_tun(), but only if
--ifconfig-noexec isn't set. This is symmetric to how open_tun() and
do_ifconfig() are used.
v2: Fix tabs-vs-spaces.
v3: Fix another style mistake.
v4: Move undo_ifconfig{4,6}() out of #ifdef TARGET_LINUX.
v5: Keep ctx argument in close_tun().
v6: Fix bug in non-Linux non-Windows version of undo_ifconfig_ipv6
Signed-off-by: Max Fillinger <maximilian.fillinger@foxcrypto.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20220810153006.18860-1-maximilian.fillinger@foxcrypto.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24860.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
parent
ddbe6a6fc2
commit
0c4d40cb83
3 changed files with 94 additions and 76 deletions
|
|
@ -1920,6 +1920,10 @@ do_close_tun_simple(struct context *c)
|
|||
msg(D_CLOSE, "Closing TUN/TAP interface");
|
||||
if (c->c1.tuntap)
|
||||
{
|
||||
if (!c->options.ifconfig_noexec)
|
||||
{
|
||||
undo_ifconfig(c->c1.tuntap, &c->net_ctx);
|
||||
}
|
||||
close_tun(c->c1.tuntap, &c->net_ctx);
|
||||
c->c1.tuntap = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1604,6 +1604,88 @@ do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
|
|||
net_ctx_free(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
undo_ifconfig_ipv4(struct tuntap *tt, openvpn_net_ctx_t *ctx)
|
||||
{
|
||||
#if defined(TARGET_LINUX)
|
||||
int netbits = netmask_to_netbits2(tt->remote_netmask);
|
||||
|
||||
if (is_tun_p2p(tt))
|
||||
{
|
||||
if (net_addr_ptp_v4_del(ctx, tt->actual_name, &tt->local,
|
||||
&tt->remote_netmask) < 0)
|
||||
{
|
||||
msg(M_WARN, "Linux can't del IP from iface %s",
|
||||
tt->actual_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (net_addr_v4_del(ctx, tt->actual_name, &tt->local, netbits) < 0)
|
||||
{
|
||||
msg(M_WARN, "Linux can't del IP from iface %s",
|
||||
tt->actual_name);
|
||||
}
|
||||
}
|
||||
#elif !defined(_WIN32) /* if !defined(TARGET_LINUX) && !defined(_WIN32) */
|
||||
struct argv argv = argv_new();
|
||||
|
||||
argv_printf(&argv, "%s %s 0.0.0.0", IFCONFIG_PATH, tt->actual_name);
|
||||
|
||||
argv_msg(M_INFO, &argv);
|
||||
openvpn_execve_check(&argv, NULL, 0, "Generic ip addr del failed");
|
||||
|
||||
argv_free(&argv);
|
||||
#endif /* if defined(TARGET_LINUX) */
|
||||
/* Empty for _WIN32. */
|
||||
}
|
||||
|
||||
static void
|
||||
undo_ifconfig_ipv6(struct tuntap *tt, openvpn_net_ctx_t *ctx)
|
||||
{
|
||||
#if defined(TARGET_LINUX)
|
||||
if (net_addr_v6_del(ctx, tt->actual_name, &tt->local_ipv6,
|
||||
tt->netbits_ipv6) < 0)
|
||||
{
|
||||
msg(M_WARN, "Linux can't del IPv6 from iface %s", tt->actual_name);
|
||||
}
|
||||
#elif !defined(_WIN32) /* if !defined(TARGET_LINUX) && !defined(_WIN32) */
|
||||
struct gc_arena gc = gc_new();
|
||||
const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
|
||||
struct argv argv = argv_new();
|
||||
|
||||
argv_printf(&argv, "%s %s del %s/%d", IFCONFIG_PATH, tt->actual_name,
|
||||
ifconfig_ipv6_local, tt->netbits_ipv6);
|
||||
|
||||
argv_msg(M_INFO, &argv);
|
||||
openvpn_execve_check(&argv, NULL, 0, "Generic ip -6 addr del failed");
|
||||
|
||||
argv_free(&argv);
|
||||
gc_free(&gc);
|
||||
#endif /* if defined(TARGET_LINUX) */
|
||||
/* Empty for _WIN32. */
|
||||
}
|
||||
|
||||
void
|
||||
undo_ifconfig(struct tuntap *tt, openvpn_net_ctx_t *ctx)
|
||||
{
|
||||
if (tt->type != DEV_TYPE_NULL)
|
||||
{
|
||||
if (tt->did_ifconfig_setup)
|
||||
{
|
||||
undo_ifconfig_ipv4(tt, ctx);
|
||||
}
|
||||
|
||||
if (tt->did_ifconfig_ipv6_setup)
|
||||
{
|
||||
undo_ifconfig_ipv6(tt, ctx);
|
||||
}
|
||||
|
||||
/* release resources potentially allocated during undo */
|
||||
net_ctx_reset(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clear_tuntap(struct tuntap *tuntap)
|
||||
{
|
||||
|
|
@ -2213,87 +2295,11 @@ tuncfg(const char *dev, const char *dev_type, const char *dev_node,
|
|||
|
||||
#endif /* ENABLE_FEATURE_TUN_PERSIST */
|
||||
|
||||
static void
|
||||
undo_ifconfig_ipv4(struct tuntap *tt, openvpn_net_ctx_t *ctx)
|
||||
{
|
||||
#if defined(TARGET_LINUX)
|
||||
int netbits = netmask_to_netbits2(tt->remote_netmask);
|
||||
|
||||
if (is_tun_p2p(tt))
|
||||
{
|
||||
if (net_addr_ptp_v4_del(ctx, tt->actual_name, &tt->local,
|
||||
&tt->remote_netmask) < 0)
|
||||
{
|
||||
msg(M_WARN, "Linux can't del IP from iface %s",
|
||||
tt->actual_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (net_addr_v4_del(ctx, tt->actual_name, &tt->local, netbits) < 0)
|
||||
{
|
||||
msg(M_WARN, "Linux can't del IP from iface %s",
|
||||
tt->actual_name);
|
||||
}
|
||||
}
|
||||
#else /* ifndef TARGET_LINUX */
|
||||
struct argv argv = argv_new();
|
||||
|
||||
argv_printf(&argv, "%s %s 0.0.0.0", IFCONFIG_PATH, tt->actual_name);
|
||||
|
||||
argv_msg(M_INFO, &argv);
|
||||
openvpn_execve_check(&argv, NULL, 0, "Generic ip addr del failed");
|
||||
|
||||
argv_free(&argv);
|
||||
#endif /* ifdef TARGET_LINUX */
|
||||
}
|
||||
|
||||
static void
|
||||
undo_ifconfig_ipv6(struct tuntap *tt, openvpn_net_ctx_t *ctx)
|
||||
{
|
||||
#if defined(TARGET_LINUX)
|
||||
if (net_addr_v6_del(ctx, tt->actual_name, &tt->local_ipv6,
|
||||
tt->netbits_ipv6) < 0)
|
||||
{
|
||||
msg(M_WARN, "Linux can't del IPv6 from iface %s", tt->actual_name);
|
||||
}
|
||||
#else /* ifndef TARGET_LINUX */
|
||||
struct gc_arena gc = gc_new();
|
||||
const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, gc);
|
||||
struct argv argv = argv_new();
|
||||
|
||||
argv_printf(&argv, "%s %s del %s/%d", IFCONFIG_PATH, tt->actual_name,
|
||||
ifconfig_ipv6_local, tt->netbits_ipv6);
|
||||
|
||||
argv_msg(M_INFO, &argv);
|
||||
openvpn_execve_check(&argv, NULL, 0, "Linux ip -6 addr del failed");
|
||||
|
||||
argv_free(&argv);
|
||||
gc_free(&gc);
|
||||
#endif /* ifdef TARGET_LINUX */
|
||||
}
|
||||
|
||||
void
|
||||
close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
|
||||
{
|
||||
ASSERT(tt);
|
||||
|
||||
if (tt->type != DEV_TYPE_NULL)
|
||||
{
|
||||
if (tt->did_ifconfig_setup)
|
||||
{
|
||||
undo_ifconfig_ipv4(tt, ctx);
|
||||
}
|
||||
|
||||
if (tt->did_ifconfig_ipv6_setup)
|
||||
{
|
||||
undo_ifconfig_ipv6(tt, ctx);
|
||||
}
|
||||
|
||||
/* release resources potentially allocated during undo */
|
||||
net_ctx_reset(ctx);
|
||||
}
|
||||
|
||||
#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
|
||||
if (tun_dco_enabled(tt))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -314,6 +314,14 @@ void do_ifconfig_setenv(const struct tuntap *tt,
|
|||
void do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
|
||||
const struct env_set *es, openvpn_net_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* undo_ifconfig - undo configuration of the tunnel interface
|
||||
*
|
||||
* @param tt the tuntap interface context
|
||||
* @param ctx the networking API opaque context
|
||||
*/
|
||||
void undo_ifconfig(struct tuntap *tt, openvpn_net_ctx_t *ctx);
|
||||
|
||||
bool is_dev_type(const char *dev, const char *dev_type, const char *match_type);
|
||||
|
||||
int dev_type_enum(const char *dev, const char *dev_type);
|
||||
|
|
|
|||
Loading…
Reference in a new issue