Skip to contentSkip to conversation

Allow IPv6-only tunnels

PATCH Superseded Antonio Quartulli 4 participants 45 messages Jun 8, 2018 – Jun 24, 2018

lore
Share & tools
lore
#0 lore raw

v2 cover Allow IPv6-only tunnels

This patchset allows clients and servers to work with a tunnel configured with IPv6 only.

Patch 3 is a mere cosmetic change and could be merged regardless of the rest.

With this change a server can be configured by using only the '--server-ipv6' directive.
This will result in clients receiving only 'ifconfig-ipv6' setting in their push-reply (and no IPv4 at all).

Differences from v1:
- more windows logic has been added to ensure client is properly started and configured with IPv6 only;
- warning messages added when trying to add IPv4 routes (even when redirect-gateway without !ipv4 is specified). Note: the behaviour of redirect-gateway has not been touched, therefore the "ipv6" flag is still required, even if only IPv6 are configured on the interfaces;
- redirect-gateway is prevented from adding a bypass route if no IPv4 redirection is taking place;
- added support for --ifconfig-pool-persist when only IPv6 is configured
- added do_ifconfig_ipv4() in do_ifconfig() to make code symmetric wrt IPv6;
- I may have forgotten some other little details..

(Note: this code is also available at [1] in the ipv6-only branch)

Cheers,

Trac: #208
[1] https://gitlab.com/ordex986/openvpn

Antonio Quartulli (8):
tun: ensure interface can be configured with IPv6 only
windows: properly configure TAP driver when no IPv4 is configured
pool: convert pool 'type' to enum
pool: allow to configure an IPv6-only ifconfig-pool make server capable of starting with an IPv6-only tunnel
pool: add support for ifconfig-pool-persist with IPv6 only
route: warn on IPv4 routes installation when no IPv4 is configured
options: enable IPv4 redirection logic only if really required

 src/openvpn/forward.c |    4 +-
 src/openvpn/helper.c  |    8 +-
 src/openvpn/multi.c   |   10 +-
 src/openvpn/options.c |   16 +-
 src/openvpn/pool.c    |  259 +++++++---
 src/openvpn/pool.h    |   17 +-
 src/openvpn/route.c   |   14 +-
 src/openvpn/tun.c     | 1142 ++++++++++++++++++-----------------------
 src/openvpn/tun.h     |   12 +-
 9 files changed, 754 insertions(+), 728 deletions(-)
Signature · 1 line
2.17.1
#1 lore raw

PATCH v2 1/8 tun: ensure interface can be configured with IPv6 only

From: Antonio Quartulli <[email protected]...>

This change ensures that an interface is properly brought up even when only IPv6 settings are configured/pushed.

Trac: #208

---
 src/openvpn/tun.c | 1118 ++++++++++++++++++++-------------------------
 src/openvpn/tun.h |   12 +-
 2 files changed, 492 insertions(+), 638 deletions(-)
src/openvpn/tun.c +483 -635
index 263cacdf..8509d489 100644
@@ -871,724 +871,572 @@ create_arbitrary_remote( struct tuntap *tt )
 }
 #endif
 
-/* execute the ifconfig command through the shell */
-void
-do_ifconfig(struct tuntap *tt,
-            const char *actual,     /* actual device name */
-            int tun_mtu,
-            const struct env_set *es)
+/**
+ * do_ifconfig_ipv6 - perform platform specific ifconfig6 commands
+ *
+ * @param tt        the tuntap interface context
+ * @param ifname    the human readable interface name
+ * @param mtu       the MTU value to set the interface to
+ * @param es        the environment to be used when executing the commands
+ */
+static void
+do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
+                 const struct env_set *es)
 {
+    const char *ifconfig_ipv6_local = NULL;
+    struct argv argv = argv_new();
     struct gc_arena gc = gc_new();
 
-    if (tt->did_ifconfig_setup)
-    {
-        bool tun = false;
-        const char *ifconfig_local = NULL;
-        const char *ifconfig_remote_netmask = NULL;
-        const char *ifconfig_broadcast = NULL;
-        const char *ifconfig_ipv6_local = NULL;
-        bool do_ipv6 = false;
-        struct argv argv = argv_new();
+    ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
 
-        msg( M_DEBUG, "do_ifconfig, tt->did_ifconfig_ipv6_setup=%d",
-             tt->did_ifconfig_ipv6_setup );
+#if defined(TARGET_LINUX)
+#ifdef ENABLE_IPROUTE
+    /* set the MTU for the device and bring it up */
+    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
+                tun_mtu);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
 
-        /*
-         * We only handle TUN/TAP devices here, not --dev null devices.
-         */
-        tun = is_tun_p2p(tt);
+    argv_printf(&argv, "%s -6 addr add %s/%d dev %s", iproute_path,
+                ifconfig_ipv6_local, tt->netbits_ipv6, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip -6 addr add failed");
+#else
+    argv_printf(&argv, "%s %s add %s/%d mtu %d up", IFCONFIG_PATH, ifname,
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
+#endif
+#elif defined(TARGET_ANDROID)
+    char out6[64];
 
-        /*
-         * Set ifconfig parameters
-         */
-        ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
-        ifconfig_remote_netmask = print_in_addr_t(tt->remote_netmask, 0, &gc);
+    openvpn_snprintf(out6, sizeof(out6), "%s/%d",
+                     ifconfig_ipv6_local,tt->netbits_ipv6);
+    management_android_control(management, "IFCONFIG6", out6);
+#elif defined(TARGET_SOLARIS)
+    argv_printf(&argv, "%s %s inet6 unplumb", IFCONFIG_PATH, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, 0, NULL);
 
-        if (tt->did_ifconfig_ipv6_setup)
+    if (tt->type == DEV_TYPE_TUN)
+    {
+        const char *ifconfig_ipv6_remote = print_in6_addr(tt->remote_ipv6, 0,
+                                                          gc);
+
+        argv_printf(&argv, "%s %s inet6 plumb %s/%d %s mtu %d up",
+                    IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
+                    tt->netbits_ipv6, ifconfig_ipv6_remote, tun_mtu);
+    }
+    else /* tap mode */
+    {
+        /* base IPv6 tap interface needs to be brought up first */
+        argv_printf(&argv, "%s %s inet6 plumb up", IFCONFIG_PATH, ifname);
+        argv_msg(M_INFO, &argv);
+
+        if (!openvpn_execve_check(&argv, es, 0,
+                                  "Solaris ifconfig IPv6 (prepare) failed"))
         {
-            ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
-            do_ipv6 = true;
+            solaris_error_close(tt, es, ifname, true);
         }
 
-        /*
-         * If TAP-style device, generate broadcast address.
+        /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
+         * after the system has noticed the interface and fired up
+         * the DHCPv6 client - but this takes quite a while, and the
+         * server will ignore the DHCPv6 packets anyway.  So we don't.
          */
-        if (!tun)
-        {
-            ifconfig_broadcast = print_in_addr_t(tt->broadcast, 0, &gc);
-        }
 
-#ifdef ENABLE_MANAGEMENT
-        if (management)
-        {
-            management_set_state(management,
-                                 OPENVPN_STATE_ASSIGN_IP,
-                                 NULL,
-                                 &tt->local,
-                                 &tt->local_ipv6,
-                                 NULL,
-                                 NULL);
-        }
+        /* static IPv6 addresses need to go to a subinterface (tap0:1) */
+        argv_printf(&argv, "%s %s inet6 addif %s/%d mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    }
+    argv_msg(M_INFO, &argv);
+
+    if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 failed"))
+    {
+        solaris_error_close(tt, es, ifname, true);
+    }
+#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
+    || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
+    || defined(TARGET_DRAGONFLY) || defined(TARGET_AIX)
+    argv_printf(&argv, "%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    argv_msg(M_INFO, &argv);
+
+#if defined(TARGET_AIX)
+    /* AIX ifconfig will complain if it can't find ODM path in env */
+    es = env_set_create(NULL);
+    env_set_add(es, "ODMDIR=/etc/objrepos");
 #endif
 
+    openvpn_execve_check(&argv, es, S_FATAL,
+                         "generic BSD ifconfig inet6 failed");
+
+#if defined(TARGET_AIX)
+    env_set_destroy(es);
+#endif
+
+#if !defined(TARGET_FREEBSD) && !defined(TARGET_DRAGONFLY) \
+    && !defined(TARGET_AIX)
+    /* and, hooray, we explicitely need to add a route... */
+    add_route_connected_v6_net(tt, es);
+#endif
+#elif defined (_WIN32)
+    if (tt->options.ip_win32_type == IPW32_SET_MANUAL)
+    {
+        msg(M_INFO, "******** NOTE:  Please manually set the v6 IP of '%s' to %s (if it is not already set)",
+            ifname, ifconfig_ipv6_local);
+    }
+    else if (tt->options.msg_channel)
+    {
+        do_address_service(true, AF_INET6, tt);
+        do_dns6_service(true, tt);
+    }
+    else
+    {
+        /* example: netsh interface ipv6 set address interface=42
+         * 2001:608:8003::d store=active
+         */
+        char iface[64];
+
+        openvpn_snprintf(iface, sizeof(iface), "interface=%lu",
+                         tt->adapter_index);
+        argv_printf(&argv, "%s%sc interface ipv6 set address %s %s store=active",
+                    get_win_sys_path(), NETSH_PATH_SUFFIX, iface,
+                    ifconfig_ipv6_local);
+        netsh_command(&argv, 4, M_FATAL);
+        /* set ipv6 dns servers if any are specified */
+        netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, ifname);
+    }
+
+    /* explicit route needed */
+    if (tt->options.ip_win32_type != IPW32_SET_MANUAL)
+    {
+        add_route_connected_v6_net(tt, es);
+    }
+#else  /* if defined(TARGET_LINUX) */
+    msg(M_FATAL, "Sorry, but I don't know how to do IPv6 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
+#endif  /* if defined(TARGET_LINUX) */
+
+    gc_free(&gc);
+    argv_reset(&argv);
+}
+
+/**
+ * do_ifconfig_ipv4 - perform platform specific ifconfig commands
+ *
+ * @param tt        the tuntap interface context
+ * @param ifname    the human readable interface name
+ * @param mtu       the MTU value to set the interface to
+ * @param es        the environment to be used when executing the commands
+ */
+static void
+do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
+                 const struct env_set *es)
+{
+    bool tun = false;
+    const char *ifconfig_local = NULL;
+    const char *ifconfig_remote_netmask = NULL;
+    const char *ifconfig_broadcast = NULL;
+    struct argv argv = argv_new();
+    struct gc_arena gc = gc_new();
+
+    /*
+     * We only handle TUN/TAP devices here, not --dev null devices.
+     */
+    tun = is_tun_p2p(tt);
+
+    /*
+     * Set ifconfig parameters
+     */
+    ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
+    ifconfig_remote_netmask = print_in_addr_t(tt->remote_netmask, 0, &gc);
+
+    /*
+     * If TAP-style device, generate broadcast address.
+     */
+    if (!tun)
+    {
+        ifconfig_broadcast = print_in_addr_t(tt->broadcast, 0, &gc);
+    }
 
 #if defined(TARGET_LINUX)
 #ifdef ENABLE_IPROUTE
+    /*
+     * Set the MTU for the device
+     */
+    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
+                tun_mtu);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
+
+    if (tun)
+    {
+
         /*
-         * Set the MTU for the device
+         * Set the address for the device
          */
-        argv_printf(&argv,
-                    "%s link set dev %s up mtu %d",
-                    iproute_path,
-                    actual,
-                    tun_mtu
-                    );
+        argv_printf(&argv, "%s addr add dev %s local %s peer %s", iproute_path,
+                    ifname, ifconfig_local, ifconfig_remote_netmask);
         argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
-
-        if (tun)
-        {
-
-            /*
-             * Set the address for the device
-             */
-            argv_printf(&argv,
-                        "%s addr add dev %s local %s peer %s",
-                        iproute_path,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s addr add dev %s %s/%d broadcast %s",
-                        iproute_path,
-                        actual,
-                        ifconfig_local,
-                        netmask_to_netbits2(tt->remote_netmask),
-                        ifconfig_broadcast
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
-        }
-        if (do_ipv6)
-        {
-            argv_printf( &argv,
-                         "%s -6 addr add %s/%d dev %s",
-                         iproute_path,
-                         ifconfig_ipv6_local,
-                         tt->netbits_ipv6,
-                         actual
-                         );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip -6 addr add failed");
-        }
-        tt->did_ifconfig = true;
-#else  /* ifdef ENABLE_IPROUTE */
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s pointopoint %s mtu %d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d broadcast %s",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu,
-                        ifconfig_broadcast
-                        );
-        }
+        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
+    }
+    else
+    {
+        argv_printf(&argv, "%s addr add dev %s %s/%d broadcast %s",
+                    iproute_path, ifname, ifconfig_local,
+                    netmask_to_netbits2(tt->remote_netmask),
+                    ifconfig_broadcast);
         argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig failed");
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s add %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
-        }
-        tt->did_ifconfig = true;
+        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
+    }
+    tt->did_ifconfig = true;
+#else  /* ifdef ENABLE_IPROUTE */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s pointopoint %s mtu %d", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+    }
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig failed");
+    tt->did_ifconfig = true;
 
 #endif /*ENABLE_IPROUTE*/
 #elif defined(TARGET_ANDROID)
+    char out[64];
 
-        if (do_ipv6)
-        {
-            char out6[64];
-            openvpn_snprintf(out6, sizeof(out6), "%s/%d", ifconfig_ipv6_local,tt->netbits_ipv6);
-            management_android_control(management, "IFCONFIG6", out6);
-        }
-
-        char out[64];
-
-        char *top;
-        switch (tt->topology)
-        {
-            case TOP_NET30:
-                top = "net30";
-                break;
+    char *top;
+    switch (tt->topology)
+    {
+        case TOP_NET30:
+            top = "net30";
+            break;
 
-            case TOP_P2P:
-                top = "p2p";
-                break;
+        case TOP_P2P:
+            top = "p2p";
+            break;
 
-            case TOP_SUBNET:
-                top = "subnet";
-                break;
+        case TOP_SUBNET:
+            top = "subnet";
+            break;
 
-            default:
-                top = "undef";
-        }
+        default:
+            top = "undef";
+    }
 
-        openvpn_snprintf(out, sizeof(out), "%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu, top);
-        management_android_control(management, "IFCONFIG", out);
+    openvpn_snprintf(out, sizeof(out), "%s %s %d %s", ifconfig_local,
+                     ifconfig_remote_netmask, tun_mtu, top);
+    management_android_control(management, "IFCONFIG", out);
 
 #elif defined(TARGET_SOLARIS)
-        /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
-         * example:
-         *    ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
-         *    ifconfig tun2 netmask 255.255.255.255
-         */
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-
-            argv_msg(M_INFO, &argv);
-            if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-1 failed"))
-            {
-                solaris_error_close(tt, es, actual, false);
-            }
-
-            argv_printf(&argv,
-                        "%s %s netmask 255.255.255.255",
-                        IFCONFIG_PATH,
-                        actual
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s netmask %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        " %s %s %s netmask %s broadcast + up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask
-                        );
-        }
+    /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
+     * example:
+     *    ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
+     *    ifconfig tun2 netmask 255.255.255.255
+     */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d up", IFCONFIG_PATH, ifname,
+                    ifconfig_local, ifconfig_remote_netmask, tun_mtu);
 
         argv_msg(M_INFO, &argv);
-        if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-2 failed"))
+        if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-1 failed"))
         {
-            solaris_error_close(tt, es, actual, false);
+            solaris_error_close(tt, es, ifname, false);
         }
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv, "%s %s inet6 unplumb",
-                        IFCONFIG_PATH, actual );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, 0, NULL);
-
-            if (tt->type == DEV_TYPE_TUN)
-            {
-                const char *ifconfig_ipv6_remote =
-                    print_in6_addr(tt->remote_ipv6, 0, &gc);
-
-                argv_printf(&argv,
-                            "%s %s inet6 plumb %s/%d %s up",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_ipv6_local,
-                            tt->netbits_ipv6,
-                            ifconfig_ipv6_remote
-                            );
-            }
-            else                                        /* tap mode */
-            {
-                /* base IPv6 tap interface needs to be brought up first
-                 */
-                argv_printf(&argv, "%s %s inet6 plumb up",
-                            IFCONFIG_PATH, actual );
-                argv_msg(M_INFO, &argv);
-                if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 (prepare) failed"))
-                {
-                    solaris_error_close(tt, es, actual, true);
-                }
-
-                /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
-                 * after the system has noticed the interface and fired up
-                 * the DHCPv6 client - but this takes quite a while, and the
-                 * server will ignore the DHCPv6 packets anyway.  So we don't.
-                 */
+        argv_printf(&argv, "%s %s netmask 255.255.255.255", IFCONFIG_PATH,
+                    ifname);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s broadcast + up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask);
+    }
 
-                /* static IPv6 addresses need to go to a subinterface (tap0:1)
-                 */
-                argv_printf(&argv,
-                            "%s %s inet6 addif %s/%d up",
-                            IFCONFIG_PATH, actual,
-                            ifconfig_ipv6_local, tt->netbits_ipv6 );
-            }
-            argv_msg(M_INFO, &argv);
-            if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 failed"))
-            {
-                solaris_error_close(tt, es, actual, true);
-            }
-        }
+    argv_msg(M_INFO, &argv);
+    if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-2 failed"))
+    {
+        solaris_error_close(tt, es, ifname, false);
+    }
 
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            /* Add a network route for the local tun interface */
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED | RT_METRIC_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = tt->local;
-            r.metric = 0;
-            add_route(&r, tt, 0, NULL, es);
-        }
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        /* Add a network route for the local tun interface */
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED | RT_METRIC_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = tt->local;
+        r.metric = 0;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-        tt->did_ifconfig = true;
+    tt->did_ifconfig = true;
 
 #elif defined(TARGET_OPENBSD)
 
-        in_addr_t remote_end;           /* for "virtual" subnet topology */
+    in_addr_t remote_end;           /* for "virtual" subnet topology */
 
-        /*
-         * On OpenBSD, tun interfaces are persistent if created with
-         * "ifconfig tunX create", and auto-destroyed if created by
-         * opening "/dev/tunX" (so we just use the /dev/tunX)
-         */
-
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            remote_end = create_arbitrary_remote( tt );
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask %s up -link0",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        print_in_addr_t(remote_end, 0, &gc),
-                        tun_mtu,
-                        ifconfig_remote_netmask
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d broadcast %s link0",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu,
-                        ifconfig_broadcast
-                        );
-        }
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed");
+    /*
+     * On OpenBSD, tun interfaces are persistent if created with
+     * "ifconfig tunX create", and auto-destroyed if created by
+     * opening "/dev/tunX" (so we just use the /dev/tunX)
+     */
 
-        /* Add a network route for the local tun interface */
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = remote_end;
-            add_route(&r, tt, 0, NULL, es);
-        }
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
+    if (tun)
+    {
+        argv_printf(&argv,
+                    "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        remote_end = create_arbitrary_remote( tt );
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up -link0",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    print_in_addr_t(remote_end, 0, &gc), tun_mtu,
+                    ifconfig_remote_netmask);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s link0",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+    }
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed");
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig inet6 failed");
+    /* Add a network route for the local tun interface */
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = remote_end;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-            /* and, hooray, we explicitely need to add a route... */
-            add_route_connected_v6_net(tt, es);
-        }
-        tt->did_ifconfig = true;
+    tt->did_ifconfig = true;
 
 #elif defined(TARGET_NETBSD)
 
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask %s up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_local,
-                        tun_mtu,
-                        ifconfig_remote_netmask
-                        );
-        }
-        else
-        {
-            /*
-             * NetBSD has distinct tun and tap devices
-             * so we don't need the "link0" extra parameter to specify we want to do
-             * tunneling at the ethernet level
-             */
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d broadcast %s",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu,
-                        ifconfig_broadcast
-                        );
-        }
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed");
-
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig inet6 failed");
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_local, tun_mtu,
+                    ifconfig_remote_netmask);
+    }
+    else
+    {
+        /*
+         * NetBSD has distinct tun and tap devices
+         * so we don't need the "link0" extra parameter to specify we want to do
+         * tunneling at the ethernet level
+         */
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+    }
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed");
 
-            /* and, hooray, we explicitely need to add a route... */
-            add_route_connected_v6_net(tt, es);
-        }
-        tt->did_ifconfig = true;
+    tt->did_ifconfig = true;
 
 #elif defined(TARGET_DARWIN)
-        /*
-         * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
-         */
+    /*
+     * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
+     */
 
-        argv_printf(&argv,
-                    "%s %s delete",
-                    IFCONFIG_PATH,
-                    actual);
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, 0, NULL);
-        msg(M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
+    argv_printf(&argv, "%s %s delete", IFCONFIG_PATH, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, 0, NULL);
+    msg(M_INFO,
+        "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
 
 
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
-        if (tun)
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else
+    {
+        if (tt->topology == TOP_SUBNET)
         {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
+            argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up",
+                        IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_local,
+                        ifconfig_remote_netmask, tun_mtu);
         }
         else
         {
-            if (tt->topology == TOP_SUBNET)
-            {
-                argv_printf(&argv,
-                            "%s %s %s %s netmask %s mtu %d up",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_local,
-                            ifconfig_local,
-                            ifconfig_remote_netmask,
-                            tun_mtu
-                            );
-            }
-            else
-            {
-                argv_printf(&argv,
-                            "%s %s %s netmask %s mtu %d up",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_local,
-                            ifconfig_remote_netmask,
-                            tun_mtu
-                            );
-            }
+            argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                        ifname, ifconfig_local, ifconfig_remote_netmask,
+                        tun_mtu);
         }
+    }
 
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed");
-        tt->did_ifconfig = true;
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed");
+    tt->did_ifconfig = true;
 
-        /* Add a network route for the local tun interface */
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = tt->local;
-            add_route(&r, tt, 0, NULL, es);
-        }
+    /* Add a network route for the local tun interface */
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = tt->local;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "MacOS X ifconfig inet6 failed");
+#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
 
-            /* and, hooray, we explicitely need to add a route... */
-            add_route_connected_v6_net(tt, es);
-        }
+    in_addr_t remote_end;           /* for "virtual" subnet topology */
 
-#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        remote_end = create_arbitrary_remote( tt );
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, print_in_addr_t(remote_end, 0, &gc),
+                    tun_mtu, ifconfig_remote_netmask);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
+    }
+
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed");
+    tt->did_ifconfig = true;
 
-        in_addr_t remote_end;           /* for "virtual" subnet topology */
+    /* Add a network route for the local tun interface */
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = remote_end;
+        add_route(&r, tt, 0, NULL, es);
+    }
+
+#elif defined(TARGET_AIX)
+    {
+        /* AIX ifconfig will complain if it can't find ODM path in env */
+        struct env_set *aix_es = env_set_create(NULL);
+        env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
 
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
         if (tun)
         {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            remote_end = create_arbitrary_remote( tt );
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask %s up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        print_in_addr_t(remote_end, 0, &gc),
-                        tun_mtu,
-                        ifconfig_remote_netmask
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
+            msg(M_FATAL, "no tun support on AIX (canthappen)");
         }
 
+        /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
+
         argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed");
+        openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig failed");
         tt->did_ifconfig = true;
 
-        /* Add a network route for the local tun interface */
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = remote_end;
-            add_route(&r, tt, 0, NULL, es);
-        }
-
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed");
-        }
+        env_set_destroy(aix_es);
+    }
+#elif defined (_WIN32)
+    {
+        ASSERT(ifname != NULL);
 
-#elif defined(TARGET_AIX)
+        switch (tt->options.ip_win32_type)
         {
-            /* AIX ifconfig will complain if it can't find ODM path in env */
-            struct env_set *aix_es = env_set_create(NULL);
-            env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
-
-            if (tun)
-            {
-                msg(M_FATAL, "no tun support on AIX (canthappen)");
-            }
-
-            /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig failed");
-            tt->did_ifconfig = true;
+            case IPW32_SET_MANUAL:
+                msg(M_INFO,
+                    "******** NOTE:  Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
+                    ifname, ifconfig_local,
+                    print_in_addr_t(tt->adapter_netmask, 0, &gc));
+                break;
+            case IPW32_SET_NETSH:
+                netsh_ifconfig(&tt->options, ifname, tt->local,
+                               tt->adapter_netmask, NI_IP_NETMASK|NI_OPTIONS);
 
-            if (do_ipv6)
-            {
-                argv_printf(&argv,
-                            "%s %s inet6 %s/%d",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_ipv6_local,
-                            tt->netbits_ipv6
-                            );
-                argv_msg(M_INFO, &argv);
-                openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig inet6 failed");
-            }
-            env_set_destroy(aix_es);
+                break;
         }
-#elif defined (_WIN32)
-        {
-            ASSERT(actual != NULL);
+        tt->did_ifconfig = true;
+    }
 
-            switch (tt->options.ip_win32_type)
-            {
-                case IPW32_SET_MANUAL:
-                    msg(M_INFO, "******** NOTE:  Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
-                        actual,
-                        ifconfig_local,
-                        print_in_addr_t(tt->adapter_netmask, 0, &gc));
-                    break;
+#else  /* if defined(TARGET_LINUX) */
+    msg(M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
+#endif /* if defined(TARGET_LINUX) */
 
-                case IPW32_SET_NETSH:
-                    netsh_ifconfig(&tt->options,
-                                   actual,
-                                   tt->local,
-                                   tt->adapter_netmask,
-                                   NI_IP_NETMASK|NI_OPTIONS);
+    gc_free(&gc);
+    argv_reset(&argv);
+}
 
-                    break;
-            }
-            tt->did_ifconfig = true;
-        }
+/* execute the ifconfig command through the shell */
+void
+do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
+            const struct env_set *es)
+{
+    msg(M_DEBUG, "do_ifconfig, ipv4=%d, ipv6=%d", tt->did_ifconfig_setup,
+        tt->did_ifconfig_ipv6_setup);
 
-        if (do_ipv6)
-        {
-            if (tt->options.ip_win32_type == IPW32_SET_MANUAL)
-            {
-                msg(M_INFO, "******** NOTE:  Please manually set the v6 IP of '%s' to %s (if it is not already set)",
-                    actual,
-                    ifconfig_ipv6_local);
-            }
-            else if (tt->options.msg_channel)
-            {
-                do_address_service(true, AF_INET6, tt);
-                do_dns6_service(true, tt);
-            }
-            else
-            {
-                /* example: netsh interface ipv6 set address interface=42 2001:608:8003::d store=active */
-                char iface[64];
-                openvpn_snprintf(iface, sizeof(iface), "interface=%lu", tt->adapter_index );
-                argv_printf(&argv,
-                            "%s%sc interface ipv6 set address %s %s store=active",
-                            get_win_sys_path(),
-                            NETSH_PATH_SUFFIX,
-                            iface,
-                            ifconfig_ipv6_local );
-                netsh_command(&argv, 4, M_FATAL);
-                /* set ipv6 dns servers if any are specified */
-                netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, actual);
-            }
+#ifdef ENABLE_MANAGEMENT
+    if (management)
+    {
+        management_set_state(management,
+                             OPENVPN_STATE_ASSIGN_IP,
+                             NULL,
+                             &tt->local,
+                             &tt->local_ipv6,
+                             NULL,
+                             NULL);
+    }
+#endif
 
-            /* explicit route needed */
-            if (tt->options.ip_win32_type != IPW32_SET_MANUAL)
-            {
-                add_route_connected_v6_net(tt, es);
-            }
-        }
-#else  /* if defined(TARGET_LINUX) */
-        msg(M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
-#endif /* if defined(TARGET_LINUX) */
-        argv_reset(&argv);
+    if (tt->did_ifconfig_setup)
+    {
+        do_ifconfig_ipv4(tt, ifname, tun_mtu, es);
+    }
+
+    if (tt->did_ifconfig_ipv6_setup)
+    {
+        do_ifconfig_ipv6(tt, ifname, tun_mtu, es);
     }
-    gc_free(&gc);
 }
 
 static void
@@ -5865,7 +5713,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
 
     if (tt->type == DEV_TYPE_TUN)
     {
-        if (!tt->did_ifconfig_setup)
+        if (!tt->did_ifconfig_setup && !tt->did_ifconfig_ipv6_setup)
         {
             msg(M_FATAL, "ERROR: --dev tun also requires --ifconfig");
         }
src/openvpn/tun.h +9 -3
index 6c57ad0d..448a7738 100644
@@ -247,9 +247,15 @@ void init_tun_post(struct tuntap *tt,
 void do_ifconfig_setenv(const struct tuntap *tt,
                         struct env_set *es);
 
-void do_ifconfig(struct tuntap *tt,
-                 const char *actual,     /* actual device name */
-                 int tun_mtu,
+/**
+ * do_ifconfig - configure the tunnel interface
+ *
+ * @param tt        the tuntap interface context
+ * @param ifname    the human readable interface name
+ * @param mtu       the MTU value to set the interface to
+ * @param es        the environment to be used when executing the commands
+ */
+void do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
                  const struct env_set *es);
 
 bool is_dev_type(const char *dev, const char *dev_type, const char *match_type);
Signature · 1 line
2.17.1
#2 lore raw

PATCH v3 1/1 tun: ensure interface can be configured with IPv6 only

From: Antonio Quartulli <[email protected]...>

This change ensures that an interface is properly brought up even when only IPv6 settings are configured/pushed.

At the same time, the do_ifconfig() function has been rearranged by splitting the logic into a v4 and a v6 specific part. Each part has then been moved into an idependent helper that can be invoked as needed.

This makes the code easier to read and more "symmetric" with respect to the two address families.

Trac: #208

---

Changes from v2:
- rebased on top of master (fix conflict about D_LOW)
- commit message improved

 src/openvpn/tun.c | 1118 ++++++++++++++++++++-------------------------
 src/openvpn/tun.h |   12 +-
 2 files changed, 492 insertions(+), 638 deletions(-)
src/openvpn/tun.c +483 -635
index 3eb0f78a..2a08cf2c 100644
@@ -871,724 +871,572 @@ create_arbitrary_remote( struct tuntap *tt )
 }
 #endif
 
-/* execute the ifconfig command through the shell */
-void
-do_ifconfig(struct tuntap *tt,
-            const char *actual,     /* actual device name */
-            int tun_mtu,
-            const struct env_set *es)
+/**
+ * do_ifconfig_ipv6 - perform platform specific ifconfig6 commands
+ *
+ * @param tt        the tuntap interface context
+ * @param ifname    the human readable interface name
+ * @param mtu       the MTU value to set the interface to
+ * @param es        the environment to be used when executing the commands
+ */
+static void
+do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
+                 const struct env_set *es)
 {
+    const char *ifconfig_ipv6_local = NULL;
+    struct argv argv = argv_new();
     struct gc_arena gc = gc_new();
 
-    if (tt->did_ifconfig_setup)
-    {
-        bool tun = false;
-        const char *ifconfig_local = NULL;
-        const char *ifconfig_remote_netmask = NULL;
-        const char *ifconfig_broadcast = NULL;
-        const char *ifconfig_ipv6_local = NULL;
-        bool do_ipv6 = false;
-        struct argv argv = argv_new();
+    ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
 
-        msg( D_LOW, "do_ifconfig, tt->did_ifconfig_ipv6_setup=%d",
-             tt->did_ifconfig_ipv6_setup );
+#if defined(TARGET_LINUX)
+#ifdef ENABLE_IPROUTE
+    /* set the MTU for the device and bring it up */
+    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
+                tun_mtu);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
 
-        /*
-         * We only handle TUN/TAP devices here, not --dev null devices.
-         */
-        tun = is_tun_p2p(tt);
+    argv_printf(&argv, "%s -6 addr add %s/%d dev %s", iproute_path,
+                ifconfig_ipv6_local, tt->netbits_ipv6, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip -6 addr add failed");
+#else
+    argv_printf(&argv, "%s %s add %s/%d mtu %d up", IFCONFIG_PATH, ifname,
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
+#endif
+#elif defined(TARGET_ANDROID)
+    char out6[64];
 
-        /*
-         * Set ifconfig parameters
-         */
-        ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
-        ifconfig_remote_netmask = print_in_addr_t(tt->remote_netmask, 0, &gc);
+    openvpn_snprintf(out6, sizeof(out6), "%s/%d",
+                     ifconfig_ipv6_local,tt->netbits_ipv6);
+    management_android_control(management, "IFCONFIG6", out6);
+#elif defined(TARGET_SOLARIS)
+    argv_printf(&argv, "%s %s inet6 unplumb", IFCONFIG_PATH, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, 0, NULL);
 
-        if (tt->did_ifconfig_ipv6_setup)
+    if (tt->type == DEV_TYPE_TUN)
+    {
+        const char *ifconfig_ipv6_remote = print_in6_addr(tt->remote_ipv6, 0,
+                                                          gc);
+
+        argv_printf(&argv, "%s %s inet6 plumb %s/%d %s mtu %d up",
+                    IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
+                    tt->netbits_ipv6, ifconfig_ipv6_remote, tun_mtu);
+    }
+    else /* tap mode */
+    {
+        /* base IPv6 tap interface needs to be brought up first */
+        argv_printf(&argv, "%s %s inet6 plumb up", IFCONFIG_PATH, ifname);
+        argv_msg(M_INFO, &argv);
+
+        if (!openvpn_execve_check(&argv, es, 0,
+                                  "Solaris ifconfig IPv6 (prepare) failed"))
         {
-            ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
-            do_ipv6 = true;
+            solaris_error_close(tt, es, ifname, true);
         }
 
-        /*
-         * If TAP-style device, generate broadcast address.
+        /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
+         * after the system has noticed the interface and fired up
+         * the DHCPv6 client - but this takes quite a while, and the
+         * server will ignore the DHCPv6 packets anyway.  So we don't.
          */
-        if (!tun)
-        {
-            ifconfig_broadcast = print_in_addr_t(tt->broadcast, 0, &gc);
-        }
 
-#ifdef ENABLE_MANAGEMENT
-        if (management)
-        {
-            management_set_state(management,
-                                 OPENVPN_STATE_ASSIGN_IP,
-                                 NULL,
-                                 &tt->local,
-                                 &tt->local_ipv6,
-                                 NULL,
-                                 NULL);
-        }
+        /* static IPv6 addresses need to go to a subinterface (tap0:1) */
+        argv_printf(&argv, "%s %s inet6 addif %s/%d mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    }
+    argv_msg(M_INFO, &argv);
+
+    if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 failed"))
+    {
+        solaris_error_close(tt, es, ifname, true);
+    }
+#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
+    || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
+    || defined(TARGET_DRAGONFLY) || defined(TARGET_AIX)
+    argv_printf(&argv, "%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    argv_msg(M_INFO, &argv);
+
+#if defined(TARGET_AIX)
+    /* AIX ifconfig will complain if it can't find ODM path in env */
+    es = env_set_create(NULL);
+    env_set_add(es, "ODMDIR=/etc/objrepos");
 #endif
 
+    openvpn_execve_check(&argv, es, S_FATAL,
+                         "generic BSD ifconfig inet6 failed");
+
+#if defined(TARGET_AIX)
+    env_set_destroy(es);
+#endif
+
+#if !defined(TARGET_FREEBSD) && !defined(TARGET_DRAGONFLY) \
+    && !defined(TARGET_AIX)
+    /* and, hooray, we explicitely need to add a route... */
+    add_route_connected_v6_net(tt, es);
+#endif
+#elif defined (_WIN32)
+    if (tt->options.ip_win32_type == IPW32_SET_MANUAL)
+    {
+        msg(M_INFO, "******** NOTE:  Please manually set the v6 IP of '%s' to %s (if it is not already set)",
+            ifname, ifconfig_ipv6_local);
+    }
+    else if (tt->options.msg_channel)
+    {
+        do_address_service(true, AF_INET6, tt);
+        do_dns6_service(true, tt);
+    }
+    else
+    {
+        /* example: netsh interface ipv6 set address interface=42
+         * 2001:608:8003::d store=active
+         */
+        char iface[64];
+
+        openvpn_snprintf(iface, sizeof(iface), "interface=%lu",
+                         tt->adapter_index);
+        argv_printf(&argv, "%s%sc interface ipv6 set address %s %s store=active",
+                    get_win_sys_path(), NETSH_PATH_SUFFIX, iface,
+                    ifconfig_ipv6_local);
+        netsh_command(&argv, 4, M_FATAL);
+        /* set ipv6 dns servers if any are specified */
+        netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, ifname);
+    }
+
+    /* explicit route needed */
+    if (tt->options.ip_win32_type != IPW32_SET_MANUAL)
+    {
+        add_route_connected_v6_net(tt, es);
+    }
+#else  /* if defined(TARGET_LINUX) */
+    msg(M_FATAL, "Sorry, but I don't know how to do IPv6 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
+#endif  /* if defined(TARGET_LINUX) */
+
+    gc_free(&gc);
+    argv_reset(&argv);
+}
+
+/**
+ * do_ifconfig_ipv4 - perform platform specific ifconfig commands
+ *
+ * @param tt        the tuntap interface context
+ * @param ifname    the human readable interface name
+ * @param mtu       the MTU value to set the interface to
+ * @param es        the environment to be used when executing the commands
+ */
+static void
+do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
+                 const struct env_set *es)
+{
+    bool tun = false;
+    const char *ifconfig_local = NULL;
+    const char *ifconfig_remote_netmask = NULL;
+    const char *ifconfig_broadcast = NULL;
+    struct argv argv = argv_new();
+    struct gc_arena gc = gc_new();
+
+    /*
+     * We only handle TUN/TAP devices here, not --dev null devices.
+     */
+    tun = is_tun_p2p(tt);
+
+    /*
+     * Set ifconfig parameters
+     */
+    ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
+    ifconfig_remote_netmask = print_in_addr_t(tt->remote_netmask, 0, &gc);
+
+    /*
+     * If TAP-style device, generate broadcast address.
+     */
+    if (!tun)
+    {
+        ifconfig_broadcast = print_in_addr_t(tt->broadcast, 0, &gc);
+    }
 
 #if defined(TARGET_LINUX)
 #ifdef ENABLE_IPROUTE
+    /*
+     * Set the MTU for the device
+     */
+    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
+                tun_mtu);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
+
+    if (tun)
+    {
+
         /*
-         * Set the MTU for the device
+         * Set the address for the device
          */
-        argv_printf(&argv,
-                    "%s link set dev %s up mtu %d",
-                    iproute_path,
-                    actual,
-                    tun_mtu
-                    );
+        argv_printf(&argv, "%s addr add dev %s local %s peer %s", iproute_path,
+                    ifname, ifconfig_local, ifconfig_remote_netmask);
         argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
-
-        if (tun)
-        {
-
-            /*
-             * Set the address for the device
-             */
-            argv_printf(&argv,
-                        "%s addr add dev %s local %s peer %s",
-                        iproute_path,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s addr add dev %s %s/%d broadcast %s",
-                        iproute_path,
-                        actual,
-                        ifconfig_local,
-                        netmask_to_netbits2(tt->remote_netmask),
-                        ifconfig_broadcast
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
-        }
-        if (do_ipv6)
-        {
-            argv_printf( &argv,
-                         "%s -6 addr add %s/%d dev %s",
-                         iproute_path,
-                         ifconfig_ipv6_local,
-                         tt->netbits_ipv6,
-                         actual
-                         );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip -6 addr add failed");
-        }
-        tt->did_ifconfig = true;
-#else  /* ifdef ENABLE_IPROUTE */
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s pointopoint %s mtu %d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d broadcast %s",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu,
-                        ifconfig_broadcast
-                        );
-        }
+        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
+    }
+    else
+    {
+        argv_printf(&argv, "%s addr add dev %s %s/%d broadcast %s",
+                    iproute_path, ifname, ifconfig_local,
+                    netmask_to_netbits2(tt->remote_netmask),
+                    ifconfig_broadcast);
         argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig failed");
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s add %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
-        }
-        tt->did_ifconfig = true;
+        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
+    }
+    tt->did_ifconfig = true;
+#else  /* ifdef ENABLE_IPROUTE */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s pointopoint %s mtu %d", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+    }
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig failed");
+    tt->did_ifconfig = true;
 
 #endif /*ENABLE_IPROUTE*/
 #elif defined(TARGET_ANDROID)
+    char out[64];
 
-        if (do_ipv6)
-        {
-            char out6[64];
-            openvpn_snprintf(out6, sizeof(out6), "%s/%d", ifconfig_ipv6_local,tt->netbits_ipv6);
-            management_android_control(management, "IFCONFIG6", out6);
-        }
-
-        char out[64];
-
-        char *top;
-        switch (tt->topology)
-        {
-            case TOP_NET30:
-                top = "net30";
-                break;
+    char *top;
+    switch (tt->topology)
+    {
+        case TOP_NET30:
+            top = "net30";
+            break;
 
-            case TOP_P2P:
-                top = "p2p";
-                break;
+        case TOP_P2P:
+            top = "p2p";
+            break;
 
-            case TOP_SUBNET:
-                top = "subnet";
-                break;
+        case TOP_SUBNET:
+            top = "subnet";
+            break;
 
-            default:
-                top = "undef";
-        }
+        default:
+            top = "undef";
+    }
 
-        openvpn_snprintf(out, sizeof(out), "%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu, top);
-        management_android_control(management, "IFCONFIG", out);
+    openvpn_snprintf(out, sizeof(out), "%s %s %d %s", ifconfig_local,
+                     ifconfig_remote_netmask, tun_mtu, top);
+    management_android_control(management, "IFCONFIG", out);
 
 #elif defined(TARGET_SOLARIS)
-        /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
-         * example:
-         *    ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
-         *    ifconfig tun2 netmask 255.255.255.255
-         */
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-
-            argv_msg(M_INFO, &argv);
-            if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-1 failed"))
-            {
-                solaris_error_close(tt, es, actual, false);
-            }
-
-            argv_printf(&argv,
-                        "%s %s netmask 255.255.255.255",
-                        IFCONFIG_PATH,
-                        actual
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s netmask %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        " %s %s %s netmask %s broadcast + up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask
-                        );
-        }
+    /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
+     * example:
+     *    ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
+     *    ifconfig tun2 netmask 255.255.255.255
+     */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d up", IFCONFIG_PATH, ifname,
+                    ifconfig_local, ifconfig_remote_netmask, tun_mtu);
 
         argv_msg(M_INFO, &argv);
-        if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-2 failed"))
+        if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-1 failed"))
         {
-            solaris_error_close(tt, es, actual, false);
+            solaris_error_close(tt, es, ifname, false);
         }
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv, "%s %s inet6 unplumb",
-                        IFCONFIG_PATH, actual );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, 0, NULL);
-
-            if (tt->type == DEV_TYPE_TUN)
-            {
-                const char *ifconfig_ipv6_remote =
-                    print_in6_addr(tt->remote_ipv6, 0, &gc);
-
-                argv_printf(&argv,
-                            "%s %s inet6 plumb %s/%d %s up",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_ipv6_local,
-                            tt->netbits_ipv6,
-                            ifconfig_ipv6_remote
-                            );
-            }
-            else                                        /* tap mode */
-            {
-                /* base IPv6 tap interface needs to be brought up first
-                 */
-                argv_printf(&argv, "%s %s inet6 plumb up",
-                            IFCONFIG_PATH, actual );
-                argv_msg(M_INFO, &argv);
-                if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 (prepare) failed"))
-                {
-                    solaris_error_close(tt, es, actual, true);
-                }
-
-                /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
-                 * after the system has noticed the interface and fired up
-                 * the DHCPv6 client - but this takes quite a while, and the
-                 * server will ignore the DHCPv6 packets anyway.  So we don't.
-                 */
+        argv_printf(&argv, "%s %s netmask 255.255.255.255", IFCONFIG_PATH,
+                    ifname);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s broadcast + up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask);
+    }
 
-                /* static IPv6 addresses need to go to a subinterface (tap0:1)
-                 */
-                argv_printf(&argv,
-                            "%s %s inet6 addif %s/%d up",
-                            IFCONFIG_PATH, actual,
-                            ifconfig_ipv6_local, tt->netbits_ipv6 );
-            }
-            argv_msg(M_INFO, &argv);
-            if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 failed"))
-            {
-                solaris_error_close(tt, es, actual, true);
-            }
-        }
+    argv_msg(M_INFO, &argv);
+    if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-2 failed"))
+    {
+        solaris_error_close(tt, es, ifname, false);
+    }
 
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            /* Add a network route for the local tun interface */
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED | RT_METRIC_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = tt->local;
-            r.metric = 0;
-            add_route(&r, tt, 0, NULL, es);
-        }
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        /* Add a network route for the local tun interface */
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED | RT_METRIC_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = tt->local;
+        r.metric = 0;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-        tt->did_ifconfig = true;
+    tt->did_ifconfig = true;
 
 #elif defined(TARGET_OPENBSD)
 
-        in_addr_t remote_end;           /* for "virtual" subnet topology */
+    in_addr_t remote_end;           /* for "virtual" subnet topology */
 
-        /*
-         * On OpenBSD, tun interfaces are persistent if created with
-         * "ifconfig tunX create", and auto-destroyed if created by
-         * opening "/dev/tunX" (so we just use the /dev/tunX)
-         */
-
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            remote_end = create_arbitrary_remote( tt );
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask %s up -link0",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        print_in_addr_t(remote_end, 0, &gc),
-                        tun_mtu,
-                        ifconfig_remote_netmask
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d broadcast %s link0",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu,
-                        ifconfig_broadcast
-                        );
-        }
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed");
+    /*
+     * On OpenBSD, tun interfaces are persistent if created with
+     * "ifconfig tunX create", and auto-destroyed if created by
+     * opening "/dev/tunX" (so we just use the /dev/tunX)
+     */
 
-        /* Add a network route for the local tun interface */
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = remote_end;
-            add_route(&r, tt, 0, NULL, es);
-        }
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
+    if (tun)
+    {
+        argv_printf(&argv,
+                    "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        remote_end = create_arbitrary_remote( tt );
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up -link0",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    print_in_addr_t(remote_end, 0, &gc), tun_mtu,
+                    ifconfig_remote_netmask);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s link0",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+    }
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed");
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig inet6 failed");
+    /* Add a network route for the local tun interface */
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = remote_end;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-            /* and, hooray, we explicitely need to add a route... */
-            add_route_connected_v6_net(tt, es);
-        }
-        tt->did_ifconfig = true;
+    tt->did_ifconfig = true;
 
 #elif defined(TARGET_NETBSD)
 
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask %s up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_local,
-                        tun_mtu,
-                        ifconfig_remote_netmask
-                        );
-        }
-        else
-        {
-            /*
-             * NetBSD has distinct tun and tap devices
-             * so we don't need the "link0" extra parameter to specify we want to do
-             * tunneling at the ethernet level
-             */
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d broadcast %s",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu,
-                        ifconfig_broadcast
-                        );
-        }
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed");
-
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig inet6 failed");
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_local, tun_mtu,
+                    ifconfig_remote_netmask);
+    }
+    else
+    {
+        /*
+         * NetBSD has distinct tun and tap devices
+         * so we don't need the "link0" extra parameter to specify we want to do
+         * tunneling at the ethernet level
+         */
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+    }
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed");
 
-            /* and, hooray, we explicitely need to add a route... */
-            add_route_connected_v6_net(tt, es);
-        }
-        tt->did_ifconfig = true;
+    tt->did_ifconfig = true;
 
 #elif defined(TARGET_DARWIN)
-        /*
-         * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
-         */
+    /*
+     * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
+     */
 
-        argv_printf(&argv,
-                    "%s %s delete",
-                    IFCONFIG_PATH,
-                    actual);
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, 0, NULL);
-        msg(M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
+    argv_printf(&argv, "%s %s delete", IFCONFIG_PATH, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, 0, NULL);
+    msg(M_INFO,
+        "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
 
 
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
-        if (tun)
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else
+    {
+        if (tt->topology == TOP_SUBNET)
         {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
+            argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up",
+                        IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_local,
+                        ifconfig_remote_netmask, tun_mtu);
         }
         else
         {
-            if (tt->topology == TOP_SUBNET)
-            {
-                argv_printf(&argv,
-                            "%s %s %s %s netmask %s mtu %d up",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_local,
-                            ifconfig_local,
-                            ifconfig_remote_netmask,
-                            tun_mtu
-                            );
-            }
-            else
-            {
-                argv_printf(&argv,
-                            "%s %s %s netmask %s mtu %d up",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_local,
-                            ifconfig_remote_netmask,
-                            tun_mtu
-                            );
-            }
+            argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                        ifname, ifconfig_local, ifconfig_remote_netmask,
+                        tun_mtu);
         }
+    }
 
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed");
-        tt->did_ifconfig = true;
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed");
+    tt->did_ifconfig = true;
 
-        /* Add a network route for the local tun interface */
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = tt->local;
-            add_route(&r, tt, 0, NULL, es);
-        }
+    /* Add a network route for the local tun interface */
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = tt->local;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "MacOS X ifconfig inet6 failed");
+#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
 
-            /* and, hooray, we explicitely need to add a route... */
-            add_route_connected_v6_net(tt, es);
-        }
+    in_addr_t remote_end;           /* for "virtual" subnet topology */
 
-#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        remote_end = create_arbitrary_remote( tt );
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, print_in_addr_t(remote_end, 0, &gc),
+                    tun_mtu, ifconfig_remote_netmask);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
+    }
+
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed");
+    tt->did_ifconfig = true;
 
-        in_addr_t remote_end;           /* for "virtual" subnet topology */
+    /* Add a network route for the local tun interface */
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = remote_end;
+        add_route(&r, tt, 0, NULL, es);
+    }
+
+#elif defined(TARGET_AIX)
+    {
+        /* AIX ifconfig will complain if it can't find ODM path in env */
+        struct env_set *aix_es = env_set_create(NULL);
+        env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
 
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
         if (tun)
         {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            remote_end = create_arbitrary_remote( tt );
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask %s up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        print_in_addr_t(remote_end, 0, &gc),
-                        tun_mtu,
-                        ifconfig_remote_netmask
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
+            msg(M_FATAL, "no tun support on AIX (canthappen)");
         }
 
+        /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
+
         argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed");
+        openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig failed");
         tt->did_ifconfig = true;
 
-        /* Add a network route for the local tun interface */
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = remote_end;
-            add_route(&r, tt, 0, NULL, es);
-        }
-
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed");
-        }
+        env_set_destroy(aix_es);
+    }
+#elif defined (_WIN32)
+    {
+        ASSERT(ifname != NULL);
 
-#elif defined(TARGET_AIX)
+        switch (tt->options.ip_win32_type)
         {
-            /* AIX ifconfig will complain if it can't find ODM path in env */
-            struct env_set *aix_es = env_set_create(NULL);
-            env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
-
-            if (tun)
-            {
-                msg(M_FATAL, "no tun support on AIX (canthappen)");
-            }
-
-            /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig failed");
-            tt->did_ifconfig = true;
+            case IPW32_SET_MANUAL:
+                msg(M_INFO,
+                    "******** NOTE:  Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
+                    ifname, ifconfig_local,
+                    print_in_addr_t(tt->adapter_netmask, 0, &gc));
+                break;
+            case IPW32_SET_NETSH:
+                netsh_ifconfig(&tt->options, ifname, tt->local,
+                               tt->adapter_netmask, NI_IP_NETMASK|NI_OPTIONS);
 
-            if (do_ipv6)
-            {
-                argv_printf(&argv,
-                            "%s %s inet6 %s/%d",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_ipv6_local,
-                            tt->netbits_ipv6
-                            );
-                argv_msg(M_INFO, &argv);
-                openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig inet6 failed");
-            }
-            env_set_destroy(aix_es);
+                break;
         }
-#elif defined (_WIN32)
-        {
-            ASSERT(actual != NULL);
+        tt->did_ifconfig = true;
+    }
 
-            switch (tt->options.ip_win32_type)
-            {
-                case IPW32_SET_MANUAL:
-                    msg(M_INFO, "******** NOTE:  Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
-                        actual,
-                        ifconfig_local,
-                        print_in_addr_t(tt->adapter_netmask, 0, &gc));
-                    break;
+#else  /* if defined(TARGET_LINUX) */
+    msg(M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
+#endif /* if defined(TARGET_LINUX) */
 
-                case IPW32_SET_NETSH:
-                    netsh_ifconfig(&tt->options,
-                                   actual,
-                                   tt->local,
-                                   tt->adapter_netmask,
-                                   NI_IP_NETMASK|NI_OPTIONS);
+    gc_free(&gc);
+    argv_reset(&argv);
+}
 
-                    break;
-            }
-            tt->did_ifconfig = true;
-        }
+/* execute the ifconfig command through the shell */
+void
+do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
+            const struct env_set *es)
+{
+    msg(D_LOW, "do_ifconfig, ipv4=%d, ipv6=%d", tt->did_ifconfig_setup,
+        tt->did_ifconfig_ipv6_setup);
 
-        if (do_ipv6)
-        {
-            if (tt->options.ip_win32_type == IPW32_SET_MANUAL)
-            {
-                msg(M_INFO, "******** NOTE:  Please manually set the v6 IP of '%s' to %s (if it is not already set)",
-                    actual,
-                    ifconfig_ipv6_local);
-            }
-            else if (tt->options.msg_channel)
-            {
-                do_address_service(true, AF_INET6, tt);
-                do_dns6_service(true, tt);
-            }
-            else
-            {
-                /* example: netsh interface ipv6 set address interface=42 2001:608:8003::d store=active */
-                char iface[64];
-                openvpn_snprintf(iface, sizeof(iface), "interface=%lu", tt->adapter_index );
-                argv_printf(&argv,
-                            "%s%sc interface ipv6 set address %s %s store=active",
-                            get_win_sys_path(),
-                            NETSH_PATH_SUFFIX,
-                            iface,
-                            ifconfig_ipv6_local );
-                netsh_command(&argv, 4, M_FATAL);
-                /* set ipv6 dns servers if any are specified */
-                netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, actual);
-            }
+#ifdef ENABLE_MANAGEMENT
+    if (management)
+    {
+        management_set_state(management,
+                             OPENVPN_STATE_ASSIGN_IP,
+                             NULL,
+                             &tt->local,
+                             &tt->local_ipv6,
+                             NULL,
+                             NULL);
+    }
+#endif
 
-            /* explicit route needed */
-            if (tt->options.ip_win32_type != IPW32_SET_MANUAL)
-            {
-                add_route_connected_v6_net(tt, es);
-            }
-        }
-#else  /* if defined(TARGET_LINUX) */
-        msg(M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
-#endif /* if defined(TARGET_LINUX) */
-        argv_reset(&argv);
+    if (tt->did_ifconfig_setup)
+    {
+        do_ifconfig_ipv4(tt, ifname, tun_mtu, es);
+    }
+
+    if (tt->did_ifconfig_ipv6_setup)
+    {
+        do_ifconfig_ipv6(tt, ifname, tun_mtu, es);
     }
-    gc_free(&gc);
 }
 
 static void
@@ -5865,7 +5713,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
 
     if (tt->type == DEV_TYPE_TUN)
     {
-        if (!tt->did_ifconfig_setup)
+        if (!tt->did_ifconfig_setup && !tt->did_ifconfig_ipv6_setup)
         {
             msg(M_FATAL, "ERROR: --dev tun also requires --ifconfig");
         }
src/openvpn/tun.h +9 -3
index 6c57ad0d..448a7738 100644
@@ -247,9 +247,15 @@ void init_tun_post(struct tuntap *tt,
 void do_ifconfig_setenv(const struct tuntap *tt,
                         struct env_set *es);
 
-void do_ifconfig(struct tuntap *tt,
-                 const char *actual,     /* actual device name */
-                 int tun_mtu,
+/**
+ * do_ifconfig - configure the tunnel interface
+ *
+ * @param tt        the tuntap interface context
+ * @param ifname    the human readable interface name
+ * @param mtu       the MTU value to set the interface to
+ * @param es        the environment to be used when executing the commands
+ */
+void do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
                  const struct env_set *es);
 
 bool is_dev_type(const char *dev, const char *dev_type, const char *match_type);
Signature · 1 line
2.17.1
#3 lore raw

Re: [Openvpn-devel] [PATCH v3] tun: ensure interface can be configured with IPv6 only

HI,

Quoted 5 lines · Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

This change ensures that an interface is properly brought up even when only IPv6 settings are configured/pushed.

Quoted 7 lines

At the same time, the do_ifconfig() function has been rearranged by splitting the logic into a v4 and a v6 specific part. Each part has then been moved into an idependent helper that can be invoked as needed.

This makes the code easier to read and more "symmetric" with respect to the two address families.

Thanks for the update with a somewhat more verbose commit message, and including the "changes from v2" bit.

Most of the changes are good, so "close to ACK"...

Staring at the resulting code, I saw something I hadn't noticed in v1/v2 - "MTU handling". For example, on Linux with IPROUTE, we now call this twice, once for IPv4 and once for IPv6

    /* set the MTU for the device and bring it up */
    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
                tun_mtu);
    argv_msg(M_INFO, &argv);
    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");

not sure if this has adverse effects, but it looks a tad silly in the logs... other platforms just set the MTU in the actual "ifconfig" call (if at all) so it's no new calls.

Another thing I noticed is that we really love to set tt->did_ifconfig (in every single platform branch in do_ifconfig_ipv6()) - maybe that one should be *renamed* to did_ifconfig_ipv4, and set only once...

... and of course close_tun() (all of them) needs to be adapted for the ipv6-only case. It currently does cleanup at program end, and that depends on "tt->did_ifconfig", which is only set of there is IPv4...

Looking more closely at Linux' close_tun(), I think tt->did_ifconfig can just go, and be replaced by

if (tt->did_ifconfig_ipv4_setup)

    { cleanup ipv4 }
  if (tt->did_ifconfig_ipv6_setup)
    { cleanup ipv6 }

(in each close_tun() function, for all platforms that have cleanups)

The idea behind tt->did_ifconfig seems to have been "only cleanup for those platforms that actually have an ifconfig strategy" - but since nobody except linux close_tun() ever *looks* at tt->did_ifconfig, it's just leftover bloat.

While at it, we might want to replace the big "if(tt) { ... }" wrapper around most of the close_tun() functions with a quick exit...

close_tun(...)

{
    if ( !tt )
    {
         return; 
    }

Or if we are daring, with an ASSERT(tt)... not sure if close_tun() can ever be called without a valid tuntap pointer... - well, the normal caller of close_tun() is "do_close_tun_simple()" in init.c, so we could just move it as "if(c->c1.tuntap) { close_tun(c->c1.tuntap); }" there... (there are also tuncfg() and solaris_error_close(), which both have a valid tt, always).

Reading through this, I think it would make sense to have a "0/8" pre-patch that gets rid of tt->did_ifconfig and gets rid of the if(tt) indentation in close_tun(), and then rebase 1/8 on top of that, and add ipv4/ipv6 differenciation to close_tun() where needed.

Anyway, at least the interface address removal bits need a v4 of this patch...

Quoted 1 line
Cc Gert Doering <[email protected]...>

And please no cc:' to me in commit messages - it slightly annoys me to receive mails twice with different headers, and serves no useful purpose.

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#4 lore raw

Re: [Openvpn-devel] [PATCH v3] **Android** note: tun: ensure interface can be configured with IPv6 only

In reply to Antonio Quartulli

Hi,

another reply to the same mail, on purpose, to keep thoughts in separate threads...

Quoted 7 lines · Antonio Quartulli

This change ensures that an interface is properly brought up even when only IPv6 settings are configured/pushed.

At the same time, the do_ifconfig() function has been rearranged by splitting the logic into a v4 and a v6 specific part. Each part has then been moved into an idependent helper that can be invoked as needed.

[..]

The existing Android code is different from all the other platforms, as it sends IPv6 info ("IFCONFIG6") *before* IPv4 info.

Arne, do I have to assume that this is intentional, and your client will explode if it receives IFCONFIG first and IFCONFIG6 second, or no IFCONFIG at all?

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#5 lore raw

Re: [Openvpn-devel] [PATCH v3] **Android** note: tun: ensure interface can be configured with IPv6 only

Am 12.06.18 um 11:29 schrieb Gert Doering:

Quoted 13 lines

Hi,

another reply to the same mail, on purpose, to keep thoughts in separate threads...

Quoted 7 lines · Antonio Quartulli

This change ensures that an interface is properly brought up even when only IPv6 settings are configured/pushed.

At the same time, the do_ifconfig() function has been rearranged by splitting the logic into a v4 and a v6 specific part. Each part has then been moved into an idependent helper that can be invoked as needed.

Quoted 8 lines

[..]

The existing Android code is different from all the other platforms, as it sends IPv6 info ("IFCONFIG6") *before* IPv4 info.

Arne, do I have to assume that this is intentional, and your client will explode if it receives IFCONFIG first and IFCONFIG6 second, or no IFCONFIG at all?

No ifconfig at at all will produce an error since ANdroid itself will not like to have no ifconfig at all. For the Android client it is only important that ifconfig/routes/etc. all happen before opening the tun device.

IPv6 only should be fine with my client.

Arne

#6 lore raw

Re: [Openvpn-devel] [PATCH v3] **Android** note: tun: ensure interface can be configured with IPv6 only

Hi,

Quoted 7 lines · Arne Schwabe
Quoted 6 lines

The existing Android code is different from all the other platforms, as it sends IPv6 info ("IFCONFIG6") *before* IPv4 info.

Arne, do I have to assume that this is intentional, and your client will explode if it receives IFCONFIG first and IFCONFIG6 second, or no IFCONFIG at all?

Quoted 6 lines

No ifconfig at at all will produce an error since ANdroid itself will not like to have no ifconfig at all. For the Android client it is only important that ifconfig/routes/etc. all happen before opening the tun device.

IPv6 only should be fine with my client.

So, to paraphrase this: you will handle IFCONFIG and IFCONFIG6 in either order or "just one of them" fine?

I was sort of assuming the code waits for an incoming IFCONFIG and then fires up the VPN API with "IFCONFIG and optional IFCONFIG6" - in which case, sending IFCONFIG first would have caused "fun effects with IFCONFIG6", and "not sending IFCONFIG at all" would cause interesting effects :-)

... but now I do seem to remember that you collect *all* information first (IFCONFIG* and ROUTE*), so it doesn't really matter in which order the "core" sends it...

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#7 lore raw

Re: [Openvpn-devel] [PATCH v3] **Android** note: tun: ensure interface can be configured with IPv6 only

Am 12.06.18 um 13:17 schrieb Gert Doering:

Quoted 20 lines

Hi,

Quoted 7 lines · Arne Schwabe
Quoted 6 lines

The existing Android code is different from all the other platforms, as it sends IPv6 info ("IFCONFIG6") *before* IPv4 info.

Arne, do I have to assume that this is intentional, and your client will explode if it receives IFCONFIG first and IFCONFIG6 second, or no IFCONFIG at all?

Quoted 6 lines

No ifconfig at at all will produce an error since ANdroid itself will not like to have no ifconfig at all. For the Android client it is only important that ifconfig/routes/etc. all happen before opening the tun device.

IPv6 only should be fine with my client.

So, to paraphrase this: you will handle IFCONFIG and IFCONFIG6 in either order or "just one of them" fine?

Quoted 8 lines

I was sort of assuming the code waits for an incoming IFCONFIG and then fires up the VPN API with "IFCONFIG and optional IFCONFIG6" - in which case, sending IFCONFIG first would have caused "fun effects with IFCONFIG6", and "not sending IFCONFIG at all" would cause interesting effects :-)

... but now I do seem to remember that you collect *all* information first (IFCONFIG* and ROUTE*), so it doesn't really matter in which order the "core" sends it...

Yeah, I do. At the moment I think I need ifconfig before route but that is not a bug issue to change that. Only thing that I really need is that opening TUN happens after everything else because after opening tun there no more changes possible.

Arne

#8 lore raw

Re: [Openvpn-devel] [PATCH v3] **Android** note: tun: ensure interface can be configured with IPv6 only

Hi,

Quoted 8 lines · Arne Schwabe
Quoted 3 lines

... but now I do seem to remember that you collect *all* information first (IFCONFIG* and ROUTE*), so it doesn't really matter in which order the "core" sends it...

Yeah, I do. At the moment I think I need ifconfig before route but that is not a bug issue to change that. Only thing that I really need is that opening TUN happens after everything else because after opening tun there no more changes possible.

Good. We won't change the open-after-ifconfig thing today :-)

(I am slightly tempted to tackle that one, eventually, as Android is the only platform left doing the "reverse order" dance now that windows has been changed to "normal" with the introduction of the iservice... but not today, or this month ;-) ).

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#9 lore raw

Re: [Openvpn-devel] [PATCH v3] tun: ensure interface can be configured with IPv6 only

In reply to Antonio Quartulli

Hi,

Quoted 2 lines · Antonio Quartulli

This change ensures that an interface is properly brought up even when only IPv6 settings are configured/pushed.

And more review, this time for actual code :-)

Quoted 2 lines
src/openvpn/tun.c +2 -0
+do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
+                 const struct env_set *es)

...

Quoted 1 line

+#elif defined(TARGET_SOLARIS)

...

src/openvpn/tun.c create_arbitrary_remote( struct tuntap *tt ) · line 924

Quoted 2 lines
src/openvpn/tun.c +2 -0
+        const char *ifconfig_ipv6_remote = print_in6_addr(tt->remote_ipv6, 0,
+                                                          gc);

As discussed on IRC, I find the dangling "gc);" more ugly than the old variant - so please keep the old formatting for now.

We might revisit this and rename all these long variables towards "local_ip" and "remote_ip", or ditch all of tun.c in the sitnl-internal-API- rewrite. We'll see. But not today, or this month.

src/openvpn/tun.c create_arbitrary_remote( struct tuntap *tt ) · line 960

Quoted 3 lines
src/openvpn/tun.c +3 -0
+#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
+    || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
+    || defined(TARGET_DRAGONFLY) || defined(TARGET_AIX)

I like the fact that all the BSDs can now be nicely joined into one common block - but please keep TARGET_AIX separate.

While it uses the same "ifconfig" call as the other 5, joining the block adds two new #ifdef clauses...

src/openvpn/tun.c create_arbitrary_remote( struct tuntap *tt ) · line 969

Quoted 5 lines
src/openvpn/tun.c +4 -0
+#if defined(TARGET_AIX)
+    /* AIX ifconfig will complain if it can't find ODM path in env */
+    es = env_set_create(NULL);
+    env_set_add(es, "ODMDIR=/etc/objrepos");
 #endif

... which, I think, warrant a dedicated #elif defined(TARGET_AIX) block ("contain the ugliness").

src/openvpn/tun.c create_arbitrary_remote( struct tuntap *tt ) · line 982

Quoted 5 lines
src/openvpn/tun.c +5 -0
+#if !defined(TARGET_FREEBSD) && !defined(TARGET_DRAGONFLY) \
+    && !defined(TARGET_AIX)
+    /* and, hooray, we explicitely need to add a route... */
+    add_route_connected_v6_net(tt, es);
+#endif

And here, please use positive matching - way easier to see which platform this applies to than going upwards for the encompassing #if TARGET_* block and negating parts of them.

If counting right, this would become

Review

Quoted 2 lines
(quoted diff) +2 -0
+#if defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) || \
+    defined(TARGET_DARWIN)

... easier to understand.

Quoted 1 line

+#elif defined (_WIN32)

[..]

src/openvpn/tun.c create_arbitrary_remote( struct tuntap *tt ) · line 998

Quoted 4 lines
src/openvpn/tun.c +4 -0
+    {
+        /* example: netsh interface ipv6 set address interface=42
+         * 2001:608:8003::d store=active
+         */

I can see why you want to wrap the netsh example command, but I find this not nice to read. What about:

+ /* example: netsh interface ipv6 set address interface=42
+ * 2001:608:8003::d store=active
+ */

so it's clear that this is a continuation line?

[..]

src/openvpn/tun.c create_arbitrary_remote( struct tuntap *tt ) · line 1018

Quoted 3 lines
src/openvpn/tun.c +3 -0
+#else  /* if defined(TARGET_LINUX) */
+    msg(M_FATAL, "Sorry, but I don't know how to do IPv6 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
+#endif  /* if defined(TARGET_LINUX) */

These two "defined(TARGET_LINUX)" are not your doing, but I think they should be removed. Neither is the "#else" being "the other option to TARGET_LINUX" nor is the #endif a simple "this is only TARGET_LINUX".

I'd either completely remove the comment or make it something like

#else /* platforms we have no IPv6 code for */

#endif /* outer #if defined(TARGET_xxx) conditional */

I think that's all I have to say about v3 so far :-)

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#10 lore raw

PATCH v4 1/8 tun: ensure interface can be configured with IPv6 only

In reply to Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

This change ensures that an interface is properly brought up and down even when only IPv6 settings are configured/pushed.

At the same time, some code restyling took place to ensure the new generic logic is easier to read. Both do_ifconfig() and close_tun() (Linux only) functions have been rearranged by splitting the logic into a v4 and a v6 specific part. Each part has then been moved into an idependent helper that can be invoked as
needed.

This makes the code easier to read and more "symmetric" with respect to the two address families.

Trac: #208

---

Changes from v2:
- rebased on top of master (fix conflict about D_LOW)
- commit message improved
Changes from v3:
- rebased on top of master (including pre-ipv6-only patchset)
- move AIX logic to its own ifdef block in do_ifconfig_ipv4()
- revert ifdef logic and make it inclusive inside *BSD ifdef block in do_ifconfig_ipv4()
- bring "gc);" back next to the other function call args
- improve comments on ifdef TARGET_xxx conditionals
- close_tun() re-arranged to handle ipv6-only tunnels
- close_tun() on linux splitted in two undo_ifconfig_ipv*()

 src/openvpn/tun.c | 1211 ++++++++++++++++++++-------------------------
 src/openvpn/tun.h |   12 +-
 2 files changed, 538 insertions(+), 685 deletions(-)
src/openvpn/tun.c +529 -682
index d8b972d0..878fd845 100644
@@ -871,714 +871,562 @@ create_arbitrary_remote( struct tuntap *tt )
 }
 #endif
 
-/* execute the ifconfig command through the shell */
-void
-do_ifconfig(struct tuntap *tt,
-            const char *actual,     /* actual device name */
-            int tun_mtu,
-            const struct env_set *es)
+/**
+ * do_ifconfig_ipv6 - perform platform specific ifconfig6 commands
+ *
+ * @param tt        the tuntap interface context
+ * @param ifname    the human readable interface name
+ * @param mtu       the MTU value to set the interface to
+ * @param es        the environment to be used when executing the commands
+ */
+static void
+do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
+                 const struct env_set *es)
 {
+    const char *ifconfig_ipv6_local = NULL;
+    struct argv argv = argv_new();
     struct gc_arena gc = gc_new();
 
-    if (tt->did_ifconfig_setup)
-    {
-        bool tun = false;
-        const char *ifconfig_local = NULL;
-        const char *ifconfig_remote_netmask = NULL;
-        const char *ifconfig_broadcast = NULL;
-        const char *ifconfig_ipv6_local = NULL;
-        bool do_ipv6 = false;
-        struct argv argv = argv_new();
+    ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
 
-        msg( D_LOW, "do_ifconfig, tt->did_ifconfig_ipv6_setup=%d",
-             tt->did_ifconfig_ipv6_setup );
+#if defined(TARGET_LINUX)
+#ifdef ENABLE_IPROUTE
+    /* set the MTU for the device and bring it up */
+    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
+                tun_mtu);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
 
-        /*
-         * We only handle TUN/TAP devices here, not --dev null devices.
-         */
-        tun = is_tun_p2p(tt);
+    argv_printf(&argv, "%s -6 addr add %s/%d dev %s", iproute_path,
+                ifconfig_ipv6_local, tt->netbits_ipv6, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip -6 addr add failed");
+#else
+    argv_printf(&argv, "%s %s add %s/%d mtu %d up", IFCONFIG_PATH, ifname,
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
+#endif
+#elif defined(TARGET_ANDROID)
+    char out6[64];
 
-        /*
-         * Set ifconfig parameters
-         */
-        ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
-        ifconfig_remote_netmask = print_in_addr_t(tt->remote_netmask, 0, &gc);
+    openvpn_snprintf(out6, sizeof(out6), "%s/%d",
+                     ifconfig_ipv6_local,tt->netbits_ipv6);
+    management_android_control(management, "IFCONFIG6", out6);
+#elif defined(TARGET_SOLARIS)
+    argv_printf(&argv, "%s %s inet6 unplumb", IFCONFIG_PATH, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, 0, NULL);
 
-        if (tt->did_ifconfig_ipv6_setup)
+    if (tt->type == DEV_TYPE_TUN)
+    {
+        const char *ifconfig_ipv6_remote = print_in6_addr(tt->remote_ipv6, 0, gc);
+
+        argv_printf(&argv, "%s %s inet6 plumb %s/%d %s mtu %d up",
+                    IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
+                    tt->netbits_ipv6, ifconfig_ipv6_remote, tun_mtu);
+    }
+    else /* tap mode */
+    {
+        /* base IPv6 tap interface needs to be brought up first */
+        argv_printf(&argv, "%s %s inet6 plumb up", IFCONFIG_PATH, ifname);
+        argv_msg(M_INFO, &argv);
+
+        if (!openvpn_execve_check(&argv, es, 0,
+                                  "Solaris ifconfig IPv6 (prepare) failed"))
         {
-            ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
-            do_ipv6 = true;
+            solaris_error_close(tt, es, ifname, true);
         }
 
-        /*
-         * If TAP-style device, generate broadcast address.
+        /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
+         * after the system has noticed the interface and fired up
+         * the DHCPv6 client - but this takes quite a while, and the
+         * server will ignore the DHCPv6 packets anyway.  So we don't.
          */
-        if (!tun)
-        {
-            ifconfig_broadcast = print_in_addr_t(tt->broadcast, 0, &gc);
-        }
 
-#ifdef ENABLE_MANAGEMENT
-        if (management)
-        {
-            management_set_state(management,
-                                 OPENVPN_STATE_ASSIGN_IP,
-                                 NULL,
-                                 &tt->local,
-                                 &tt->local_ipv6,
-                                 NULL,
-                                 NULL);
-        }
+        /* static IPv6 addresses need to go to a subinterface (tap0:1) */
+        argv_printf(&argv, "%s %s inet6 addif %s/%d mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    }
+    argv_msg(M_INFO, &argv);
+
+    if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 failed"))
+    {
+        solaris_error_close(tt, es, ifname, true);
+    }
+#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
+    || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
+    || defined(TARGET_DRAGONFLY)
+    argv_printf(&argv, "%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    argv_msg(M_INFO, &argv);
+
+    openvpn_execve_check(&argv, es, S_FATAL,
+                         "generic BSD ifconfig inet6 failed");
+
+#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
+    || defined(TARGET_DARWIN)
+    /* and, hooray, we explicitely need to add a route... */
+    add_route_connected_v6_net(tt, es);
 #endif
+#elif defined(TARGET_AIX)
+    argv_printf(&argv, "%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    argv_msg(M_INFO, &argv);
 
+    /* AIX ifconfig will complain if it can't find ODM path in env */
+    es = env_set_create(NULL);
+    env_set_add(es, "ODMDIR=/etc/objrepos");
 
-#if defined(TARGET_LINUX)
-#ifdef ENABLE_IPROUTE
-        /*
-         * Set the MTU for the device
-         */
-        argv_printf(&argv,
-                    "%s link set dev %s up mtu %d",
-                    iproute_path,
-                    actual,
-                    tun_mtu
-                    );
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
+    openvpn_execve_check(&argv, es, S_FATAL,
+                         "generic BSD ifconfig inet6 failed");
 
-        if (tun)
-        {
+    env_set_destroy(es);
+#elif defined (_WIN32)
+    if (tt->options.ip_win32_type == IPW32_SET_MANUAL)
+    {
+        msg(M_INFO, "******** NOTE:  Please manually set the v6 IP of '%s' to %s (if it is not already set)",
+            ifname, ifconfig_ipv6_local);
+    }
+    else if (tt->options.msg_channel)
+    {
+        do_address_service(true, AF_INET6, tt);
+        do_dns6_service(true, tt);
+    }
+    else
+    {
+        /* example: netsh interface ipv6 set address interface=42
+         *                  2001:608:8003::d store=active
+         */
+        char iface[64];
 
-            /*
-             * Set the address for the device
-             */
-            argv_printf(&argv,
-                        "%s addr add dev %s local %s peer %s",
-                        iproute_path,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s addr add dev %s %s/%d broadcast %s",
-                        iproute_path,
-                        actual,
-                        ifconfig_local,
-                        netmask_to_netbits2(tt->remote_netmask),
-                        ifconfig_broadcast
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
-        }
-        if (do_ipv6)
-        {
-            argv_printf( &argv,
-                         "%s -6 addr add %s/%d dev %s",
-                         iproute_path,
-                         ifconfig_ipv6_local,
-                         tt->netbits_ipv6,
-                         actual
-                         );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip -6 addr add failed");
-        }
-#else  /* ifdef ENABLE_IPROUTE */
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s pointopoint %s mtu %d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d broadcast %s",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu,
-                        ifconfig_broadcast
-                        );
-        }
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig failed");
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s add %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
-        }
+        openvpn_snprintf(iface, sizeof(iface), "interface=%lu",
+                         tt->adapter_index);
+        argv_printf(&argv, "%s%sc interface ipv6 set address %s %s store=active",
+                    get_win_sys_path(), NETSH_PATH_SUFFIX, iface,
+                    ifconfig_ipv6_local);
+        netsh_command(&argv, 4, M_FATAL);
+        /* set ipv6 dns servers if any are specified */
+        netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, ifname);
+    }
 
-#endif /*ENABLE_IPROUTE*/
-#elif defined(TARGET_ANDROID)
+    /* explicit route needed */
+    if (tt->options.ip_win32_type != IPW32_SET_MANUAL)
+    {
+        add_route_connected_v6_net(tt, es);
+    }
+#else /* platforms we have no IPv6 code for */
+    msg(M_FATAL, "Sorry, but I don't know how to do IPv6 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
+#endif /* outer "if defined(TARGET_xxx)" conditional */
 
-        if (do_ipv6)
-        {
-            char out6[64];
-            openvpn_snprintf(out6, sizeof(out6), "%s/%d", ifconfig_ipv6_local,tt->netbits_ipv6);
-            management_android_control(management, "IFCONFIG6", out6);
-        }
+    gc_free(&gc);
+    argv_reset(&argv);
+}
 
-        char out[64];
+/**
+ * do_ifconfig_ipv4 - perform platform specific ifconfig commands
+ *
+ * @param tt        the tuntap interface context
+ * @param ifname    the human readable interface name
+ * @param mtu       the MTU value to set the interface to
+ * @param es        the environment to be used when executing the commands
+ */
+static void
+do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
+                 const struct env_set *es)
+{
+    bool tun = false;
+    const char *ifconfig_local = NULL;
+    const char *ifconfig_remote_netmask = NULL;
+    const char *ifconfig_broadcast = NULL;
+    struct argv argv = argv_new();
+    struct gc_arena gc = gc_new();
 
-        char *top;
-        switch (tt->topology)
-        {
-            case TOP_NET30:
-                top = "net30";
-                break;
+    /*
+     * We only handle TUN/TAP devices here, not --dev null devices.
+     */
+    tun = is_tun_p2p(tt);
 
-            case TOP_P2P:
-                top = "p2p";
-                break;
+    /*
+     * Set ifconfig parameters
+     */
+    ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
+    ifconfig_remote_netmask = print_in_addr_t(tt->remote_netmask, 0, &gc);
 
-            case TOP_SUBNET:
-                top = "subnet";
-                break;
+    /*
+     * If TAP-style device, generate broadcast address.
+     */
+    if (!tun)
+    {
+        ifconfig_broadcast = print_in_addr_t(tt->broadcast, 0, &gc);
+    }
 
-            default:
-                top = "undef";
-        }
+#if defined(TARGET_LINUX)
+#ifdef ENABLE_IPROUTE
+    /*
+     * Set the MTU for the device
+     */
+    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
+                tun_mtu);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
 
-        openvpn_snprintf(out, sizeof(out), "%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu, top);
-        management_android_control(management, "IFCONFIG", out);
+    if (tun)
+    {
 
-#elif defined(TARGET_SOLARIS)
-        /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
-         * example:
-         *    ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
-         *    ifconfig tun2 netmask 255.255.255.255
+        /*
+         * Set the address for the device
          */
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-
-            argv_msg(M_INFO, &argv);
-            if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-1 failed"))
-            {
-                solaris_error_close(tt, es, actual, false);
-            }
+        argv_printf(&argv, "%s addr add dev %s local %s peer %s", iproute_path,
+                    ifname, ifconfig_local, ifconfig_remote_netmask);
+        argv_msg(M_INFO, &argv);
+        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
+    }
+    else
+    {
+        argv_printf(&argv, "%s addr add dev %s %s/%d broadcast %s",
+                    iproute_path, ifname, ifconfig_local,
+                    netmask_to_netbits2(tt->remote_netmask),
+                    ifconfig_broadcast);
+        argv_msg(M_INFO, &argv);
+        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
+    }
+#else  /* ifdef ENABLE_IPROUTE */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s pointopoint %s mtu %d", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+    }
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig failed");
 
-            argv_printf(&argv,
-                        "%s %s netmask 255.255.255.255",
-                        IFCONFIG_PATH,
-                        actual
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s netmask %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        " %s %s %s netmask %s broadcast + up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask
-                        );
-        }
+#endif /*ENABLE_IPROUTE*/
+#elif defined(TARGET_ANDROID)
+    char out[64];
 
-        argv_msg(M_INFO, &argv);
-        if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-2 failed"))
-        {
-            solaris_error_close(tt, es, actual, false);
-        }
+    char *top;
+    switch (tt->topology)
+    {
+        case TOP_NET30:
+            top = "net30";
+            break;
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv, "%s %s inet6 unplumb",
-                        IFCONFIG_PATH, actual );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, 0, NULL);
+        case TOP_P2P:
+            top = "p2p";
+            break;
 
-            if (tt->type == DEV_TYPE_TUN)
-            {
-                const char *ifconfig_ipv6_remote =
-                    print_in6_addr(tt->remote_ipv6, 0, &gc);
+        case TOP_SUBNET:
+            top = "subnet";
+            break;
 
-                argv_printf(&argv,
-                            "%s %s inet6 plumb %s/%d %s up",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_ipv6_local,
-                            tt->netbits_ipv6,
-                            ifconfig_ipv6_remote
-                            );
-            }
-            else                                        /* tap mode */
-            {
-                /* base IPv6 tap interface needs to be brought up first
-                 */
-                argv_printf(&argv, "%s %s inet6 plumb up",
-                            IFCONFIG_PATH, actual );
-                argv_msg(M_INFO, &argv);
-                if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 (prepare) failed"))
-                {
-                    solaris_error_close(tt, es, actual, true);
-                }
+        default:
+            top = "undef";
+    }
 
-                /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
-                 * after the system has noticed the interface and fired up
-                 * the DHCPv6 client - but this takes quite a while, and the
-                 * server will ignore the DHCPv6 packets anyway.  So we don't.
-                 */
+    openvpn_snprintf(out, sizeof(out), "%s %s %d %s", ifconfig_local,
+                     ifconfig_remote_netmask, tun_mtu, top);
+    management_android_control(management, "IFCONFIG", out);
 
-                /* static IPv6 addresses need to go to a subinterface (tap0:1)
-                 */
-                argv_printf(&argv,
-                            "%s %s inet6 addif %s/%d up",
-                            IFCONFIG_PATH, actual,
-                            ifconfig_ipv6_local, tt->netbits_ipv6 );
-            }
-            argv_msg(M_INFO, &argv);
-            if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 failed"))
-            {
-                solaris_error_close(tt, es, actual, true);
-            }
-        }
+#elif defined(TARGET_SOLARIS)
+    /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
+     * example:
+     *    ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
+     *    ifconfig tun2 netmask 255.255.255.255
+     */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d up", IFCONFIG_PATH, ifname,
+                    ifconfig_local, ifconfig_remote_netmask, tun_mtu);
 
-        if (!tun && tt->topology == TOP_SUBNET)
+        argv_msg(M_INFO, &argv);
+        if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-1 failed"))
         {
-            /* Add a network route for the local tun interface */
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED | RT_METRIC_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = tt->local;
-            r.metric = 0;
-            add_route(&r, tt, 0, NULL, es);
+            solaris_error_close(tt, es, ifname, false);
         }
 
-#elif defined(TARGET_OPENBSD)
-
-        in_addr_t remote_end;           /* for "virtual" subnet topology */
-
-        /*
-         * On OpenBSD, tun interfaces are persistent if created with
-         * "ifconfig tunX create", and auto-destroyed if created by
-         * opening "/dev/tunX" (so we just use the /dev/tunX)
-         */
+        argv_printf(&argv, "%s %s netmask 255.255.255.255", IFCONFIG_PATH,
+                    ifname);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s broadcast + up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask);
+    }
 
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            remote_end = create_arbitrary_remote( tt );
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask %s up -link0",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        print_in_addr_t(remote_end, 0, &gc),
-                        tun_mtu,
-                        ifconfig_remote_netmask
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d broadcast %s link0",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu,
-                        ifconfig_broadcast
-                        );
-        }
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed");
+    argv_msg(M_INFO, &argv);
+    if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-2 failed"))
+    {
+        solaris_error_close(tt, es, ifname, false);
+    }
 
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
         /* Add a network route for the local tun interface */
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = remote_end;
-            add_route(&r, tt, 0, NULL, es);
-        }
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED | RT_METRIC_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = tt->local;
+        r.metric = 0;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig inet6 failed");
+#elif defined(TARGET_OPENBSD)
 
-            /* and, hooray, we explicitely need to add a route... */
-            add_route_connected_v6_net(tt, es);
-        }
+    in_addr_t remote_end;           /* for "virtual" subnet topology */
 
-#elif defined(TARGET_NETBSD)
+    /*
+     * On OpenBSD, tun interfaces are persistent if created with
+     * "ifconfig tunX create", and auto-destroyed if created by
+     * opening "/dev/tunX" (so we just use the /dev/tunX)
+     */
 
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask %s up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_local,
-                        tun_mtu,
-                        ifconfig_remote_netmask
-                        );
-        }
-        else
-        {
-            /*
-             * NetBSD has distinct tun and tap devices
-             * so we don't need the "link0" extra parameter to specify we want to do
-             * tunneling at the ethernet level
-             */
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d broadcast %s",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu,
-                        ifconfig_broadcast
-                        );
-        }
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed");
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
+    if (tun)
+    {
+        argv_printf(&argv,
+                    "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        remote_end = create_arbitrary_remote( tt );
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up -link0",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    print_in_addr_t(remote_end, 0, &gc), tun_mtu,
+                    ifconfig_remote_netmask);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s link0",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+    }
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed");
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig inet6 failed");
+    /* Add a network route for the local tun interface */
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = remote_end;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-            /* and, hooray, we explicitely need to add a route... */
-            add_route_connected_v6_net(tt, es);
-        }
+#elif defined(TARGET_NETBSD)
 
-#elif defined(TARGET_DARWIN)
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_local, tun_mtu,
+                    ifconfig_remote_netmask);
+    }
+    else
+    {
         /*
-         * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
+         * NetBSD has distinct tun and tap devices
+         * so we don't need the "link0" extra parameter to specify we want to do
+         * tunneling at the ethernet level
          */
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+    }
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed");
 
-        argv_printf(&argv,
-                    "%s %s delete",
-                    IFCONFIG_PATH,
-                    actual);
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, 0, NULL);
-        msg(M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
+#elif defined(TARGET_DARWIN)
+    /*
+     * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
+     */
+
+    argv_printf(&argv, "%s %s delete", IFCONFIG_PATH, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, 0, NULL);
+    msg(M_INFO,
+        "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
 
 
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
-        if (tun)
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else
+    {
+        if (tt->topology == TOP_SUBNET)
         {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
+            argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up",
+                        IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_local,
+                        ifconfig_remote_netmask, tun_mtu);
         }
         else
         {
-            if (tt->topology == TOP_SUBNET)
-            {
-                argv_printf(&argv,
-                            "%s %s %s %s netmask %s mtu %d up",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_local,
-                            ifconfig_local,
-                            ifconfig_remote_netmask,
-                            tun_mtu
-                            );
-            }
-            else
-            {
-                argv_printf(&argv,
-                            "%s %s %s netmask %s mtu %d up",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_local,
-                            ifconfig_remote_netmask,
-                            tun_mtu
-                            );
-            }
+            argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                        ifname, ifconfig_local, ifconfig_remote_netmask,
+                        tun_mtu);
         }
+    }
 
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed");
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed");
 
-        /* Add a network route for the local tun interface */
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = tt->local;
-            add_route(&r, tt, 0, NULL, es);
-        }
+    /* Add a network route for the local tun interface */
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = tt->local;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "MacOS X ifconfig inet6 failed");
+#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
 
-            /* and, hooray, we explicitely need to add a route... */
-            add_route_connected_v6_net(tt, es);
-        }
+    in_addr_t remote_end;           /* for "virtual" subnet topology */
 
-#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        remote_end = create_arbitrary_remote( tt );
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, print_in_addr_t(remote_end, 0, &gc),
+                    tun_mtu, ifconfig_remote_netmask);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
+    }
+
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed");
+
+    /* Add a network route for the local tun interface */
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = remote_end;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-        in_addr_t remote_end;           /* for "virtual" subnet topology */
+#elif defined(TARGET_AIX)
+    {
+        /* AIX ifconfig will complain if it can't find ODM path in env */
+        struct env_set *aix_es = env_set_create(NULL);
+        env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
 
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
         if (tun)
         {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            remote_end = create_arbitrary_remote( tt );
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask %s up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        print_in_addr_t(remote_end, 0, &gc),
-                        tun_mtu,
-                        ifconfig_remote_netmask
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
+            msg(M_FATAL, "no tun support on AIX (canthappen)");
         }
 
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed");
+        /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
 
-        /* Add a network route for the local tun interface */
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = remote_end;
-            add_route(&r, tt, 0, NULL, es);
-        }
+        argv_msg(M_INFO, &argv);
+        openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig failed");
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed");
-        }
+        env_set_destroy(aix_es);
+    }
+#elif defined (_WIN32)
+    {
+        ASSERT(ifname != NULL);
 
-#elif defined(TARGET_AIX)
+        switch (tt->options.ip_win32_type)
         {
-            /* AIX ifconfig will complain if it can't find ODM path in env */
-            struct env_set *aix_es = env_set_create(NULL);
-            env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
-
-            if (tun)
-            {
-                msg(M_FATAL, "no tun support on AIX (canthappen)");
-            }
+            case IPW32_SET_MANUAL:
+                msg(M_INFO,
+                    "******** NOTE:  Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
+                    ifname, ifconfig_local,
+                    print_in_addr_t(tt->adapter_netmask, 0, &gc));
+                break;
+            case IPW32_SET_NETSH:
+                netsh_ifconfig(&tt->options, ifname, tt->local,
+                               tt->adapter_netmask, NI_IP_NETMASK|NI_OPTIONS);
 
-            /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig failed");
-
-            if (do_ipv6)
-            {
-                argv_printf(&argv,
-                            "%s %s inet6 %s/%d",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_ipv6_local,
-                            tt->netbits_ipv6
-                            );
-                argv_msg(M_INFO, &argv);
-                openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig inet6 failed");
-            }
-            env_set_destroy(aix_es);
+                break;
         }
-#elif defined (_WIN32)
-        {
-            ASSERT(actual != NULL);
+    }
 
-            switch (tt->options.ip_win32_type)
-            {
-                case IPW32_SET_MANUAL:
-                    msg(M_INFO, "******** NOTE:  Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
-                        actual,
-                        ifconfig_local,
-                        print_in_addr_t(tt->adapter_netmask, 0, &gc));
-                    break;
+#else  /* if defined(TARGET_LINUX) */
+    msg(M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
+#endif /* if defined(TARGET_LINUX) */
 
-                case IPW32_SET_NETSH:
-                    netsh_ifconfig(&tt->options,
-                                   actual,
-                                   tt->local,
-                                   tt->adapter_netmask,
-                                   NI_IP_NETMASK|NI_OPTIONS);
+    gc_free(&gc);
+    argv_reset(&argv);
+}
 
-                    break;
-            }
-        }
+/* execute the ifconfig command through the shell */
+void
+do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
+            const struct env_set *es)
+{
+    msg(D_LOW, "do_ifconfig, ipv4=%d, ipv6=%d", tt->did_ifconfig_setup,
+        tt->did_ifconfig_ipv6_setup);
 
-        if (do_ipv6)
-        {
-            if (tt->options.ip_win32_type == IPW32_SET_MANUAL)
-            {
-                msg(M_INFO, "******** NOTE:  Please manually set the v6 IP of '%s' to %s (if it is not already set)",
-                    actual,
-                    ifconfig_ipv6_local);
-            }
-            else if (tt->options.msg_channel)
-            {
-                do_address_service(true, AF_INET6, tt);
-                do_dns6_service(true, tt);
-            }
-            else
-            {
-                /* example: netsh interface ipv6 set address interface=42 2001:608:8003::d store=active */
-                char iface[64];
-                openvpn_snprintf(iface, sizeof(iface), "interface=%lu", tt->adapter_index );
-                argv_printf(&argv,
-                            "%s%sc interface ipv6 set address %s %s store=active",
-                            get_win_sys_path(),
-                            NETSH_PATH_SUFFIX,
-                            iface,
-                            ifconfig_ipv6_local );
-                netsh_command(&argv, 4, M_FATAL);
-                /* set ipv6 dns servers if any are specified */
-                netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, actual);
-            }
+#ifdef ENABLE_MANAGEMENT
+    if (management)
+    {
+        management_set_state(management,
+                             OPENVPN_STATE_ASSIGN_IP,
+                             NULL,
+                             &tt->local,
+                             &tt->local_ipv6,
+                             NULL,
+                             NULL);
+    }
+#endif
 
-            /* explicit route needed */
-            if (tt->options.ip_win32_type != IPW32_SET_MANUAL)
-            {
-                add_route_connected_v6_net(tt, es);
-            }
-        }
-#else  /* if defined(TARGET_LINUX) */
-        msg(M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
-#endif /* if defined(TARGET_LINUX) */
-        argv_reset(&argv);
+    if (tt->did_ifconfig_setup)
+    {
+        do_ifconfig_ipv4(tt, ifname, tun_mtu, es);
+    }
+
+    if (tt->did_ifconfig_ipv6_setup)
+    {
+        do_ifconfig_ipv6(tt, ifname, tun_mtu, es);
     }
-    gc_free(&gc);
 }
 
 static void
@@ -2089,77 +1937,76 @@ tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_
 
 #endif /* ENABLE_FEATURE_TUN_PERSIST */
 
+void
+undo_ifconfig_ipv4(struct tuntap *tt, struct gc_arena *gc)
+{
+    struct argv argv = argv_new();
+
+#ifdef ENABLE_IPROUTE
+    if (is_tun_p2p(tt))
+    {
+        argv_printf(&argv, "%s addr del dev %s local %s peer %s", iproute_path,
+                    tt->actual_name, print_in_addr_t(tt->local, 0, gc),
+                    print_in_addr_t(tt->remote_netmask, 0, gc));
+    }
+    else
+    {
+        argv_printf(&argv, "%s addr del dev %s %s/%d", iproute_path,
+                    tt->actual_name, print_in_addr_t(tt->local, 0, gc),
+                    netmask_to_netbits2(tt->remote_netmask));
+    }
+#else  /* ifdef ENABLE_IPROUTE */
+    argv_printf(&argv, "%s %s 0.0.0.0", IFCONFIG_PATH, tt->actual_name);
+#endif /* ifdef ENABLE_IPROUTE */
+
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, NULL, 0, "Linux ip addr del failed");
+
+    argv_reset(&argv);
+}
+
+void
+undo_ifconfig_ipv6(struct tuntap *tt, struct gc_arena *gc)
+{
+    const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, gc);
+    struct argv argv = argv_new();
+
+#ifdef ENABLE_IPROUTE
+    argv_printf(&argv, "%s -6 addr del %s/%d dev %s", iproute_path,
+                ifconfig_ipv6_local, tt->netbits_ipv6, tt->actual_name);
+#else  /* ifdef ENABLE_IPROUTE */
+    argv_printf(&argv, "%s %s del %s/%d", IFCONFIG_PATH, tt->actual_name,
+                ifconfig_ipv6_local, tt->netbits_ipv6);
+#endif
+
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, NULL, 0, "Linux ip -6 addr del failed");
+
+    argv_reset(&argv);
+}
+
 void
 close_tun(struct tuntap *tt)
 {
     ASSERT(tt);
 
-    if (tt->type != DEV_TYPE_NULL && tt->did_ifconfig_setup)
+    if (tt->type != DEV_TYPE_NULL)
     {
-        struct argv argv = argv_new();
         struct gc_arena gc = gc_new();
 
-#ifdef ENABLE_IPROUTE
-        if (is_tun_p2p(tt))
+        if (tt->did_ifconfig_setup)
         {
-            argv_printf(&argv,
-                        "%s addr del dev %s local %s peer %s",
-                        iproute_path,
-                        tt->actual_name,
-                        print_in_addr_t(tt->local, 0, &gc),
-                        print_in_addr_t(tt->remote_netmask, 0, &gc)
-                       );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s addr del dev %s %s/%d",
-                        iproute_path,
-                        tt->actual_name,
-                        print_in_addr_t(tt->local, 0, &gc),
-                        netmask_to_netbits2(tt->remote_netmask)
-                       );
+            undo_ifconfig_ipv4(tt, &gc);
         }
-#else  /* ifdef ENABLE_IPROUTE */
-        argv_printf(&argv,
-                    "%s %s 0.0.0.0",
-                    IFCONFIG_PATH,
-                    tt->actual_name
-                   );
-#endif /* ifdef ENABLE_IPROUTE */
-
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, NULL, 0, "Linux ip addr del failed");
 
         if (tt->did_ifconfig_ipv6_setup)
         {
-            const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
-
-#ifdef ENABLE_IPROUTE
-            argv_printf(&argv, "%s -6 addr del %s/%d dev %s",
-                        iproute_path,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6,
-                        tt->actual_name
-                       );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, NULL, 0, "Linux ip -6 addr del failed");
-#else  /* ifdef ENABLE_IPROUTE */
-            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 ifconfig inet6 del failed");
-#endif
+            undo_ifconfig_ipv6(tt, &gc);
         }
 
-        argv_reset(&argv);
         gc_free(&gc);
     }
+
     close_tun_generic(tt);
     free(tt);
 }
@@ -5851,7 +5698,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
 
     if (tt->type == DEV_TYPE_TUN)
     {
-        if (!tt->did_ifconfig_setup)
+        if (!tt->did_ifconfig_setup && !tt->did_ifconfig_ipv6_setup)
         {
             msg(M_FATAL, "ERROR: --dev tun also requires --ifconfig");
         }
src/openvpn/tun.h +9 -3
index 9495d602..cb1ab1cc 100644
@@ -246,9 +246,15 @@ void init_tun_post(struct tuntap *tt,
 void do_ifconfig_setenv(const struct tuntap *tt,
                         struct env_set *es);
 
-void do_ifconfig(struct tuntap *tt,
-                 const char *actual,     /* actual device name */
-                 int tun_mtu,
+/**
+ * do_ifconfig - configure the tunnel interface
+ *
+ * @param tt        the tuntap interface context
+ * @param ifname    the human readable interface name
+ * @param mtu       the MTU value to set the interface to
+ * @param es        the environment to be used when executing the commands
+ */
+void do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
                  const struct env_set *es);
 
 bool is_dev_type(const char *dev, const char *dev_type, const char *match_type);
Signature · 1 line
2.17.1
#11 lore raw

Re: [Openvpn-devel] [PATCH v4 1/8] tun: ensure interface can be configured with IPv6 only

Hi,

Quoted 12 lines · Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

This change ensures that an interface is properly brought up and down even when only IPv6 settings are configured/pushed.

At the same time, some code restyling took place to ensure the new generic logic is easier to read. Both do_ifconfig() and close_tun() (Linux only) functions have been rearranged by splitting the logic into a v4 and a v6 specific part. Each part has then been moved into an idependent helper that can be invoked as
needed.

Quoted 5 lines

This makes the code easier to read and more "symmetric" with respect to the two address families.

Trac: #208

Thanks. Can I have a v5, please, that has been buildbot-compile-tested...?

This version breaks OpenSolaris, as

src/openvpn/tun.c create_arbitrary_remote( struct tuntap *tt ) · line 924

Quoted 10 lines
src/openvpn/tun.c +8 -1
+#elif defined(TARGET_SOLARIS)
+    argv_printf(&argv, "%s %s inet6 unplumb", IFCONFIG_PATH, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, 0, NULL);
 
-        if (tt->did_ifconfig_ipv6_setup)
+    if (tt->type == DEV_TYPE_TUN)
+    {
+        const char *ifconfig_ipv6_remote = print_in6_addr(tt->remote_ipv6, 0, gc);
+

... this has to be "&gc"... so, I do understand that you really do not like this line, but please...

Besides this, I've not only compiled but actually tested IPv6-only mode on Linux (Gentoo), FreeBSD (10.4), NetBSD (7.0), OpenSolaris (with the trival patch), OpenBSD 6.0, MacOS X (something current, Arne's box).

Haven't tested Windows yet as we know it will not work until 2/8 is merged (IPv4-only or IPv4+IPv6 is expected to be unaffected) - but it builds fine, so no larger accidents.

All the other code changes look reasonable ("git diff -w --color-moved=zebra" plus "visually comparing with a pre-patch tun.c").

Since we're a bit strict about code changes that are bigger than whitespace and comments... can I have a v5, please?

gert

PS: Side note 1: MacOS is actually slightly strange and needs repair - the call to (e.g.) "ifconfig utun1 delete" actually doesn't "delete" anything but tries to find a host named "delete" and ifconfig it on "utun1"... but this is old stuff which propably worked 5 MacOS versions ago... and the on-link route might also no longer be needed. Need to test this on "more MacOS versions", plus look at the MacOS patch that is lingering on the list...

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#12 lore raw

PATCH v5 1/8 tun: ensure interface can be configured with IPv6 only

In reply to Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

This change ensures that an interface is properly brought up and down even when only IPv6 settings are configured/pushed.

At the same time, some code restyling took place to ensure the new generic logic is easier to read. Both do_ifconfig() and close_tun() (Linux only) functions have been rearranged by splitting the logic into a v4 and a v6 specific part. Each part has then been moved into an idependent helper that can be invoked as
needed.

This makes the code easier to read and more "symmetric" with respect to the two address families.

Trac: #208

---

Changes from v2:
- rebased on top of master (fix conflict about D_LOW)
- commit message improved
Changes from v3:
- patchset rebased on top of the pre-ipv6-only patchset
- move AIX logic to its own ifdef block in do_ifconfig_ipv4()
- revert ifdef logic and make it inclusive inside *BSD ifdef block in do_ifconfig_ipv4()
- bring "gc);" back next to the other function call args
- improve comments on ifdef TARGET_xxx conditionals
- close_tun() re-arranged to handle ipv6-only tunnels
- close_tun() on linux split in two undo_ifconfig_ipv*() Changes from v4:
- fix syntax issue in TARGET_OPENSOLARIS section (prepend '&' to gc)

 src/openvpn/tun.c | 1211 ++++++++++++++++++++-------------------------
 src/openvpn/tun.h |   12 +-
 2 files changed, 538 insertions(+), 685 deletions(-)
src/openvpn/tun.c +529 -682
index d8b972d0..2e1c96e6 100644
@@ -871,714 +871,562 @@ create_arbitrary_remote( struct tuntap *tt )
 }
 #endif
 
-/* execute the ifconfig command through the shell */
-void
-do_ifconfig(struct tuntap *tt,
-            const char *actual,     /* actual device name */
-            int tun_mtu,
-            const struct env_set *es)
+/**
+ * do_ifconfig_ipv6 - perform platform specific ifconfig6 commands
+ *
+ * @param tt        the tuntap interface context
+ * @param ifname    the human readable interface name
+ * @param mtu       the MTU value to set the interface to
+ * @param es        the environment to be used when executing the commands
+ */
+static void
+do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
+                 const struct env_set *es)
 {
+    const char *ifconfig_ipv6_local = NULL;
+    struct argv argv = argv_new();
     struct gc_arena gc = gc_new();
 
-    if (tt->did_ifconfig_setup)
-    {
-        bool tun = false;
-        const char *ifconfig_local = NULL;
-        const char *ifconfig_remote_netmask = NULL;
-        const char *ifconfig_broadcast = NULL;
-        const char *ifconfig_ipv6_local = NULL;
-        bool do_ipv6 = false;
-        struct argv argv = argv_new();
+    ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
 
-        msg( D_LOW, "do_ifconfig, tt->did_ifconfig_ipv6_setup=%d",
-             tt->did_ifconfig_ipv6_setup );
+#if defined(TARGET_LINUX)
+#ifdef ENABLE_IPROUTE
+    /* set the MTU for the device and bring it up */
+    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
+                tun_mtu);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
 
-        /*
-         * We only handle TUN/TAP devices here, not --dev null devices.
-         */
-        tun = is_tun_p2p(tt);
+    argv_printf(&argv, "%s -6 addr add %s/%d dev %s", iproute_path,
+                ifconfig_ipv6_local, tt->netbits_ipv6, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip -6 addr add failed");
+#else
+    argv_printf(&argv, "%s %s add %s/%d mtu %d up", IFCONFIG_PATH, ifname,
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
+#endif
+#elif defined(TARGET_ANDROID)
+    char out6[64];
 
-        /*
-         * Set ifconfig parameters
-         */
-        ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
-        ifconfig_remote_netmask = print_in_addr_t(tt->remote_netmask, 0, &gc);
+    openvpn_snprintf(out6, sizeof(out6), "%s/%d",
+                     ifconfig_ipv6_local,tt->netbits_ipv6);
+    management_android_control(management, "IFCONFIG6", out6);
+#elif defined(TARGET_SOLARIS)
+    argv_printf(&argv, "%s %s inet6 unplumb", IFCONFIG_PATH, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, 0, NULL);
 
-        if (tt->did_ifconfig_ipv6_setup)
+    if (tt->type == DEV_TYPE_TUN)
+    {
+        const char *ifconfig_ipv6_remote = print_in6_addr(tt->remote_ipv6, 0, &gc);
+
+        argv_printf(&argv, "%s %s inet6 plumb %s/%d %s mtu %d up",
+                    IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
+                    tt->netbits_ipv6, ifconfig_ipv6_remote, tun_mtu);
+    }
+    else /* tap mode */
+    {
+        /* base IPv6 tap interface needs to be brought up first */
+        argv_printf(&argv, "%s %s inet6 plumb up", IFCONFIG_PATH, ifname);
+        argv_msg(M_INFO, &argv);
+
+        if (!openvpn_execve_check(&argv, es, 0,
+                                  "Solaris ifconfig IPv6 (prepare) failed"))
         {
-            ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
-            do_ipv6 = true;
+            solaris_error_close(tt, es, ifname, true);
         }
 
-        /*
-         * If TAP-style device, generate broadcast address.
+        /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
+         * after the system has noticed the interface and fired up
+         * the DHCPv6 client - but this takes quite a while, and the
+         * server will ignore the DHCPv6 packets anyway.  So we don't.
          */
-        if (!tun)
-        {
-            ifconfig_broadcast = print_in_addr_t(tt->broadcast, 0, &gc);
-        }
 
-#ifdef ENABLE_MANAGEMENT
-        if (management)
-        {
-            management_set_state(management,
-                                 OPENVPN_STATE_ASSIGN_IP,
-                                 NULL,
-                                 &tt->local,
-                                 &tt->local_ipv6,
-                                 NULL,
-                                 NULL);
-        }
+        /* static IPv6 addresses need to go to a subinterface (tap0:1) */
+        argv_printf(&argv, "%s %s inet6 addif %s/%d mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    }
+    argv_msg(M_INFO, &argv);
+
+    if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 failed"))
+    {
+        solaris_error_close(tt, es, ifname, true);
+    }
+#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
+    || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
+    || defined(TARGET_DRAGONFLY)
+    argv_printf(&argv, "%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    argv_msg(M_INFO, &argv);
+
+    openvpn_execve_check(&argv, es, S_FATAL,
+                         "generic BSD ifconfig inet6 failed");
+
+#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
+    || defined(TARGET_DARWIN)
+    /* and, hooray, we explicitely need to add a route... */
+    add_route_connected_v6_net(tt, es);
 #endif
+#elif defined(TARGET_AIX)
+    argv_printf(&argv, "%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
+    argv_msg(M_INFO, &argv);
 
+    /* AIX ifconfig will complain if it can't find ODM path in env */
+    es = env_set_create(NULL);
+    env_set_add(es, "ODMDIR=/etc/objrepos");
 
-#if defined(TARGET_LINUX)
-#ifdef ENABLE_IPROUTE
-        /*
-         * Set the MTU for the device
-         */
-        argv_printf(&argv,
-                    "%s link set dev %s up mtu %d",
-                    iproute_path,
-                    actual,
-                    tun_mtu
-                    );
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
+    openvpn_execve_check(&argv, es, S_FATAL,
+                         "generic BSD ifconfig inet6 failed");
 
-        if (tun)
-        {
+    env_set_destroy(es);
+#elif defined (_WIN32)
+    if (tt->options.ip_win32_type == IPW32_SET_MANUAL)
+    {
+        msg(M_INFO, "******** NOTE:  Please manually set the v6 IP of '%s' to %s (if it is not already set)",
+            ifname, ifconfig_ipv6_local);
+    }
+    else if (tt->options.msg_channel)
+    {
+        do_address_service(true, AF_INET6, tt);
+        do_dns6_service(true, tt);
+    }
+    else
+    {
+        /* example: netsh interface ipv6 set address interface=42
+         *                  2001:608:8003::d store=active
+         */
+        char iface[64];
 
-            /*
-             * Set the address for the device
-             */
-            argv_printf(&argv,
-                        "%s addr add dev %s local %s peer %s",
-                        iproute_path,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s addr add dev %s %s/%d broadcast %s",
-                        iproute_path,
-                        actual,
-                        ifconfig_local,
-                        netmask_to_netbits2(tt->remote_netmask),
-                        ifconfig_broadcast
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
-        }
-        if (do_ipv6)
-        {
-            argv_printf( &argv,
-                         "%s -6 addr add %s/%d dev %s",
-                         iproute_path,
-                         ifconfig_ipv6_local,
-                         tt->netbits_ipv6,
-                         actual
-                         );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip -6 addr add failed");
-        }
-#else  /* ifdef ENABLE_IPROUTE */
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s pointopoint %s mtu %d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d broadcast %s",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu,
-                        ifconfig_broadcast
-                        );
-        }
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig failed");
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s add %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
-        }
+        openvpn_snprintf(iface, sizeof(iface), "interface=%lu",
+                         tt->adapter_index);
+        argv_printf(&argv, "%s%sc interface ipv6 set address %s %s store=active",
+                    get_win_sys_path(), NETSH_PATH_SUFFIX, iface,
+                    ifconfig_ipv6_local);
+        netsh_command(&argv, 4, M_FATAL);
+        /* set ipv6 dns servers if any are specified */
+        netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, ifname);
+    }
 
-#endif /*ENABLE_IPROUTE*/
-#elif defined(TARGET_ANDROID)
+    /* explicit route needed */
+    if (tt->options.ip_win32_type != IPW32_SET_MANUAL)
+    {
+        add_route_connected_v6_net(tt, es);
+    }
+#else /* platforms we have no IPv6 code for */
+    msg(M_FATAL, "Sorry, but I don't know how to do IPv6 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
+#endif /* outer "if defined(TARGET_xxx)" conditional */
 
-        if (do_ipv6)
-        {
-            char out6[64];
-            openvpn_snprintf(out6, sizeof(out6), "%s/%d", ifconfig_ipv6_local,tt->netbits_ipv6);
-            management_android_control(management, "IFCONFIG6", out6);
-        }
+    gc_free(&gc);
+    argv_reset(&argv);
+}
 
-        char out[64];
+/**
+ * do_ifconfig_ipv4 - perform platform specific ifconfig commands
+ *
+ * @param tt        the tuntap interface context
+ * @param ifname    the human readable interface name
+ * @param mtu       the MTU value to set the interface to
+ * @param es        the environment to be used when executing the commands
+ */
+static void
+do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
+                 const struct env_set *es)
+{
+    bool tun = false;
+    const char *ifconfig_local = NULL;
+    const char *ifconfig_remote_netmask = NULL;
+    const char *ifconfig_broadcast = NULL;
+    struct argv argv = argv_new();
+    struct gc_arena gc = gc_new();
 
-        char *top;
-        switch (tt->topology)
-        {
-            case TOP_NET30:
-                top = "net30";
-                break;
+    /*
+     * We only handle TUN/TAP devices here, not --dev null devices.
+     */
+    tun = is_tun_p2p(tt);
 
-            case TOP_P2P:
-                top = "p2p";
-                break;
+    /*
+     * Set ifconfig parameters
+     */
+    ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
+    ifconfig_remote_netmask = print_in_addr_t(tt->remote_netmask, 0, &gc);
 
-            case TOP_SUBNET:
-                top = "subnet";
-                break;
+    /*
+     * If TAP-style device, generate broadcast address.
+     */
+    if (!tun)
+    {
+        ifconfig_broadcast = print_in_addr_t(tt->broadcast, 0, &gc);
+    }
 
-            default:
-                top = "undef";
-        }
+#if defined(TARGET_LINUX)
+#ifdef ENABLE_IPROUTE
+    /*
+     * Set the MTU for the device
+     */
+    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
+                tun_mtu);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
 
-        openvpn_snprintf(out, sizeof(out), "%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu, top);
-        management_android_control(management, "IFCONFIG", out);
+    if (tun)
+    {
 
-#elif defined(TARGET_SOLARIS)
-        /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
-         * example:
-         *    ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
-         *    ifconfig tun2 netmask 255.255.255.255
+        /*
+         * Set the address for the device
          */
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-
-            argv_msg(M_INFO, &argv);
-            if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-1 failed"))
-            {
-                solaris_error_close(tt, es, actual, false);
-            }
+        argv_printf(&argv, "%s addr add dev %s local %s peer %s", iproute_path,
+                    ifname, ifconfig_local, ifconfig_remote_netmask);
+        argv_msg(M_INFO, &argv);
+        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
+    }
+    else
+    {
+        argv_printf(&argv, "%s addr add dev %s %s/%d broadcast %s",
+                    iproute_path, ifname, ifconfig_local,
+                    netmask_to_netbits2(tt->remote_netmask),
+                    ifconfig_broadcast);
+        argv_msg(M_INFO, &argv);
+        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
+    }
+#else  /* ifdef ENABLE_IPROUTE */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s pointopoint %s mtu %d", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+    }
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig failed");
 
-            argv_printf(&argv,
-                        "%s %s netmask 255.255.255.255",
-                        IFCONFIG_PATH,
-                        actual
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s netmask %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        " %s %s %s netmask %s broadcast + up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask
-                        );
-        }
+#endif /*ENABLE_IPROUTE*/
+#elif defined(TARGET_ANDROID)
+    char out[64];
 
-        argv_msg(M_INFO, &argv);
-        if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-2 failed"))
-        {
-            solaris_error_close(tt, es, actual, false);
-        }
+    char *top;
+    switch (tt->topology)
+    {
+        case TOP_NET30:
+            top = "net30";
+            break;
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv, "%s %s inet6 unplumb",
-                        IFCONFIG_PATH, actual );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, 0, NULL);
+        case TOP_P2P:
+            top = "p2p";
+            break;
 
-            if (tt->type == DEV_TYPE_TUN)
-            {
-                const char *ifconfig_ipv6_remote =
-                    print_in6_addr(tt->remote_ipv6, 0, &gc);
+        case TOP_SUBNET:
+            top = "subnet";
+            break;
 
-                argv_printf(&argv,
-                            "%s %s inet6 plumb %s/%d %s up",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_ipv6_local,
-                            tt->netbits_ipv6,
-                            ifconfig_ipv6_remote
-                            );
-            }
-            else                                        /* tap mode */
-            {
-                /* base IPv6 tap interface needs to be brought up first
-                 */
-                argv_printf(&argv, "%s %s inet6 plumb up",
-                            IFCONFIG_PATH, actual );
-                argv_msg(M_INFO, &argv);
-                if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 (prepare) failed"))
-                {
-                    solaris_error_close(tt, es, actual, true);
-                }
+        default:
+            top = "undef";
+    }
 
-                /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
-                 * after the system has noticed the interface and fired up
-                 * the DHCPv6 client - but this takes quite a while, and the
-                 * server will ignore the DHCPv6 packets anyway.  So we don't.
-                 */
+    openvpn_snprintf(out, sizeof(out), "%s %s %d %s", ifconfig_local,
+                     ifconfig_remote_netmask, tun_mtu, top);
+    management_android_control(management, "IFCONFIG", out);
 
-                /* static IPv6 addresses need to go to a subinterface (tap0:1)
-                 */
-                argv_printf(&argv,
-                            "%s %s inet6 addif %s/%d up",
-                            IFCONFIG_PATH, actual,
-                            ifconfig_ipv6_local, tt->netbits_ipv6 );
-            }
-            argv_msg(M_INFO, &argv);
-            if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 failed"))
-            {
-                solaris_error_close(tt, es, actual, true);
-            }
-        }
+#elif defined(TARGET_SOLARIS)
+    /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
+     * example:
+     *    ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
+     *    ifconfig tun2 netmask 255.255.255.255
+     */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d up", IFCONFIG_PATH, ifname,
+                    ifconfig_local, ifconfig_remote_netmask, tun_mtu);
 
-        if (!tun && tt->topology == TOP_SUBNET)
+        argv_msg(M_INFO, &argv);
+        if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-1 failed"))
         {
-            /* Add a network route for the local tun interface */
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED | RT_METRIC_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = tt->local;
-            r.metric = 0;
-            add_route(&r, tt, 0, NULL, es);
+            solaris_error_close(tt, es, ifname, false);
         }
 
-#elif defined(TARGET_OPENBSD)
-
-        in_addr_t remote_end;           /* for "virtual" subnet topology */
-
-        /*
-         * On OpenBSD, tun interfaces are persistent if created with
-         * "ifconfig tunX create", and auto-destroyed if created by
-         * opening "/dev/tunX" (so we just use the /dev/tunX)
-         */
+        argv_printf(&argv, "%s %s netmask 255.255.255.255", IFCONFIG_PATH,
+                    ifname);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s broadcast + up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask);
+    }
 
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            remote_end = create_arbitrary_remote( tt );
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask %s up -link0",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        print_in_addr_t(remote_end, 0, &gc),
-                        tun_mtu,
-                        ifconfig_remote_netmask
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d broadcast %s link0",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu,
-                        ifconfig_broadcast
-                        );
-        }
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed");
+    argv_msg(M_INFO, &argv);
+    if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-2 failed"))
+    {
+        solaris_error_close(tt, es, ifname, false);
+    }
 
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
         /* Add a network route for the local tun interface */
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = remote_end;
-            add_route(&r, tt, 0, NULL, es);
-        }
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED | RT_METRIC_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = tt->local;
+        r.metric = 0;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig inet6 failed");
+#elif defined(TARGET_OPENBSD)
 
-            /* and, hooray, we explicitely need to add a route... */
-            add_route_connected_v6_net(tt, es);
-        }
+    in_addr_t remote_end;           /* for "virtual" subnet topology */
 
-#elif defined(TARGET_NETBSD)
+    /*
+     * On OpenBSD, tun interfaces are persistent if created with
+     * "ifconfig tunX create", and auto-destroyed if created by
+     * opening "/dev/tunX" (so we just use the /dev/tunX)
+     */
 
-        if (tun)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask %s up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_local,
-                        tun_mtu,
-                        ifconfig_remote_netmask
-                        );
-        }
-        else
-        {
-            /*
-             * NetBSD has distinct tun and tap devices
-             * so we don't need the "link0" extra parameter to specify we want to do
-             * tunneling at the ethernet level
-             */
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d broadcast %s",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu,
-                        ifconfig_broadcast
-                        );
-        }
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed");
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
+    if (tun)
+    {
+        argv_printf(&argv,
+                    "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        remote_end = create_arbitrary_remote( tt );
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up -link0",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    print_in_addr_t(remote_end, 0, &gc), tun_mtu,
+                    ifconfig_remote_netmask);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s link0",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+    }
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed");
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig inet6 failed");
+    /* Add a network route for the local tun interface */
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = remote_end;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-            /* and, hooray, we explicitely need to add a route... */
-            add_route_connected_v6_net(tt, es);
-        }
+#elif defined(TARGET_NETBSD)
 
-#elif defined(TARGET_DARWIN)
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_local, tun_mtu,
+                    ifconfig_remote_netmask);
+    }
+    else
+    {
         /*
-         * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
+         * NetBSD has distinct tun and tap devices
+         * so we don't need the "link0" extra parameter to specify we want to do
+         * tunneling at the ethernet level
          */
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
+    }
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed");
 
-        argv_printf(&argv,
-                    "%s %s delete",
-                    IFCONFIG_PATH,
-                    actual);
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, 0, NULL);
-        msg(M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
+#elif defined(TARGET_DARWIN)
+    /*
+     * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
+     */
 
+    argv_printf(&argv, "%s %s delete", IFCONFIG_PATH, ifname);
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, 0, NULL);
+    msg(M_INFO,
+        "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
 
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
-        if (tun)
+
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else
+    {
+        if (tt->topology == TOP_SUBNET)
         {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
+            argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up",
+                        IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_local,
+                        ifconfig_remote_netmask, tun_mtu);
         }
         else
         {
-            if (tt->topology == TOP_SUBNET)
-            {
-                argv_printf(&argv,
-                            "%s %s %s %s netmask %s mtu %d up",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_local,
-                            ifconfig_local,
-                            ifconfig_remote_netmask,
-                            tun_mtu
-                            );
-            }
-            else
-            {
-                argv_printf(&argv,
-                            "%s %s %s netmask %s mtu %d up",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_local,
-                            ifconfig_remote_netmask,
-                            tun_mtu
-                            );
-            }
+            argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                        ifname, ifconfig_local, ifconfig_remote_netmask,
+                        tun_mtu);
         }
+    }
 
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed");
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed");
 
-        /* Add a network route for the local tun interface */
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = tt->local;
-            add_route(&r, tt, 0, NULL, es);
-        }
+    /* Add a network route for the local tun interface */
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = tt->local;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "MacOS X ifconfig inet6 failed");
+#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
 
-            /* and, hooray, we explicitely need to add a route... */
-            add_route_connected_v6_net(tt, es);
-        }
+    in_addr_t remote_end;           /* for "virtual" subnet topology */
 
-#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
+    if (tun)
+    {
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
+                    IFCONFIG_PATH, ifname, ifconfig_local,
+                    ifconfig_remote_netmask, tun_mtu);
+    }
+    else if (tt->topology == TOP_SUBNET)
+    {
+        remote_end = create_arbitrary_remote( tt );
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, print_in_addr_t(remote_end, 0, &gc),
+                    tun_mtu, ifconfig_remote_netmask);
+    }
+    else
+    {
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
+    }
+
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed");
+
+    /* Add a network route for the local tun interface */
+    if (!tun && tt->topology == TOP_SUBNET)
+    {
+        struct route_ipv4 r;
+        CLEAR(r);
+        r.flags = RT_DEFINED;
+        r.network = tt->local & tt->remote_netmask;
+        r.netmask = tt->remote_netmask;
+        r.gateway = remote_end;
+        add_route(&r, tt, 0, NULL, es);
+    }
 
-        in_addr_t remote_end;           /* for "virtual" subnet topology */
+#elif defined(TARGET_AIX)
+    {
+        /* AIX ifconfig will complain if it can't find ODM path in env */
+        struct env_set *aix_es = env_set_create(NULL);
+        env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
 
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
         if (tun)
         {
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-        }
-        else if (tt->topology == TOP_SUBNET)
-        {
-            remote_end = create_arbitrary_remote( tt );
-            argv_printf(&argv,
-                        "%s %s %s %s mtu %d netmask %s up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        print_in_addr_t(remote_end, 0, &gc),
-                        tun_mtu,
-                        ifconfig_remote_netmask
-                        );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
+            msg(M_FATAL, "no tun support on AIX (canthappen)");
         }
 
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed");
+        /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
 
-        /* Add a network route for the local tun interface */
-        if (!tun && tt->topology == TOP_SUBNET)
-        {
-            struct route_ipv4 r;
-            CLEAR(r);
-            r.flags = RT_DEFINED;
-            r.network = tt->local & tt->remote_netmask;
-            r.netmask = tt->remote_netmask;
-            r.gateway = remote_end;
-            add_route(&r, tt, 0, NULL, es);
-        }
+        argv_msg(M_INFO, &argv);
+        openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig failed");
 
-        if (do_ipv6)
-        {
-            argv_printf(&argv,
-                        "%s %s inet6 %s/%d",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6
-                        );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed");
-        }
+        env_set_destroy(aix_es);
+    }
+#elif defined (_WIN32)
+    {
+        ASSERT(ifname != NULL);
 
-#elif defined(TARGET_AIX)
+        switch (tt->options.ip_win32_type)
         {
-            /* AIX ifconfig will complain if it can't find ODM path in env */
-            struct env_set *aix_es = env_set_create(NULL);
-            env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
-
-            if (tun)
-            {
-                msg(M_FATAL, "no tun support on AIX (canthappen)");
-            }
+            case IPW32_SET_MANUAL:
+                msg(M_INFO,
+                    "******** NOTE:  Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
+                    ifname, ifconfig_local,
+                    print_in_addr_t(tt->adapter_netmask, 0, &gc));
+                break;
+            case IPW32_SET_NETSH:
+                netsh_ifconfig(&tt->options, ifname, tt->local,
+                               tt->adapter_netmask, NI_IP_NETMASK|NI_OPTIONS);
 
-            /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
-            argv_printf(&argv,
-                        "%s %s %s netmask %s mtu %d up",
-                        IFCONFIG_PATH,
-                        actual,
-                        ifconfig_local,
-                        ifconfig_remote_netmask,
-                        tun_mtu
-                        );
-
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig failed");
-
-            if (do_ipv6)
-            {
-                argv_printf(&argv,
-                            "%s %s inet6 %s/%d",
-                            IFCONFIG_PATH,
-                            actual,
-                            ifconfig_ipv6_local,
-                            tt->netbits_ipv6
-                            );
-                argv_msg(M_INFO, &argv);
-                openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig inet6 failed");
-            }
-            env_set_destroy(aix_es);
+                break;
         }
-#elif defined (_WIN32)
-        {
-            ASSERT(actual != NULL);
+    }
 
-            switch (tt->options.ip_win32_type)
-            {
-                case IPW32_SET_MANUAL:
-                    msg(M_INFO, "******** NOTE:  Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
-                        actual,
-                        ifconfig_local,
-                        print_in_addr_t(tt->adapter_netmask, 0, &gc));
-                    break;
+#else  /* if defined(TARGET_LINUX) */
+    msg(M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
+#endif /* if defined(TARGET_LINUX) */
 
-                case IPW32_SET_NETSH:
-                    netsh_ifconfig(&tt->options,
-                                   actual,
-                                   tt->local,
-                                   tt->adapter_netmask,
-                                   NI_IP_NETMASK|NI_OPTIONS);
+    gc_free(&gc);
+    argv_reset(&argv);
+}
 
-                    break;
-            }
-        }
+/* execute the ifconfig command through the shell */
+void
+do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
+            const struct env_set *es)
+{
+    msg(D_LOW, "do_ifconfig, ipv4=%d, ipv6=%d", tt->did_ifconfig_setup,
+        tt->did_ifconfig_ipv6_setup);
 
-        if (do_ipv6)
-        {
-            if (tt->options.ip_win32_type == IPW32_SET_MANUAL)
-            {
-                msg(M_INFO, "******** NOTE:  Please manually set the v6 IP of '%s' to %s (if it is not already set)",
-                    actual,
-                    ifconfig_ipv6_local);
-            }
-            else if (tt->options.msg_channel)
-            {
-                do_address_service(true, AF_INET6, tt);
-                do_dns6_service(true, tt);
-            }
-            else
-            {
-                /* example: netsh interface ipv6 set address interface=42 2001:608:8003::d store=active */
-                char iface[64];
-                openvpn_snprintf(iface, sizeof(iface), "interface=%lu", tt->adapter_index );
-                argv_printf(&argv,
-                            "%s%sc interface ipv6 set address %s %s store=active",
-                            get_win_sys_path(),
-                            NETSH_PATH_SUFFIX,
-                            iface,
-                            ifconfig_ipv6_local );
-                netsh_command(&argv, 4, M_FATAL);
-                /* set ipv6 dns servers if any are specified */
-                netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, actual);
-            }
+#ifdef ENABLE_MANAGEMENT
+    if (management)
+    {
+        management_set_state(management,
+                             OPENVPN_STATE_ASSIGN_IP,
+                             NULL,
+                             &tt->local,
+                             &tt->local_ipv6,
+                             NULL,
+                             NULL);
+    }
+#endif
 
-            /* explicit route needed */
-            if (tt->options.ip_win32_type != IPW32_SET_MANUAL)
-            {
-                add_route_connected_v6_net(tt, es);
-            }
-        }
-#else  /* if defined(TARGET_LINUX) */
-        msg(M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
-#endif /* if defined(TARGET_LINUX) */
-        argv_reset(&argv);
+    if (tt->did_ifconfig_setup)
+    {
+        do_ifconfig_ipv4(tt, ifname, tun_mtu, es);
+    }
+
+    if (tt->did_ifconfig_ipv6_setup)
+    {
+        do_ifconfig_ipv6(tt, ifname, tun_mtu, es);
     }
-    gc_free(&gc);
 }
 
 static void
@@ -2089,77 +1937,76 @@ tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_
 
 #endif /* ENABLE_FEATURE_TUN_PERSIST */
 
+void
+undo_ifconfig_ipv4(struct tuntap *tt, struct gc_arena *gc)
+{
+    struct argv argv = argv_new();
+
+#ifdef ENABLE_IPROUTE
+    if (is_tun_p2p(tt))
+    {
+        argv_printf(&argv, "%s addr del dev %s local %s peer %s", iproute_path,
+                    tt->actual_name, print_in_addr_t(tt->local, 0, gc),
+                    print_in_addr_t(tt->remote_netmask, 0, gc));
+    }
+    else
+    {
+        argv_printf(&argv, "%s addr del dev %s %s/%d", iproute_path,
+                    tt->actual_name, print_in_addr_t(tt->local, 0, gc),
+                    netmask_to_netbits2(tt->remote_netmask));
+    }
+#else  /* ifdef ENABLE_IPROUTE */
+    argv_printf(&argv, "%s %s 0.0.0.0", IFCONFIG_PATH, tt->actual_name);
+#endif /* ifdef ENABLE_IPROUTE */
+
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, NULL, 0, "Linux ip addr del failed");
+
+    argv_reset(&argv);
+}
+
+void
+undo_ifconfig_ipv6(struct tuntap *tt, struct gc_arena *gc)
+{
+    const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, gc);
+    struct argv argv = argv_new();
+
+#ifdef ENABLE_IPROUTE
+    argv_printf(&argv, "%s -6 addr del %s/%d dev %s", iproute_path,
+                ifconfig_ipv6_local, tt->netbits_ipv6, tt->actual_name);
+#else  /* ifdef ENABLE_IPROUTE */
+    argv_printf(&argv, "%s %s del %s/%d", IFCONFIG_PATH, tt->actual_name,
+                ifconfig_ipv6_local, tt->netbits_ipv6);
+#endif
+
+    argv_msg(M_INFO, &argv);
+    openvpn_execve_check(&argv, NULL, 0, "Linux ip -6 addr del failed");
+
+    argv_reset(&argv);
+}
+
 void
 close_tun(struct tuntap *tt)
 {
     ASSERT(tt);
 
-    if (tt->type != DEV_TYPE_NULL && tt->did_ifconfig_setup)
+    if (tt->type != DEV_TYPE_NULL)
     {
-        struct argv argv = argv_new();
         struct gc_arena gc = gc_new();
 
-#ifdef ENABLE_IPROUTE
-        if (is_tun_p2p(tt))
+        if (tt->did_ifconfig_setup)
         {
-            argv_printf(&argv,
-                        "%s addr del dev %s local %s peer %s",
-                        iproute_path,
-                        tt->actual_name,
-                        print_in_addr_t(tt->local, 0, &gc),
-                        print_in_addr_t(tt->remote_netmask, 0, &gc)
-                       );
-        }
-        else
-        {
-            argv_printf(&argv,
-                        "%s addr del dev %s %s/%d",
-                        iproute_path,
-                        tt->actual_name,
-                        print_in_addr_t(tt->local, 0, &gc),
-                        netmask_to_netbits2(tt->remote_netmask)
-                       );
+            undo_ifconfig_ipv4(tt, &gc);
         }
-#else  /* ifdef ENABLE_IPROUTE */
-        argv_printf(&argv,
-                    "%s %s 0.0.0.0",
-                    IFCONFIG_PATH,
-                    tt->actual_name
-                   );
-#endif /* ifdef ENABLE_IPROUTE */
-
-        argv_msg(M_INFO, &argv);
-        openvpn_execve_check(&argv, NULL, 0, "Linux ip addr del failed");
 
         if (tt->did_ifconfig_ipv6_setup)
         {
-            const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
-
-#ifdef ENABLE_IPROUTE
-            argv_printf(&argv, "%s -6 addr del %s/%d dev %s",
-                        iproute_path,
-                        ifconfig_ipv6_local,
-                        tt->netbits_ipv6,
-                        tt->actual_name
-                       );
-            argv_msg(M_INFO, &argv);
-            openvpn_execve_check(&argv, NULL, 0, "Linux ip -6 addr del failed");
-#else  /* ifdef ENABLE_IPROUTE */
-            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 ifconfig inet6 del failed");
-#endif
+            undo_ifconfig_ipv6(tt, &gc);
         }
 
-        argv_reset(&argv);
         gc_free(&gc);
     }
+
     close_tun_generic(tt);
     free(tt);
 }
@@ -5851,7 +5698,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
 
     if (tt->type == DEV_TYPE_TUN)
     {
-        if (!tt->did_ifconfig_setup)
+        if (!tt->did_ifconfig_setup && !tt->did_ifconfig_ipv6_setup)
         {
             msg(M_FATAL, "ERROR: --dev tun also requires --ifconfig");
         }
src/openvpn/tun.h +9 -3
index 9495d602..cb1ab1cc 100644
@@ -246,9 +246,15 @@ void init_tun_post(struct tuntap *tt,
 void do_ifconfig_setenv(const struct tuntap *tt,
                         struct env_set *es);
 
-void do_ifconfig(struct tuntap *tt,
-                 const char *actual,     /* actual device name */
-                 int tun_mtu,
+/**
+ * do_ifconfig - configure the tunnel interface
+ *
+ * @param tt        the tuntap interface context
+ * @param ifname    the human readable interface name
+ * @param mtu       the MTU value to set the interface to
+ * @param es        the environment to be used when executing the commands
+ */
+void do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
                  const struct env_set *es);
 
 bool is_dev_type(const char *dev, const char *dev_type, const char *match_type);
Signature · 1 line
2.17.1
Acked-by on v5 1/8
#13 lore raw

[Openvpn-devel] [PATCH applied] Re: tun: ensure interface can be configured with IPv6 only

TARGET_SOLARIS fixed, and that's (diffing the two patches) the only code difference - all the rest has been reviewed and tested for v4 already. Windows won't do ipv6-only, but ipv4(+ipv6) should be fine.

Your patch has been applied to the master branch.

commit 611fcbc487292054306767a76e727aea4e593725

Author: Antonio Quartulli
Date:   Mon Jun 18 15:47:33 2018 +0800
     tun: ensure interface can be configured with IPv6 only

     Signed-off-by: Antonio Quartulli <[email protected]...>
     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: https://www.mail-archive.com/[email protected]/msg17064.html
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#14 lore raw

PATCH v2 2/8 windows: properly configure TAP driver when no IPv4 is configured

In reply to Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

---
 src/openvpn/forward.c |  4 +++-
 src/openvpn/tun.c     | 24 +++++++++++++++++-------
 2 files changed, 20 insertions(+), 8 deletions(-)
src/openvpn/forward.c +3 -1
index 7d9a338d..51e43c28 100644
@@ -292,7 +292,9 @@ check_add_routes_action(struct context *c, const bool errors)
 void
 check_add_routes_dowork(struct context *c)
 {
-    if (test_routes(c->c1.route_list, c->c1.tuntap))
+    /* skip route check if no IPv4 was configured */
+    if (!c->c1.tuntap->did_ifconfig_setup
+        || test_routes(c->c1.route_list, c->c1.tuntap))
     {
         check_add_routes_action(c, false);
     }
src/openvpn/tun.c +17 -7
index 8509d489..d183aea7 100644
@@ -5718,7 +5718,10 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
             msg(M_FATAL, "ERROR: --dev tun also requires --ifconfig");
         }
 
-        if (tt->topology == TOP_SUBNET)
+        /* send 0/0/0 to the TAP driver even if we have no IPv4 configured to
+         * ensure it is somehow initialized.
+         */
+        if (!tt->did_ifconfig_setup || tt->topology == TOP_SUBNET)
         {
             in_addr_t ep[3];
             BOOL status;
@@ -5731,12 +5734,19 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
                                      ep, sizeof(ep),
                                      ep, sizeof(ep), &len, NULL);
 
-            msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
-                print_in_addr_t(ep[1], IA_NET_ORDER, &gc),
-                print_in_addr_t(ep[0], IA_NET_ORDER, &gc),
-                print_in_addr_t(ep[2], IA_NET_ORDER, &gc),
-                status ? "SUCCEEDED" : "FAILED");
-
+            if (tt->did_ifconfig_setup)
+            {
+                msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
+                    print_in_addr_t(ep[1], IA_NET_ORDER, &gc),
+                    print_in_addr_t(ep[0], IA_NET_ORDER, &gc),
+                    print_in_addr_t(ep[2], IA_NET_ORDER, &gc),
+                    status ? "SUCCEEDED" : "FAILED");
+            }
+            else
+            {
+                msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN with fake IPv4 [%s]",
+                    status ? "SUCCEEDED" : "FAILED");
+            }
         }
         else
         {
Signature · 1 line
2.17.1
#15 lore raw

Re: [Openvpn-devel] [PATCH v2 2/8] windows: properly configure TAP driver when no IPv4 is configured

Hi,

Quoted 3 lines · Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

This commit message is a bit... thin.

src/openvpn/forward.c check_add_routes_action(struct context *c, const bool errors) · line 300

Quoted 9 lines

check_add_routes_dowork(struct context *c)
{

src/openvpn/forward.c +3 -1
-    if (test_routes(c->c1.route_list, c->c1.tuntap))
+    /* skip route check if no IPv4 was configured */
+    if (!c->c1.tuntap->did_ifconfig_setup
+        || test_routes(c->c1.route_list, c->c1.tuntap))
     {
         check_add_routes_action(c, false);
     }

And I'm not sure if that comment is sufficient to explain this increasingly convoluted function... (I'm so totally not understanding what is happening here, and how it's wrapped into the event looping)

Maybe a easier to understand place for the did_ifconfig_setup check would be inside test_routes()?

Like:

- if (rl)
+ /* we do this test only if we have IPv4 routes to install, and if

+   * the tun/tap interface has seen ipv4 ifconfig - because if we 
+   * have no IPv4, the check will always fail, failing tun init
+   */

+ if (rl && tt->did_ifconfig_setup)

But really, WTF...

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#16 lore raw

PATCH v3 2/8 windows: properly configure TAP driver when no IPv4 is configured

In reply to Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

This patch ensures that the TAP driver on a windows host is still configured, even though no IPv4 has been provided.

In this case the TAP driver ioctl will be invoked with a fake 0.0.0.0/0.0.0.0 IPv4 which will simply start the interface and get it to a working state.

Trac: #208

---

Changes from v2:
- rebased on top ov v4 1/8
- extended commit message
- moved did_ifconfig_setup check into test_routes()
- added longer comment into test_routes() to explain check condition

 src/openvpn/route.c |  6 +++++-
 src/openvpn/tun.c   | 24 +++++++++++++++++-------
 2 files changed, 22 insertions(+), 8 deletions(-)
src/openvpn/route.c +5 -1
index 8990a986..be07bd65 100644
@@ -2642,7 +2642,11 @@ test_routes(const struct route_list *rl, const struct tuntap *tt)
         ret = true;
         adapter_up = true;
 
-        if (rl)
+        /* we do this test only if we have IPv4 routes to install, and if
+         * the tun/tap interface has seen IPv4 ifconfig - because if we
+         * have no IPv4, the check will always fail, failing tun init
+         */
+        if (rl && c->c1.tuntap->did_ifconfig_setup)
         {
             struct route_ipv4 *r;
             for (r = rl->routes, len = 0; r; r = r->next, ++len)
src/openvpn/tun.c +17 -7
index 878fd845..c0d1ac18 100644
@@ -5703,7 +5703,10 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
             msg(M_FATAL, "ERROR: --dev tun also requires --ifconfig");
         }
 
-        if (tt->topology == TOP_SUBNET)
+        /* send 0/0/0 to the TAP driver even if we have no IPv4 configured to
+         * ensure it is somehow initialized.
+         */
+        if (!tt->did_ifconfig_setup || tt->topology == TOP_SUBNET)
         {
             in_addr_t ep[3];
             BOOL status;
@@ -5716,12 +5719,19 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
                                      ep, sizeof(ep),
                                      ep, sizeof(ep), &len, NULL);
 
-            msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
-                print_in_addr_t(ep[1], IA_NET_ORDER, &gc),
-                print_in_addr_t(ep[0], IA_NET_ORDER, &gc),
-                print_in_addr_t(ep[2], IA_NET_ORDER, &gc),
-                status ? "SUCCEEDED" : "FAILED");
-
+            if (tt->did_ifconfig_setup)
+            {
+                msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
+                    print_in_addr_t(ep[1], IA_NET_ORDER, &gc),
+                    print_in_addr_t(ep[0], IA_NET_ORDER, &gc),
+                    print_in_addr_t(ep[2], IA_NET_ORDER, &gc),
+                    status ? "SUCCEEDED" : "FAILED");
+            }
+            else
+            {
+                msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN with fake IPv4 [%s]",
+                    status ? "SUCCEEDED" : "FAILED");
+            }
         }
         else
         {
Signature · 1 line
2.17.1
#17 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

Hi,

Quoted 11 lines · Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

This patch ensures that the TAP driver on a windows host is still configured, even though no IPv4 has been provided.

In this case the TAP driver ioctl will be invoked with a fake 0.0.0.0/0.0.0.0 IPv4 which will simply start the interface and get it to a working state.

Trac: #208

I think this is good enough, though I haven't tested it yet (compile and run). Will do that tomorrow, before I merge & push.

Before I go ahead with it - Selva, are you fine with this version?

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#18 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

Quoted 13 lines · Gert Doering

Hi,

Quoted 9 lines · Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

This patch ensures that the TAP driver on a windows host is still configured, even though no IPv4 has been provided.

In this case the TAP driver ioctl will be invoked with a fake 0.0.0.0/0.0.0.0 IPv4 which will simply start the interface and get it to a working state.

Quoted 7 lines
Quoted 2 lines

Trac: #208

I think this is good enough, though I haven't tested it yet (compile and run). Will do that tomorrow, before I merge & push.

Before I go ahead with it - Selva, are you fine with this version?

I believe this is the same as the gitlab version I had tested and commented on. I only had some opinionated remarks (nothing critical), so this should be good to merge.

Selva

Acked-by on v3 2/8
#19 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

In reply to Antonio Quartulli

Hi,

Quoted 11 lines · Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

This patch ensures that the TAP driver on a windows host is still configured, even though no IPv4 has been provided.

In this case the TAP driver ioctl will be invoked with a fake 0.0.0.0/0.0.0.0 IPv4 which will simply start the interface and get it to a working state.

Trac: #208

Well...

Review test_routes(const struct route_list *rl, const struct tuntap *tt) · line 2649

Quoted 10 lines
(quoted diff) +5 -1
@@ -2642,7 +2642,11 @@ test_routes(const struct route_list *rl, const struct tuntap *tt)
         ret = true;
         adapter_up = true;
 
-        if (rl)
+        /* we do this test only if we have IPv4 routes to install, and if
+         * the tun/tap interface has seen IPv4 ifconfig - because if we
+         * have no IPv4, the check will always fail, failing tun init
+         */
+        if (rl && c->c1.tuntap->did_ifconfig_setup)

This code is a bit optimstic :-) - there is no "c" here...

route.c: In function 'test_routes':
route.c:2649:19: error: 'c' undeclared (first use in this function)

         if (rl && c->c1.tuntap->did_ifconfig_setup)
                   ^

... because it's just "tt" here, so "tt->did_ifconfig_setup" should be fine... at least it compiled :-) - I've sent you a link to an installer for testing.

Amended patch attached

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...

From 7fd30a4c131fa8e45a972b7f312b651bd38f784b Mon Sep 17 00:00:00 2001
From: Antonio Quartulli <[email protected]...>
Date: Wed, 13 Jun 2018 22:12:13 +0800
Subject: [PATCH] windows: properly configure TAP driver when no IPv4 is
configured

This patch ensures that the TAP driver on a windows host is still configured, even though no IPv4 has been provided.

In this case the TAP driver ioctl will be invoked with a fake 0.0.0.0/0.0.0.0 IPv4 which will simply start the interface and get it to a working state.

Trac: #208

Message-Id: <[email protected]...>
URL: https://www.mail-archive.com/[email protected]/msg17052.html

---
 src/openvpn/route.c |  6 +++++-
 src/openvpn/tun.c   | 24 +++++++++++++++++-------
 2 files changed, 22 insertions(+), 8 deletions(-)
src/openvpn/route.c +5 -1
index 8990a986..f6962848 100644
@@ -2642,7 +2642,11 @@ test_routes(const struct route_list *rl, const struct tuntap *tt)
         ret = true;
         adapter_up = true;
 
-        if (rl)
+        /* we do this test only if we have IPv4 routes to install, and if
+         * the tun/tap interface has seen IPv4 ifconfig - because if we
+         * have no IPv4, the check will always fail, failing tun init
+         */
+        if (rl && tt->did_ifconfig_setup)
         {
             struct route_ipv4 *r;
             for (r = rl->routes, len = 0; r; r = r->next, ++len)
src/openvpn/tun.c +17 -7
index 2e1c96e6..f9b9c716 100644
@@ -5703,7 +5703,10 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
             msg(M_FATAL, "ERROR: --dev tun also requires --ifconfig");
         }
 
-        if (tt->topology == TOP_SUBNET)
+        /* send 0/0/0 to the TAP driver even if we have no IPv4 configured to
+         * ensure it is somehow initialized.
+         */
+        if (!tt->did_ifconfig_setup || tt->topology == TOP_SUBNET)
         {
             in_addr_t ep[3];
             BOOL status;
@@ -5716,12 +5719,19 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
                                      ep, sizeof(ep),
                                      ep, sizeof(ep), &len, NULL);
 
-            msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
-                print_in_addr_t(ep[1], IA_NET_ORDER, &gc),
-                print_in_addr_t(ep[0], IA_NET_ORDER, &gc),
-                print_in_addr_t(ep[2], IA_NET_ORDER, &gc),
-                status ? "SUCCEEDED" : "FAILED");
-
+            if (tt->did_ifconfig_setup)
+            {
+                msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
+                    print_in_addr_t(ep[1], IA_NET_ORDER, &gc),
+                    print_in_addr_t(ep[0], IA_NET_ORDER, &gc),
+                    print_in_addr_t(ep[2], IA_NET_ORDER, &gc),
+                    status ? "SUCCEEDED" : "FAILED");
+            }
+            else
+            {
+                msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN with fake IPv4 [%s]",
+                    status ? "SUCCEEDED" : "FAILED");
+            }
         }
         else
         {
Signature · 1 line
2.17.1
#20 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

Hi,

Quoted 21 lines · Gert Doering

Hi,

Quoted 11 lines · Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

This patch ensures that the TAP driver on a windows host is still configured, even though no IPv4 has been provided.

In this case the TAP driver ioctl will be invoked with a fake 0.0.0.0/0.0.0.0 IPv4 which will simply start the interface and get it to a working state.

Trac: #208

Well...

Quoted 4 lines
(quoted diff) +0 -0
@@ -2642,7 +2642,11 @@ test_routes(const struct route_list *rl, const struct tuntap *tt)
         ret = true;
         adapter_up = true;
 
Quoted 8 lines

Review test_routes(const struct route_list *rl, const struct tuntap *tt) · line 2649

Quoted 6 lines
(quoted diff) +5 -1
-        if (rl)
+        /* we do this test only if we have IPv4 routes to install, and if
+         * the tun/tap interface has seen IPv4 ifconfig - because if we
+         * have no IPv4, the check will always fail, failing tun init
+         */
+        if (rl && c->c1.tuntap->did_ifconfig_setup)

This code is a bit optimstic :-) - there is no "c" here...

When did this change? In a previous version this was done as

src/openvpn/forward.c +0 -0
index 7d9a338..51e43c2 100644
@@ -292,7 +292,9 @@ check_add_routes_action(struct context *c, const

bool errors)
void
check_add_routes_dowork(struct context *c)
{

-    if (test_routes(c->c1.route_list, c->c1.tuntap))
+    /* skip route check if no IPv4 was configured */
+    if (!c->c1.tuntap->did_ifconfig_setup
+        || test_routes(c->c1.route_list, c->c1.tuntap))
     {
         check_add_routes_action(c, false);
     }

That said, moving this to route.c but corrected as in Gert's attachment looks better.

Selva

#21 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

Hi,

Quoted 3 lines · Selva Nair
Quoted 1 line

This code is a bit optimstic :-) - there is no "c" here...

When did this change? In a previous version this was done as

v2 to v3, because I complained that check_add_routes_dowork() is hard enough to read as it is, and suggested to put the check elsewhere.

All my fault :-)

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#22 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

In reply to Gert Doering

Hi,

On 20/06/18 23:53, Gert Doering wrote:
[cut]

Quoted 5 lines

... because it's just "tt" here, so "tt->did_ifconfig_setup" should be fine... at least it compiled :-) - I've sent you a link to an installer for testing.

Thanks for the installer Gert!
I just tried it on Windows 10 (not my laptop! just in case somebody thinks I use Windows :-P) and unfortunately it does not work as expected.

The failure is reported as:

TUN: adding address failed using service: The parameter is incorrect. [status=87 if_index=42]

I have to double check the code to understand what is different from what Selva tested. In the meantime, you have the full log attached to this email in case somebody wants to give it a look.

Cheers,

Signature · 1 line
Antonio Quartulli

Fri Jun 22 13:43:48 2018 us=883035 Current Parameter Settings:

Fri Jun 22 13:43:48 2018 us=883535   config = 'client-lan.ovpn'
Fri Jun 22 13:43:48 2018 us=883535   mode = 0
Fri Jun 22 13:43:48 2018 us=883535   show_ciphers = DISABLED
Fri Jun 22 13:43:48 2018 us=883535   show_digests = DISABLED
Fri Jun 22 13:43:48 2018 us=883535   show_engines = DISABLED
Fri Jun 22 13:43:48 2018 us=883535   genkey = DISABLED
Fri Jun 22 13:43:48 2018 us=883535   key_pass_file = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=883535   show_tls_ciphers = DISABLED
Fri Jun 22 13:43:48 2018 us=883535   connect_retry_max = 0
Fri Jun 22 13:43:48 2018 us=883535 Connection profiles [0]:
Fri Jun 22 13:43:48 2018 us=883535   proto = udp
Fri Jun 22 13:43:48 2018 us=883535   local = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=883535   local_port = '1194'
Fri Jun 22 13:43:48 2018 us=883535   remote = '192.168.1.190'
Fri Jun 22 13:43:48 2018 us=883535   remote_port = '1194'
Fri Jun 22 13:43:48 2018 us=883535   remote_float = DISABLED
Fri Jun 22 13:43:48 2018 us=883535   bind_defined = DISABLED
Fri Jun 22 13:43:48 2018 us=883535   bind_local = ENABLED
Fri Jun 22 13:43:48 2018 us=883535   bind_ipv6_only = DISABLED
Fri Jun 22 13:43:48 2018 us=883535   connect_retry_seconds = 5
Fri Jun 22 13:43:48 2018 us=883535   connect_timeout = 120
Fri Jun 22 13:43:48 2018 us=883535   socks_proxy_server = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=883535   socks_proxy_port = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=883535   tun_mtu = 1500
Fri Jun 22 13:43:48 2018 us=883535   tun_mtu_defined = ENABLED
Fri Jun 22 13:43:48 2018 us=884034   link_mtu = 1500
Fri Jun 22 13:43:48 2018 us=884034   link_mtu_defined = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   tun_mtu_extra = 0
Fri Jun 22 13:43:48 2018 us=884034   tun_mtu_extra_defined = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   mtu_discover_type = -1
Fri Jun 22 13:43:48 2018 us=884034   fragment = 0
Fri Jun 22 13:43:48 2018 us=884034   mssfix = 1450
Fri Jun 22 13:43:48 2018 us=884034   explicit_exit_notification = 0
Fri Jun 22 13:43:48 2018 us=884034 Connection profiles END
Fri Jun 22 13:43:48 2018 us=884034   remote_random = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   ipchange = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   dev = 'tun'
Fri Jun 22 13:43:48 2018 us=884034   dev_type = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   dev_node = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   lladdr = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   topology = 1
Fri Jun 22 13:43:48 2018 us=884034   ifconfig_local = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   ifconfig_remote_netmask = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   ifconfig_noexec = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   ifconfig_nowarn = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   ifconfig_ipv6_local = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   ifconfig_ipv6_netbits = 0
Fri Jun 22 13:43:48 2018 us=884034   ifconfig_ipv6_remote = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   shaper = 0
Fri Jun 22 13:43:48 2018 us=884034   mtu_test = 0
Fri Jun 22 13:43:48 2018 us=884034   mlock = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   keepalive_ping = 10
Fri Jun 22 13:43:48 2018 us=884034   keepalive_timeout = 120
Fri Jun 22 13:43:48 2018 us=884034   inactivity_timeout = 0
Fri Jun 22 13:43:48 2018 us=884034   ping_send_timeout = 10
Fri Jun 22 13:43:48 2018 us=884034   ping_rec_timeout = 120
Fri Jun 22 13:43:48 2018 us=884034   ping_rec_timeout_action = 2
Fri Jun 22 13:43:48 2018 us=884034   ping_timer_remote = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   remap_sigusr1 = 0
Fri Jun 22 13:43:48 2018 us=884034   persist_tun = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   persist_local_ip = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   persist_remote_ip = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   persist_key = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   passtos = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   resolve_retry_seconds = 1000000000
Fri Jun 22 13:43:48 2018 us=884034   resolve_in_advance = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   username = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   groupname = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   chroot_dir = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   cd_dir = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   writepid = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   up_script = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   down_script = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   down_pre = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   up_restart = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   up_delay = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   daemon = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   inetd = 0
Fri Jun 22 13:43:48 2018 us=884034   log = ENABLED
Fri Jun 22 13:43:48 2018 us=884034   suppress_timestamps = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   machine_readable_output = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   nice = 0
Fri Jun 22 13:43:48 2018 us=884034   verbosity = 4
Fri Jun 22 13:43:48 2018 us=884034   mute = 0
Fri Jun 22 13:43:48 2018 us=884034   gremlin = 0
Fri Jun 22 13:43:48 2018 us=884034   status_file = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   status_file_version = 1
Fri Jun 22 13:43:48 2018 us=884034   status_file_update_freq = 60
Fri Jun 22 13:43:48 2018 us=884034   occ = ENABLED
Fri Jun 22 13:43:48 2018 us=884034   rcvbuf = 0
Fri Jun 22 13:43:48 2018 us=884034   sndbuf = 0
Fri Jun 22 13:43:48 2018 us=884034   sockflags = 0
Fri Jun 22 13:43:48 2018 us=884034   fast_io = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   comp.alg = 0
Fri Jun 22 13:43:48 2018 us=884034   comp.flags = 0
Fri Jun 22 13:43:48 2018 us=884034   route_script = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   route_default_gateway = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   route_default_metric = 0
Fri Jun 22 13:43:48 2018 us=884034   route_noexec = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   route_delay = 5
Fri Jun 22 13:43:48 2018 us=884034   route_delay_window = 30
Fri Jun 22 13:43:48 2018 us=884034   route_delay_defined = ENABLED
Fri Jun 22 13:43:48 2018 us=884034   route_nopull = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   route_gateway_via_dhcp = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   allow_pull_fqdn = DISABLED
Fri Jun 22 13:43:48 2018 us=884034   management_addr = '127.0.0.1'
Fri Jun 22 13:43:48 2018 us=884034   management_port = '25340'
Fri Jun 22 13:43:48 2018 us=884034   management_user_pass = 'stdin'
Fri Jun 22 13:43:48 2018 us=884034   management_log_history_cache = 250
Fri Jun 22 13:43:48 2018 us=884034   management_echo_buffer_size = 100
Fri Jun 22 13:43:48 2018 us=884034   management_write_peer_info_file = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   management_client_user = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884034   management_client_group = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   management_flags = 6
Fri Jun 22 13:43:48 2018 us=884532   shared_secret_file = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   key_direction = not set
Fri Jun 22 13:43:48 2018 us=884532   ciphername = 'AES-256-CBC'
Fri Jun 22 13:43:48 2018 us=884532   ncp_enabled = ENABLED
Fri Jun 22 13:43:48 2018 us=884532   ncp_ciphers = 'AES-256-GCM:AES-128-GCM'
Fri Jun 22 13:43:48 2018 us=884532   authname = 'SHA1'
Fri Jun 22 13:43:48 2018 us=884532   prng_hash = 'SHA1'
Fri Jun 22 13:43:48 2018 us=884532   prng_nonce_secret_len = 16
Fri Jun 22 13:43:48 2018 us=884532   keysize = 0
Fri Jun 22 13:43:48 2018 us=884532   engine = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   replay = ENABLED
Fri Jun 22 13:43:48 2018 us=884532   mute_replay_warnings = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   replay_window = 64
Fri Jun 22 13:43:48 2018 us=884532   replay_time = 15
Fri Jun 22 13:43:48 2018 us=884532   packet_id_file = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   test_crypto = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   tls_server = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   tls_client = ENABLED
Fri Jun 22 13:43:48 2018 us=884532   key_method = 2
Fri Jun 22 13:43:48 2018 us=884532   ca_file = '[[INLINE]]'
Fri Jun 22 13:43:48 2018 us=884532   ca_path = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   dh_file = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   cert_file = '[[INLINE]]'
Fri Jun 22 13:43:48 2018 us=884532   extra_certs_file = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   priv_key_file = '[[INLINE]]'
Fri Jun 22 13:43:48 2018 us=884532   pkcs12_file = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   cryptoapi_cert = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   cipher_list = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   tls_cert_profile = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   tls_verify = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   tls_export_cert = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   verify_x509_type = 0
Fri Jun 22 13:43:48 2018 us=884532   verify_x509_name = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   crl_file = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   ns_cert_type = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_ku[i] = 0
Fri Jun 22 13:43:48 2018 us=884532   remote_cert_eku = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   ssl_flags = 0
Fri Jun 22 13:43:48 2018 us=884532   tls_timeout = 2
Fri Jun 22 13:43:48 2018 us=884532   renegotiate_bytes = -1
Fri Jun 22 13:43:48 2018 us=884532   renegotiate_packets = 0
Fri Jun 22 13:43:48 2018 us=884532   renegotiate_seconds = 3600
Fri Jun 22 13:43:48 2018 us=884532   handshake_window = 60
Fri Jun 22 13:43:48 2018 us=884532   transition_window = 3600
Fri Jun 22 13:43:48 2018 us=884532   single_session = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   push_peer_info = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   tls_exit = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   tls_auth_file = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   tls_crypt_file = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_protected_authentication = DISABLED
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=884532   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_private_mode = 00000000
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_cert_private = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_pin_cache_period = -1
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_id = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=885031   pkcs11_id_management = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   server_network = 0.0.0.0
Fri Jun 22 13:43:48 2018 us=885031   server_netmask = 0.0.0.0
Fri Jun 22 13:43:48 2018 us=885031   server_network_ipv6 = ::
Fri Jun 22 13:43:48 2018 us=885031   server_netbits_ipv6 = 0
Fri Jun 22 13:43:48 2018 us=885031   server_bridge_ip = 0.0.0.0
Fri Jun 22 13:43:48 2018 us=885031   server_bridge_netmask = 0.0.0.0
Fri Jun 22 13:43:48 2018 us=885031   server_bridge_pool_start = 0.0.0.0
Fri Jun 22 13:43:48 2018 us=885031   server_bridge_pool_end = 0.0.0.0
Fri Jun 22 13:43:48 2018 us=885031   ifconfig_pool_defined = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   ifconfig_pool_start = 0.0.0.0
Fri Jun 22 13:43:48 2018 us=885031   ifconfig_pool_end = 0.0.0.0
Fri Jun 22 13:43:48 2018 us=885031   ifconfig_pool_netmask = 0.0.0.0
Fri Jun 22 13:43:48 2018 us=885031   ifconfig_pool_persist_filename = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=885031   ifconfig_pool_persist_refresh_freq = 600
Fri Jun 22 13:43:48 2018 us=885031   ifconfig_ipv6_pool_defined = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   ifconfig_ipv6_pool_base = ::
Fri Jun 22 13:43:48 2018 us=885031   ifconfig_ipv6_pool_netbits = 0
Fri Jun 22 13:43:48 2018 us=885031   n_bcast_buf = 256
Fri Jun 22 13:43:48 2018 us=885031   tcp_queue_limit = 64
Fri Jun 22 13:43:48 2018 us=885031   real_hash_size = 256
Fri Jun 22 13:43:48 2018 us=885031   virtual_hash_size = 256
Fri Jun 22 13:43:48 2018 us=885031   client_connect_script = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=885031   learn_address_script = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=885031   client_disconnect_script = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=885031   client_config_dir = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=885031   ccd_exclusive = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   tmp_dir = 'C:\Users\Nicol\AppData\Local\Temp\'
Fri Jun 22 13:43:48 2018 us=885031   push_ifconfig_defined = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   push_ifconfig_local = 0.0.0.0
Fri Jun 22 13:43:48 2018 us=885031   push_ifconfig_remote_netmask = 0.0.0.0
Fri Jun 22 13:43:48 2018 us=885031   push_ifconfig_ipv6_defined = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   push_ifconfig_ipv6_local = ::/0
Fri Jun 22 13:43:48 2018 us=885031   push_ifconfig_ipv6_remote = ::
Fri Jun 22 13:43:48 2018 us=885031   enable_c2c = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   duplicate_cn = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   cf_max = 0
Fri Jun 22 13:43:48 2018 us=885031   cf_per = 0
Fri Jun 22 13:43:48 2018 us=885031   max_clients = 1024
Fri Jun 22 13:43:48 2018 us=885031   max_routes_per_client = 256
Fri Jun 22 13:43:48 2018 us=885031   auth_user_pass_verify_script = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=885031   auth_user_pass_verify_script_via_file = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   auth_token_generate = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   auth_token_lifetime = 0
Fri Jun 22 13:43:48 2018 us=885031   client = ENABLED
Fri Jun 22 13:43:48 2018 us=885031   pull = ENABLED
Fri Jun 22 13:43:48 2018 us=885031   auth_user_pass_file = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=885031   show_net_up = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   route_method = 3
Fri Jun 22 13:43:48 2018 us=885031   block_outside_dns = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   ip_win32_defined = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   ip_win32_type = 3
Fri Jun 22 13:43:48 2018 us=885031   dhcp_masq_offset = 0
Fri Jun 22 13:43:48 2018 us=885031   dhcp_lease_time = 31536000
Fri Jun 22 13:43:48 2018 us=885031   tap_sleep = 0
Fri Jun 22 13:43:48 2018 us=885031   dhcp_options = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   dhcp_renew = DISABLED
Fri Jun 22 13:43:48 2018 us=885031   dhcp_pre_release = DISABLED
Fri Jun 22 13:43:48 2018 us=885530   domain = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=885530   netbios_scope = '[UNDEF]'
Fri Jun 22 13:43:48 2018 us=885530   netbios_node_type = 0
Fri Jun 22 13:43:48 2018 us=885530   disable_nbt = DISABLED

Fri Jun 22 13:43:48 2018 us=885530 OpenVPN 2.5_git x86_64-w64-mingw32 [SSL (OpenSSL)] [LZO] [LZ4] [PKCS11] [AEAD] built on Jun 20 2018
Fri Jun 22 13:43:48 2018 us=885530 Windows version 6.2 (Windows 8 or greater) 64bit
Fri Jun 22 13:43:48 2018 us=885530 library versions: OpenSSL 1.0.2n 7 Dec 2017, LZO 2.10
Enter Management Password:
Fri Jun 22 13:43:48 2018 us=886030 MANAGEMENT: TCP Socket listening on [AF_INET]127.0.0.1:25340
Fri Jun 22 13:43:48 2018 us=886030 Need hold release from management interface, waiting...
Fri Jun 22 13:43:49 2018 us=188374 MANAGEMENT: Client connected from [AF_INET]127.0.0.1:25340
Fri Jun 22 13:43:49 2018 us=289279 MANAGEMENT: CMD 'state on'
Fri Jun 22 13:43:49 2018 us=289279 MANAGEMENT: CMD 'log all on'
Fri Jun 22 13:43:49 2018 us=418667 MANAGEMENT: CMD 'echo all on'
Fri Jun 22 13:43:49 2018 us=420666 MANAGEMENT: CMD 'hold off'
Fri Jun 22 13:43:49 2018 us=421661 MANAGEMENT: CMD 'hold release'
Fri Jun 22 13:43:49 2018 us=422162 WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info.
Fri Jun 22 13:43:49 2018 us=529463 Control Channel MTU parms [ L:1621 D:1212 EF:38 EB:0 ET:0 EL:3 ]
Fri Jun 22 13:43:49 2018 us=529463 Data Channel MTU parms [ L:1621 D:1450 EF:121 EB:406 ET:0 EL:3 ]
Fri Jun 22 13:43:49 2018 us=529463 Local Options String (VER=V4): 'V4,dev-type tun,link-mtu 1557,tun-mtu 1500,proto UDPv4,cipher AES-256-CBC,auth SHA1,keysize 256,key-method 2,tls-client' Fri Jun 22 13:43:49 2018 us=529463 Expected Remote Options String (VER=V4): 'V4,dev-type tun,link-mtu 1557,tun-mtu 1500,proto UDPv4,cipher AES-256-CBC,auth SHA1,keysize 256,key-method 2,tls-server' Fri Jun 22 13:43:49 2018 us=529463 TCP/UDP: Preserving recently used remote address: [AF_INET]192.168.1.190:1194
Fri Jun 22 13:43:49 2018 us=529463 Socket Buffers: R=[65536->65536] S=[65536->65536]
Fri Jun 22 13:43:49 2018 us=529962 UDP link local (bound): [AF_INET][undef]:1194
Fri Jun 22 13:43:49 2018 us=529962 UDP link remote: [AF_INET]192.168.1.190:1194
Fri Jun 22 13:43:49 2018 us=529962 MANAGEMENT: >STATE:1529646229,WAIT,,,,,,
Fri Jun 22 13:43:49 2018 us=667818 MANAGEMENT: >STATE:1529646229,AUTH,,,,,,
Fri Jun 22 13:43:49 2018 us=667818 TLS: Initial packet from [AF_INET]192.168.1.190:1194, sid=63a560b7 d2d590fb
Fri Jun 22 13:43:49 2018 us=677343 VERIFY OK: depth=1, CN=Easy-RSA CA
Fri Jun 22 13:43:49 2018 us=677842 VERIFY OK: depth=0, CN=server
Fri Jun 22 13:43:49 2018 us=687341 Control Channel: TLSv1.2, cipher TLSv1/SSLv3 ECDHE-RSA-AES256-GCM-SHA384, 2048 bit RSA
Fri Jun 22 13:43:49 2018 us=687341 [server] Peer Connection Initiated with [AF_INET]192.168.1.190:1194
Fri Jun 22 13:43:50 2018 us=886603 MANAGEMENT: >STATE:1529646230,GET_CONFIG,,,,,,
Fri Jun 22 13:43:50 2018 us=886603 SENT CONTROL [server]: 'PUSH_REQUEST' (status=1)
Fri Jun 22 13:43:51 2018 us=116232 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway !ipv4 ipv6,tun-ipv6,ping 10,ping-restart 120,ifconfig-ipv6 2002::1001/112 2002::2,peer-id 0,cipher AES-256-GCM' Fri Jun 22 13:43:51 2018 us=116232 OPTIONS IMPORT: timers and/or timeouts modified
Fri Jun 22 13:43:51 2018 us=116232 OPTIONS IMPORT: --ifconfig/up options modified
Fri Jun 22 13:43:51 2018 us=116232 OPTIONS IMPORT: route options modified
Fri Jun 22 13:43:51 2018 us=116232 OPTIONS IMPORT: peer-id set
Fri Jun 22 13:43:51 2018 us=116232 OPTIONS IMPORT: adjusting link_mtu to 1624
Fri Jun 22 13:43:51 2018 us=116232 OPTIONS IMPORT: data channel crypto options modified
Fri Jun 22 13:43:51 2018 us=116232 Data Channel: using negotiated cipher 'AES-256-GCM'
Fri Jun 22 13:43:51 2018 us=116232 Data Channel MTU parms [ L:1552 D:1450 EF:52 EB:406 ET:0 EL:3 ]
Fri Jun 22 13:43:51 2018 us=116232 Outgoing Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
Fri Jun 22 13:43:51 2018 us=116232 Incoming Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
Fri Jun 22 13:43:51 2018 us=116232 interactive service msg_channel=736
Fri Jun 22 13:43:51 2018 us=214906 ROUTE_GATEWAY 192.168.1.1/255.255.255.0 I=8 HWADDR=2c:6e:85:80:d4:aa
Fri Jun 22 13:43:51 2018 us=228188 GDG6: remote_host_ipv6=n/a
Fri Jun 22 13:43:51 2018 us=228188 GetBestInterfaceEx() returned if=8
Fri Jun 22 13:43:51 2018 us=228188 GDG6: II=8 DP=::/0 NH=fe80::9e3d:cfff:feca:d8f0
Fri Jun 22 13:43:51 2018 us=228188 GDG6: Metric=256, Loopback=0, AA=1, I=0
Fri Jun 22 13:43:51 2018 us=228188 ROUTE6_GATEWAY fe80::9e3d:cfff:feca:d8f0 I=8
Fri Jun 22 13:43:51 2018 us=228688 open_tun
Fri Jun 22 13:43:51 2018 us=229170 TAP-WIN32 device [Ethernet 2] opened: \\.\Global\{E780B359-DDDD-4B96-B70F-657F8DC3D55F}.tap
Fri Jun 22 13:43:51 2018 us=229685 TAP-Windows Driver Version 9.21
Fri Jun 22 13:43:51 2018 us=229685 TAP-Windows MTU=1500
Fri Jun 22 13:43:51 2018 us=229685 Set TAP-Windows TUN with fake IPv4 [SUCCEEDED]
Fri Jun 22 13:43:51 2018 us=230166 Successful ARP Flush on interface [42] {E780B359-DDDD-4B96-B70F-657F8DC3D55F}
Fri Jun 22 13:43:51 2018 us=230166 do_ifconfig, ipv4=0, ipv6=1
Fri Jun 22 13:43:51 2018 us=230166 MANAGEMENT: >STATE:1529646231,ASSIGN_IP,,,,,,,2002::1001
Fri Jun 22 13:43:51 2018 us=230665 TUN: adding address failed using service: The parameter is incorrect. [status=87 if_index=42]
Fri Jun 22 13:43:51 2018 us=230665 add_route_ipv6(2002::/112 -> 2002::1001 metric 0) dev Ethernet 2
Fri Jun 22 13:43:51 2018 us=230665 IPv6 route addition via service succeeded
Fri Jun 22 13:43:56 2018 us=729483 TEST ROUTES: 0/0 succeeded len=-1 ret=1 a=0 u/d=up
Fri Jun 22 13:43:56 2018 us=729483 MANAGEMENT: Client disconnected
Fri Jun 22 13:43:56 2018 us=729483 Assertion failed at argv.c:299 (0)
Fri Jun 22 13:43:56 2018 us=729483 Exiting due to fatal error
Fri Jun 22 13:43:56 2018 us=729483 Closing TUN/TAP interface
Fri Jun 22 13:43:56 2018 us=729483 delete_route_ipv6(2002::/112)
Fri Jun 22 13:43:56 2018 us=729980 IPv6 route deletion via service succeeded
Fri Jun 22 13:43:56 2018 us=729980 TUN: deleting address failed using service: The parameter is incorrect. [status=87 if_index=42]
Fri Jun 22 13:43:56 2018 us=853901 NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: An address has not yet been associated with the network endpoint. (code=1228)

#23 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

HI,

Quoted 4 lines · Antonio Quartulli

The failure is reported as:

TUN: adding address failed using service: The parameter is incorrect. [status=87 if_index=42]

This is surprising. I initially assumed that this is related to IPv4, but we do not even use the service for IPv4 today...

This *might* trigger something that the iservice logs to the windows event log - so it might be worth having a look :-)

gert

PS: as a side note - with XP and Vista dropped, we might consider ripping out every win32-api besides IPAPI and iservice, for 2.5...

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#24 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

In reply to Antonio Quartulli

Hi,

Quoted 1 line · Antonio Quartulli

Fri Jun 22 13:43:51 2018 us=116232 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway !ipv4 ipv6,tun-ipv6,ping 10,ping-restart 120,ifconfig-ipv6 2002::1001/112 2002::2,peer-id 0,cipher AES-256-GCM'

As an afterthought - the error could be totally unrelated to the changes, and the win32 API refusing 2002:: addresses because it knows that they are not "free for grabs"... (6to4, normally auto-configured unless disabled, with 2002:<ipv4>:: being the prefix that a host on <ipv4> or a network behind a router on <ipv4> can use - but that's old stuff and should no longer be used in any case).

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#25 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

Hi,

Quoted 11 lines · Gert Doering

Hi,

Quoted 1 line · Antonio Quartulli

Fri Jun 22 13:43:51 2018 us=116232 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway !ipv4 ipv6,tun-ipv6,ping 10,ping-restart 120,ifconfig-ipv6 2002::1001/112 2002::2,peer-id 0,cipher AES-256-GCM'

As an afterthought - the error could be totally unrelated to the changes, and the win32 API refusing 2002:: addresses because it knows that they are not "free for grabs"... (6to4, normally auto-configured unless disabled, with 2002:<ipv4>:: being the prefix that a host on <ipv4> or a network behind a router on <ipv4> can use - but that's old stuff and should no longer be used in any case).

After changing the prefix to 2001:db8:cafe::/112 the error is gone.

However, the assert at the end of the log in argv.c:299 is still there. This might be some argv_new()/reset() that has been misplaced (maybe?).

Cheers,

Signature · 1 line
Antonio Quartulli
#26 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

Hi,

Quoted 17 lines · Antonio Quartulli

Hi,

Quoted 4 lines · Gert Doering

Hi,

Quoted 1 line · Antonio Quartulli

Fri Jun 22 13:43:51 2018 us=116232 PUSH: Received control message:

'PUSH_REPLY,redirect-gateway !ipv4 ipv6,tun-ipv6,ping 10,ping-restart 120,ifconfig-ipv6 2002::1001/112 2002::2,peer-id 0,cipher AES-256-GCM'

Quoted 7 lines

As an afterthought - the error could be totally unrelated to the changes, and the win32 API refusing 2002:: addresses because it knows that they are not "free for grabs"... (6to4, normally auto-configured unless disabled, with 2002:<ipv4>:: being the prefix that a host on <ipv4> or a network behind a router on <ipv4> can use - but that's old stuff and should no longer be used in any case).

Quoted 5 lines

After changing the prefix to 2001:db8:cafe::/112 the error is gone.

However, the assert at the end of the log in argv.c:299 is still there. This might be some argv_new()/reset() that has been misplaced (maybe?).

While the assert is definitely due to buggy code (as discussed in the other thread),
I cant reproduce this. Both the version I had tested earlier and the v2/v3 patches
work without throwing this error.

Earlier I had tested with

pull-filter ignore "ifconfig "
route 192.168.0.0 255.255.255.0 # test a tunnel route
route 192.168.1.0 255.255.255.0 net_gateway # test an external route redirect-gateway ipv6 !ipv4

Now retested by adding

pull-filter ignore route-gateway

as otherwise the v4 tunnel gateway was not null and the v4 route succeeded with a simple warning (gateway unreacahble). With the route gateway removed, the v4 route fails with

Fri Jun 22 13:52:08 2018 OpenVPN ROUTE: OpenVPN needs a gateway parameter for a --route option and no default was specified by either --route-gateway or --ifconfig options
Fri Jun 22 13:52:08 2018 OpenVPN ROUTE: failed to parse/resolve route for host/network: 192.168.0.0
Fri Jun 22 13:52:08 2018 GDG6: remote_host_ipv6=n/a
Fri Jun 22 13:52:08 2018 GetBestInterfaceEx() returned if=15 Fri Jun 22 13:52:08 2018 GDG6: II=15 DP=::/0 NH=fe80::2d0:b7ff:febe:d8bc Fri Jun 22 13:52:08 2018 GDG6: Metric=256, Loopback=0, AA=1, I=0 Fri Jun 22 13:52:08 2018 ROUTE6_GATEWAY fe80::2d0:b7ff:febe:d8bc I=15

Again, no assert.

Possibly you have some v4 route that triggers the assert, but I can't figure which.
Or are you testing using a v6 only server -- even if so, its not clear how that would
matter.

My tap adapter has a link local address (169.254.98.86) on it possibly due to a previous dhcp failure. May be I need to get rid of that (how?) to activate
this code path?

Selva

#27 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

Hi,

Quoted 3 lines · Selva Nair

My tap adapter has a link local address (169.254.98.86) on it possibly due to a previous dhcp failure. May be I need to get rid of that (how?) to activate this code path?

I guess this is related - the branch in question is triggered by is_on_link(), so maybe in Antonio's case the tap adapter is set to 0.0.0.0 - or it actually tried to install a route related to redirect-gateway.

Are you connecting to your VPN server over IPv6 or IPv4? You already spotted one weirdness with "redirect-gateway !ipv4" which still seems to setup "something" in the route_list - so maybe it's related to that, but needs "VPN over IPv4" to trigger.

In other words, no idea - hoping for a log from Antonio that shows the "route.exe ..." call with "IF <ifindex>" so we can see what openvpn tried to do :-)

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#28 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

Quoted 7 lines · Gert Doering

Hi,

Quoted 3 lines · Selva Nair

My tap adapter has a link local address (169.254.98.86) on it possibly due to a previous dhcp failure. May be I need to get rid of that (how?) to activate this code path?

Quoted 6 lines

I guess this is related - the branch in question is triggered by is_on_link(), so maybe in Antonio's case the tap adapter is set to 0.0.0.0 - or it actually tried to install a route related to redirect-gateway.

Are you connecting to your VPN server over IPv6 or IPv4?

This physical link is v4.

I tried without !ipv4 in redirect-gateway and got:

(i) without route-gateway defined: redirecting v4 fails with a warning "route-gateway or ifconfig is missing"

(ii) with route-gateway: the route is added but warns "route gateway not reachable by any active
interfaces" -- fair enough.

Selva

#29 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

In reply to Gert Doering

Hi,

Quoted 12 lines · Gert Doering

Hi,

Quoted 3 lines · Selva Nair

My tap adapter has a link local address (169.254.98.86) on it possibly due to a previous dhcp failure. May be I need to get rid of that (how?) to activate this code path?

I guess this is related - the branch in question is triggered by is_on_link(), so maybe in Antonio's case the tap adapter is set to 0.0.0.0 - or it actually tried to install a route related to redirect-gateway.

Quoted 9 lines

Are you connecting to your VPN server over IPv6 or IPv4? You already spotted one weirdness with "redirect-gateway !ipv4" which still seems to setup "something" in the route_list - so maybe it's related to that, but needs "VPN over IPv4" to trigger.

In other words, no idea - hoping for a log from Antonio that shows the "route.exe ..." call with "IF <ifindex>" so we can see what openvpn tried to do :-)

attached you have the log, however there is no message containing "route.exe ..".

Gert, the ASSERT was triggered with your binary: was it simply master + 2/8 (this patch)?

What I used for my last test is:
* master +
* all the remaining patches from ipv6-only +
* the fix for argv_printf()

The server side is running master + ipv6-only and there is no --server directive in the configuration.

In the log "Ethernet 2" is the TAP interface".

My guts say that the issue might be related to "gateway-redirect", because only 8/8 makes sure that no logic is activated for IPv4 and without that patch there might be some IPv4 route being installed nonetheless.

Cheers,

Signature · 1 line
Antonio Quartulli

Sat Jun 23 00:38:44 2018 us=143551 Current Parameter Settings:

Sat Jun 23 00:38:44 2018 us=144050   config = 'client-lan.ovpn'
Sat Jun 23 00:38:44 2018 us=144050   mode = 0
Sat Jun 23 00:38:44 2018 us=144531   show_ciphers = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   show_digests = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   show_engines = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   genkey = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   key_pass_file = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   show_tls_ciphers = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   connect_retry_max = 0
Sat Jun 23 00:38:44 2018 us=144531 Connection profiles [0]:
Sat Jun 23 00:38:44 2018 us=144531   proto = udp
Sat Jun 23 00:38:44 2018 us=144531   local = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   local_port = '1194'
Sat Jun 23 00:38:44 2018 us=144531   remote = '192.168.1.190'
Sat Jun 23 00:38:44 2018 us=144531   remote_port = '1194'
Sat Jun 23 00:38:44 2018 us=144531   remote_float = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   bind_defined = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   bind_local = ENABLED
Sat Jun 23 00:38:44 2018 us=144531   bind_ipv6_only = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   connect_retry_seconds = 5
Sat Jun 23 00:38:44 2018 us=144531   connect_timeout = 120
Sat Jun 23 00:38:44 2018 us=144531   socks_proxy_server = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   socks_proxy_port = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   tun_mtu = 1500
Sat Jun 23 00:38:44 2018 us=144531   tun_mtu_defined = ENABLED
Sat Jun 23 00:38:44 2018 us=144531   link_mtu = 1500
Sat Jun 23 00:38:44 2018 us=144531   link_mtu_defined = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   tun_mtu_extra = 0
Sat Jun 23 00:38:44 2018 us=144531   tun_mtu_extra_defined = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   mtu_discover_type = -1
Sat Jun 23 00:38:44 2018 us=144531   fragment = 0
Sat Jun 23 00:38:44 2018 us=144531   mssfix = 1450
Sat Jun 23 00:38:44 2018 us=144531   explicit_exit_notification = 0
Sat Jun 23 00:38:44 2018 us=144531 Connection profiles END
Sat Jun 23 00:38:44 2018 us=144531   remote_random = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   ipchange = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   dev = 'tun'
Sat Jun 23 00:38:44 2018 us=144531   dev_type = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   dev_node = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   lladdr = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   topology = 1
Sat Jun 23 00:38:44 2018 us=144531   ifconfig_local = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   ifconfig_remote_netmask = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   ifconfig_noexec = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   ifconfig_nowarn = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   ifconfig_ipv6_local = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   ifconfig_ipv6_netbits = 0
Sat Jun 23 00:38:44 2018 us=144531   ifconfig_ipv6_remote = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   shaper = 0
Sat Jun 23 00:38:44 2018 us=144531   mtu_test = 0
Sat Jun 23 00:38:44 2018 us=144531   mlock = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   keepalive_ping = 10
Sat Jun 23 00:38:44 2018 us=144531   keepalive_timeout = 120
Sat Jun 23 00:38:44 2018 us=144531   inactivity_timeout = 0
Sat Jun 23 00:38:44 2018 us=144531   ping_send_timeout = 10
Sat Jun 23 00:38:44 2018 us=144531   ping_rec_timeout = 120
Sat Jun 23 00:38:44 2018 us=144531   ping_rec_timeout_action = 2
Sat Jun 23 00:38:44 2018 us=144531   ping_timer_remote = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   remap_sigusr1 = 0
Sat Jun 23 00:38:44 2018 us=144531   persist_tun = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   persist_local_ip = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   persist_remote_ip = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   persist_key = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   passtos = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   resolve_retry_seconds = 1000000000
Sat Jun 23 00:38:44 2018 us=144531   resolve_in_advance = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   username = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   groupname = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   chroot_dir = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   cd_dir = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   writepid = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   up_script = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   down_script = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   down_pre = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   up_restart = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   up_delay = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   daemon = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   inetd = 0
Sat Jun 23 00:38:44 2018 us=144531   log = ENABLED
Sat Jun 23 00:38:44 2018 us=144531   suppress_timestamps = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   machine_readable_output = DISABLED
Sat Jun 23 00:38:44 2018 us=144531   nice = 0
Sat Jun 23 00:38:44 2018 us=144531   verbosity = 4
Sat Jun 23 00:38:44 2018 us=144531   mute = 0
Sat Jun 23 00:38:44 2018 us=144531   gremlin = 0
Sat Jun 23 00:38:44 2018 us=144531   status_file = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=144531   status_file_version = 1
Sat Jun 23 00:38:44 2018 us=144531   status_file_update_freq = 60
Sat Jun 23 00:38:44 2018 us=144531   occ = ENABLED
Sat Jun 23 00:38:44 2018 us=144531   rcvbuf = 0
Sat Jun 23 00:38:44 2018 us=144531   sndbuf = 0
Sat Jun 23 00:38:44 2018 us=144531   sockflags = 0
Sat Jun 23 00:38:44 2018 us=145049   fast_io = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   comp.alg = 0
Sat Jun 23 00:38:44 2018 us=145049   comp.flags = 0
Sat Jun 23 00:38:44 2018 us=145049   route_script = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   route_default_gateway = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   route_default_metric = 0
Sat Jun 23 00:38:44 2018 us=145049   route_noexec = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   route_delay = 5
Sat Jun 23 00:38:44 2018 us=145049   route_delay_window = 30
Sat Jun 23 00:38:44 2018 us=145049   route_delay_defined = ENABLED
Sat Jun 23 00:38:44 2018 us=145049   route_nopull = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   route_gateway_via_dhcp = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   allow_pull_fqdn = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   management_addr = '127.0.0.1'
Sat Jun 23 00:38:44 2018 us=145049   management_port = '25340'
Sat Jun 23 00:38:44 2018 us=145049   management_user_pass = 'stdin'
Sat Jun 23 00:38:44 2018 us=145049   management_log_history_cache = 250
Sat Jun 23 00:38:44 2018 us=145049   management_echo_buffer_size = 100
Sat Jun 23 00:38:44 2018 us=145049   management_write_peer_info_file = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   management_client_user = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   management_client_group = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   management_flags = 6
Sat Jun 23 00:38:44 2018 us=145049   shared_secret_file = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   key_direction = not set
Sat Jun 23 00:38:44 2018 us=145049   ciphername = 'AES-256-CBC'
Sat Jun 23 00:38:44 2018 us=145049   ncp_enabled = ENABLED
Sat Jun 23 00:38:44 2018 us=145049   ncp_ciphers = 'AES-256-GCM:AES-128-GCM'
Sat Jun 23 00:38:44 2018 us=145049   authname = 'SHA1'
Sat Jun 23 00:38:44 2018 us=145049   prng_hash = 'SHA1'
Sat Jun 23 00:38:44 2018 us=145049   prng_nonce_secret_len = 16
Sat Jun 23 00:38:44 2018 us=145049   keysize = 0
Sat Jun 23 00:38:44 2018 us=145049   engine = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   replay = ENABLED
Sat Jun 23 00:38:44 2018 us=145049   mute_replay_warnings = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   replay_window = 64
Sat Jun 23 00:38:44 2018 us=145049   replay_time = 15
Sat Jun 23 00:38:44 2018 us=145049   packet_id_file = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   test_crypto = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   tls_server = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   tls_client = ENABLED
Sat Jun 23 00:38:44 2018 us=145049   key_method = 2
Sat Jun 23 00:38:44 2018 us=145049   ca_file = '[[INLINE]]'
Sat Jun 23 00:38:44 2018 us=145049   ca_path = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   dh_file = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   cert_file = '[[INLINE]]'
Sat Jun 23 00:38:44 2018 us=145049   extra_certs_file = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   priv_key_file = '[[INLINE]]'
Sat Jun 23 00:38:44 2018 us=145049   pkcs12_file = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   cryptoapi_cert = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   cipher_list = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   tls_cert_profile = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   tls_verify = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   tls_export_cert = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   verify_x509_type = 0
Sat Jun 23 00:38:44 2018 us=145049   verify_x509_name = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   crl_file = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   ns_cert_type = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_ku[i] = 0
Sat Jun 23 00:38:44 2018 us=145049   remote_cert_eku = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   ssl_flags = 0
Sat Jun 23 00:38:44 2018 us=145049   tls_timeout = 2
Sat Jun 23 00:38:44 2018 us=145049   renegotiate_bytes = -1
Sat Jun 23 00:38:44 2018 us=145049   renegotiate_packets = 0
Sat Jun 23 00:38:44 2018 us=145049   renegotiate_seconds = 3600
Sat Jun 23 00:38:44 2018 us=145049   handshake_window = 60
Sat Jun 23 00:38:44 2018 us=145049   transition_window = 3600
Sat Jun 23 00:38:44 2018 us=145049   single_session = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   push_peer_info = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   tls_exit = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   tls_auth_file = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   tls_crypt_file = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145049   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145049   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_protected_authentication = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_private_mode = 00000000
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_cert_private = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_pin_cache_period = -1
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_id = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145547   pkcs11_id_management = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   server_network = 0.0.0.0
Sat Jun 23 00:38:44 2018 us=145547   server_netmask = 0.0.0.0
Sat Jun 23 00:38:44 2018 us=145547   server_network_ipv6 = ::
Sat Jun 23 00:38:44 2018 us=145547   server_netbits_ipv6 = 0
Sat Jun 23 00:38:44 2018 us=145547   server_bridge_ip = 0.0.0.0
Sat Jun 23 00:38:44 2018 us=145547   server_bridge_netmask = 0.0.0.0
Sat Jun 23 00:38:44 2018 us=145547   server_bridge_pool_start = 0.0.0.0
Sat Jun 23 00:38:44 2018 us=145547   server_bridge_pool_end = 0.0.0.0
Sat Jun 23 00:38:44 2018 us=145547   ifconfig_pool_defined = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   ifconfig_pool_start = 0.0.0.0
Sat Jun 23 00:38:44 2018 us=145547   ifconfig_pool_end = 0.0.0.0
Sat Jun 23 00:38:44 2018 us=145547   ifconfig_pool_netmask = 0.0.0.0
Sat Jun 23 00:38:44 2018 us=145547   ifconfig_pool_persist_filename = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145547   ifconfig_pool_persist_refresh_freq = 600
Sat Jun 23 00:38:44 2018 us=145547   ifconfig_ipv6_pool_defined = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   ifconfig_ipv6_pool_base = ::
Sat Jun 23 00:38:44 2018 us=145547   ifconfig_ipv6_pool_netbits = 0
Sat Jun 23 00:38:44 2018 us=145547   n_bcast_buf = 256
Sat Jun 23 00:38:44 2018 us=145547   tcp_queue_limit = 64
Sat Jun 23 00:38:44 2018 us=145547   real_hash_size = 256
Sat Jun 23 00:38:44 2018 us=145547   virtual_hash_size = 256
Sat Jun 23 00:38:44 2018 us=145547   client_connect_script = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145547   learn_address_script = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145547   client_disconnect_script = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145547   client_config_dir = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=145547   ccd_exclusive = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   tmp_dir = 'C:\Users\Nicol\AppData\Local\Temp\'
Sat Jun 23 00:38:44 2018 us=145547   push_ifconfig_defined = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   push_ifconfig_local = 0.0.0.0
Sat Jun 23 00:38:44 2018 us=145547   push_ifconfig_remote_netmask = 0.0.0.0
Sat Jun 23 00:38:44 2018 us=145547   push_ifconfig_ipv6_defined = DISABLED
Sat Jun 23 00:38:44 2018 us=145547   push_ifconfig_ipv6_local = ::/0
Sat Jun 23 00:38:44 2018 us=145547   push_ifconfig_ipv6_remote = ::
Sat Jun 23 00:38:44 2018 us=146049   enable_c2c = DISABLED
Sat Jun 23 00:38:44 2018 us=146049   duplicate_cn = DISABLED
Sat Jun 23 00:38:44 2018 us=146049   cf_max = 0
Sat Jun 23 00:38:44 2018 us=146049   cf_per = 0
Sat Jun 23 00:38:44 2018 us=146049   max_clients = 1024
Sat Jun 23 00:38:44 2018 us=146049   max_routes_per_client = 256
Sat Jun 23 00:38:44 2018 us=146049   auth_user_pass_verify_script = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=146049   auth_user_pass_verify_script_via_file = DISABLED
Sat Jun 23 00:38:44 2018 us=146049   auth_token_generate = DISABLED
Sat Jun 23 00:38:44 2018 us=146049   auth_token_lifetime = 0
Sat Jun 23 00:38:44 2018 us=146049   client = ENABLED
Sat Jun 23 00:38:44 2018 us=146049   pull = ENABLED
Sat Jun 23 00:38:44 2018 us=146049   auth_user_pass_file = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=146049   show_net_up = DISABLED
Sat Jun 23 00:38:44 2018 us=146049   route_method = 3
Sat Jun 23 00:38:44 2018 us=146049   block_outside_dns = DISABLED
Sat Jun 23 00:38:44 2018 us=146049   ip_win32_defined = DISABLED
Sat Jun 23 00:38:44 2018 us=146049   ip_win32_type = 3
Sat Jun 23 00:38:44 2018 us=146049   dhcp_masq_offset = 0
Sat Jun 23 00:38:44 2018 us=146049   dhcp_lease_time = 31536000
Sat Jun 23 00:38:44 2018 us=146049   tap_sleep = 0
Sat Jun 23 00:38:44 2018 us=146049   dhcp_options = DISABLED
Sat Jun 23 00:38:44 2018 us=146049   dhcp_renew = DISABLED
Sat Jun 23 00:38:44 2018 us=146049   dhcp_pre_release = DISABLED
Sat Jun 23 00:38:44 2018 us=146049   domain = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=146049   netbios_scope = '[UNDEF]'
Sat Jun 23 00:38:44 2018 us=146049   netbios_node_type = 0
Sat Jun 23 00:38:44 2018 us=146049   disable_nbt = DISABLED

Sat Jun 23 00:38:44 2018 us=146049 OpenVPN 2.5_git x86_64-w64-mingw32 [SSL (OpenSSL)] [LZO] [LZ4] [PKCS11] [AEAD] built on Jun 22 2018
Sat Jun 23 00:38:44 2018 us=146049 Windows version 6.2 (Windows 8 or greater) 64bit
Sat Jun 23 00:38:44 2018 us=146049 library versions: OpenSSL 1.0.2n 7 Dec 2017, LZO 2.10
Enter Management Password:
Sat Jun 23 00:38:44 2018 us=146528 MANAGEMENT: TCP Socket listening on [AF_INET]127.0.0.1:25340
Sat Jun 23 00:38:44 2018 us=146528 Need hold release from management interface, waiting...
Sat Jun 23 00:38:44 2018 us=557288 MANAGEMENT: Client connected from [AF_INET]127.0.0.1:25340
Sat Jun 23 00:38:44 2018 us=663132 MANAGEMENT: CMD 'state on'
Sat Jun 23 00:38:44 2018 us=663132 MANAGEMENT: CMD 'log all on'
Sat Jun 23 00:38:44 2018 us=789409 MANAGEMENT: CMD 'echo all on'
Sat Jun 23 00:38:44 2018 us=791407 MANAGEMENT: CMD 'hold off'
Sat Jun 23 00:38:44 2018 us=792919 MANAGEMENT: CMD 'hold release'
Sat Jun 23 00:38:44 2018 us=793401 WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info.
Sat Jun 23 00:38:44 2018 us=897279 Control Channel MTU parms [ L:1621 D:1212 EF:38 EB:0 ET:0 EL:3 ]
Sat Jun 23 00:38:44 2018 us=897780 Data Channel MTU parms [ L:1621 D:1450 EF:121 EB:406 ET:0 EL:3 ]
Sat Jun 23 00:38:44 2018 us=897780 Local Options String (VER=V4): 'V4,dev-type tun,link-mtu 1557,tun-mtu 1500,proto UDPv4,cipher AES-256-CBC,auth SHA1,keysize 256,key-method 2,tls-client' Sat Jun 23 00:38:44 2018 us=897780 Expected Remote Options String (VER=V4): 'V4,dev-type tun,link-mtu 1557,tun-mtu 1500,proto UDPv4,cipher AES-256-CBC,auth SHA1,keysize 256,key-method 2,tls-server' Sat Jun 23 00:38:44 2018 us=897780 TCP/UDP: Preserving recently used remote address: [AF_INET]192.168.1.190:1194
Sat Jun 23 00:38:44 2018 us=897780 Socket Buffers: R=[65536->65536] S=[65536->65536]
Sat Jun 23 00:38:44 2018 us=897780 UDP link local (bound): [AF_INET][undef]:1194
Sat Jun 23 00:38:44 2018 us=897780 UDP link remote: [AF_INET]192.168.1.190:1194
Sat Jun 23 00:38:44 2018 us=897780 MANAGEMENT: >STATE:1529685524,WAIT,,,,,,
Sat Jun 23 00:38:44 2018 us=919785 MANAGEMENT: >STATE:1529685524,AUTH,,,,,,
Sat Jun 23 00:38:44 2018 us=919785 TLS: Initial packet from [AF_INET]192.168.1.190:1194, sid=26b4cac9 530ee636
Sat Jun 23 00:38:44 2018 us=931266 VERIFY OK: depth=1, CN=Easy-RSA CA
Sat Jun 23 00:38:44 2018 us=931787 VERIFY OK: depth=0, CN=server
Sat Jun 23 00:38:44 2018 us=945339 Control Channel: TLSv1.2, cipher TLSv1/SSLv3 ECDHE-RSA-AES256-GCM-SHA384, 2048 bit RSA
Sat Jun 23 00:38:44 2018 us=945339 [server] Peer Connection Initiated with [AF_INET]192.168.1.190:1194
Sat Jun 23 00:38:46 2018 us=20355 MANAGEMENT: >STATE:1529685526,GET_CONFIG,,,,,,
Sat Jun 23 00:38:46 2018 us=20355 SENT CONTROL [server]: 'PUSH_REQUEST' (status=1)
Sat Jun 23 00:38:46 2018 us=339449 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway !ipv4 ipv6,tun-ipv6,ping 10,ping-restart 120,ifconfig-ipv6 2001:db8:cafe::1000/112 2001:db8:cafe::1,peer-id 0,cipher AES-256-GCM' Sat Jun 23 00:38:46 2018 us=339449 OPTIONS IMPORT: timers and/or timeouts modified
Sat Jun 23 00:38:46 2018 us=339449 OPTIONS IMPORT: --ifconfig/up options modified
Sat Jun 23 00:38:46 2018 us=339449 OPTIONS IMPORT: route options modified
Sat Jun 23 00:38:46 2018 us=339449 OPTIONS IMPORT: peer-id set
Sat Jun 23 00:38:46 2018 us=339449 OPTIONS IMPORT: adjusting link_mtu to 1624
Sat Jun 23 00:38:46 2018 us=339449 OPTIONS IMPORT: data channel crypto options modified
Sat Jun 23 00:38:46 2018 us=339449 Data Channel: using negotiated cipher 'AES-256-GCM'
Sat Jun 23 00:38:46 2018 us=339449 Data Channel MTU parms [ L:1552 D:1450 EF:52 EB:406 ET:0 EL:3 ]
Sat Jun 23 00:38:46 2018 us=339449 Outgoing Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
Sat Jun 23 00:38:46 2018 us=339449 Incoming Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
Sat Jun 23 00:38:46 2018 us=339969 interactive service msg_channel=608
Sat Jun 23 00:38:46 2018 us=431773 ROUTE_GATEWAY 192.168.1.1/255.255.255.0 I=8 HWADDR=2c:6e:85:80:d4:aa
Sat Jun 23 00:38:46 2018 us=431773 GDG6: remote_host_ipv6=n/a
Sat Jun 23 00:38:46 2018 us=431773 GetBestInterfaceEx() returned if=8
Sat Jun 23 00:38:46 2018 us=431773 GDG6: II=8 DP=::/0 NH=fe80::9e3d:cfff:feca:d8f0
Sat Jun 23 00:38:46 2018 us=431773 GDG6: Metric=256, Loopback=0, AA=1, I=0
Sat Jun 23 00:38:46 2018 us=431773 ROUTE6_GATEWAY fe80::9e3d:cfff:feca:d8f0 I=8
Sat Jun 23 00:38:46 2018 us=431773 open_tun
Sat Jun 23 00:38:46 2018 us=432771 TAP-WIN32 device [Ethernet 2] opened: \\.\Global\{E780B359-DDDD-4B96-B70F-657F8DC3D55F}.tap
Sat Jun 23 00:38:46 2018 us=432771 TAP-Windows Driver Version 9.21
Sat Jun 23 00:38:46 2018 us=432771 TAP-Windows MTU=1500
Sat Jun 23 00:38:46 2018 us=433270 Set TAP-Windows TUN with fake IPv4 [SUCCEEDED]
Sat Jun 23 00:38:46 2018 us=433270 Successful ARP Flush on interface [42] {E780B359-DDDD-4B96-B70F-657F8DC3D55F}
Sat Jun 23 00:38:46 2018 us=433270 do_ifconfig, ipv4=0, ipv6=1
Sat Jun 23 00:38:46 2018 us=433270 MANAGEMENT: >STATE:1529685526,ASSIGN_IP,,,,,,,2001:db8:cafe::1000
Sat Jun 23 00:38:46 2018 us=433270 add_route_ipv6(2001:db8:cafe::/112 -> 2001:db8:cafe::1000 metric 0) dev Ethernet 2
Sat Jun 23 00:38:46 2018 us=433270 IPv6 route addition via service succeeded
Sat Jun 23 00:38:51 2018 us=615720 TEST ROUTES: 0/0 succeeded len=-1 ret=1 a=0 u/d=up
Sat Jun 23 00:38:51 2018 us=615720 add_route_ipv6(::/3 -> 2001:db8:cafe::1 metric -1) dev Ethernet 2
Sat Jun 23 00:38:51 2018 us=615965 IPv6 route addition via service succeeded
Sat Jun 23 00:38:51 2018 us=615965 add_route_ipv6(2000::/4 -> 2001:db8:cafe::1 metric -1) dev Ethernet 2
Sat Jun 23 00:38:51 2018 us=615965 IPv6 route addition via service succeeded
Sat Jun 23 00:38:51 2018 us=615965 add_route_ipv6(3000::/4 -> 2001:db8:cafe::1 metric -1) dev Ethernet 2
Sat Jun 23 00:38:51 2018 us=615965 IPv6 route addition via service succeeded
Sat Jun 23 00:38:51 2018 us=615965 add_route_ipv6(fc00::/7 -> 2001:db8:cafe::1 metric -1) dev Ethernet 2
Sat Jun 23 00:38:51 2018 us=615965 IPv6 route addition via service succeeded
Sat Jun 23 00:38:51 2018 us=615965 WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
Sat Jun 23 00:38:51 2018 us=615965 Initialization Sequence Completed
Sat Jun 23 00:38:51 2018 us=615965 MANAGEMENT: >STATE:1529685531,CONNECTED,SUCCESS,,192.168.1.190,1194,,,2001:db8:cafe::1000
Sat Jun 23 00:40:39 2018 us=283635 TCP/UDP: Closing socket
Sat Jun 23 00:40:39 2018 us=283635 delete_route_ipv6(::/3)
Sat Jun 23 00:40:39 2018 us=283635 IPv6 route deletion via service succeeded
Sat Jun 23 00:40:39 2018 us=284135 delete_route_ipv6(2000::/4)
Sat Jun 23 00:40:39 2018 us=284135 IPv6 route deletion via service succeeded
Sat Jun 23 00:40:39 2018 us=284135 delete_route_ipv6(3000::/4)
Sat Jun 23 00:40:39 2018 us=284135 IPv6 route deletion via service succeeded
Sat Jun 23 00:40:39 2018 us=284135 delete_route_ipv6(fc00::/7)
Sat Jun 23 00:40:39 2018 us=284633 IPv6 route deletion via service succeeded
Sat Jun 23 00:40:39 2018 us=284633 Closing TUN/TAP interface
Sat Jun 23 00:40:39 2018 us=284633 delete_route_ipv6(2001:db8:cafe::/112)
Sat Jun 23 00:40:39 2018 us=284633 IPv6 route deletion via service succeeded
Sat Jun 23 00:40:39 2018 us=392963 NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: An address has not yet been associated with the network endpoint. (code=1228)
Sat Jun 23 00:40:39 2018 us=393464 SIGTERM[hard,] received, process exiting
Sat Jun 23 00:40:39 2018 us=393464 MANAGEMENT: >STATE:1529685639,EXITING,SIGTERM,,,,,

#30 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

Hi,

Quoted 20 lines · Antonio Quartulli

Hi,

Quoted 17 lines · Gert Doering

Hi,

Quoted 3 lines · Selva Nair

My tap adapter has a link local address (169.254.98.86) on it possibly due to a previous dhcp failure. May be I need to get rid of that (how?) to activate this code path?

I guess this is related - the branch in question is triggered by is_on_link(), so maybe in Antonio's case the tap adapter is set to 0.0.0.0 - or it actually tried to install a route related to redirect-gateway.

Are you connecting to your VPN server over IPv6 or IPv4? You already spotted one weirdness with "redirect-gateway !ipv4" which still seems to setup "something" in the route_list - so maybe it's related to that, but needs "VPN over IPv4" to trigger.

Quoted 7 lines
Quoted 4 lines

In other words, no idea - hoping for a log from Antonio that shows the "route.exe ..." call with "IF <ifindex>" so we can see what openvpn tried to do :-)

attached you have the log, however there is no message containing "route.exe ..".

No assert (with argv patch applied?) and no sign of any v4 routes.

Quoted 8 lines

Gert, the ASSERT was triggered with your binary: was it simply master + 2/8 (this patch)?

What I used for my last test is:
* master +
* all the remaining patches from ipv6-only +
* the fix for argv_printf()

So I guess there wont be any assert with such a build even if the argv patch is left out. That would match with what I re-tested.

Quoted 10 lines

The server side is running master + ipv6-only and there is no --server directive in the configuration.

In the log "Ethernet 2" is the TAP interface".

My guts say that the issue might be related to "gateway-redirect", because only 8/8 makes sure that no logic is activated for IPv4 and without that patch there might be some IPv4 route being installed nonetheless.

Very likely. It would be nice to find the on-link route that triggers that code path to ensure it doesn't cause any other issues.

But not very critical as the assert is fixed and route errors are not FATAL.

Selva

#31 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

Hi,

Quoted 7 lines · Selva Nair
Quoted 4 lines

My guts say that the issue might be related to "gateway-redirect", because only 8/8 makes sure that no logic is activated for IPv4 and without that patch there might be some IPv4 route being installed nonetheless.

Very likely. It would be nice to find the on-link route that triggers that code path to ensure it doesn't cause any other issues.

My server was on the same LAN (connecting via v4) as the client - should that be considered on-link? maybe this is what triggers that code path.

Quoted 3 lines

But not very critical as the assert is fixed and route errors are not FATAL.

If you like the argv patch v2, would you mind giving your blessing? :-)

Thanks!
Cheers,

Quoted 1 line
Signature · 1 line
Antonio Quartulli
#32 lore raw

Re: [Openvpn-devel] [PATCH v3 2/8] windows: properly configure TAP driver when no IPv4 is configured

Hi,

Quoted 5 lines · Antonio Quartulli
Quoted 2 lines

Very likely. It would be nice to find the on-link route that triggers that code path to ensure it doesn't cause any other issues.

My server was on the same LAN (connecting via v4) as the client - should that be considered on-link? maybe this is what triggers that code path.

Oh, definitely. I had the feeling it was related to "server over v4", but that would trigger "on-link" too.

Actually it might trigger the on-link ASSERT for the "ipv4 and ipv6" case as well, as soon as "redirect-gateway ipv4" is involved.

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
#33 lore raw

PATCH v4 2/8 windows: properly configure TAP driver when no IPv4 is configured

In reply to Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

This patch ensures that the TAP driver on a windows host is still configured, even though no IPv4 has been provided.

In this case the TAP driver ioctl will be invoked with a fake 0.0.0.0/0.0.0.0 IPv4 which will simply start the interface and get it to a working state.

Trac: #208

---

Changes from v2:
- rebased on top ov v4 1/8
- extended commit message
- moved did_ifconfig_setup check into test_routes()
- added longer comment into test_routes() to explain check condition

Changes from v3:
- fixed typ0 in condition in test_routes(): from 'c->c1.tuntap' to 'tt'
- tested on Win10 against ipv6-only and ipv6+ipv4 server (on same LAN)

 src/openvpn/route.c |  6 +++++-
 src/openvpn/tun.c   | 24 +++++++++++++++++-------
 2 files changed, 22 insertions(+), 8 deletions(-)
src/openvpn/route.c +5 -1
index 8990a986..f6962848 100644
@@ -2642,7 +2642,11 @@ test_routes(const struct route_list *rl, const struct tuntap *tt)
         ret = true;
         adapter_up = true;
 
-        if (rl)
+        /* we do this test only if we have IPv4 routes to install, and if
+         * the tun/tap interface has seen IPv4 ifconfig - because if we
+         * have no IPv4, the check will always fail, failing tun init
+         */
+        if (rl && tt->did_ifconfig_setup)
         {
             struct route_ipv4 *r;
             for (r = rl->routes, len = 0; r; r = r->next, ++len)
src/openvpn/tun.c +17 -7
index 2e1c96e6..f9b9c716 100644
@@ -5703,7 +5703,10 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
             msg(M_FATAL, "ERROR: --dev tun also requires --ifconfig");
         }
 
-        if (tt->topology == TOP_SUBNET)
+        /* send 0/0/0 to the TAP driver even if we have no IPv4 configured to
+         * ensure it is somehow initialized.
+         */
+        if (!tt->did_ifconfig_setup || tt->topology == TOP_SUBNET)
         {
             in_addr_t ep[3];
             BOOL status;
@@ -5716,12 +5719,19 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
                                      ep, sizeof(ep),
                                      ep, sizeof(ep), &len, NULL);
 
-            msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
-                print_in_addr_t(ep[1], IA_NET_ORDER, &gc),
-                print_in_addr_t(ep[0], IA_NET_ORDER, &gc),
-                print_in_addr_t(ep[2], IA_NET_ORDER, &gc),
-                status ? "SUCCEEDED" : "FAILED");
-
+            if (tt->did_ifconfig_setup)
+            {
+                msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
+                    print_in_addr_t(ep[1], IA_NET_ORDER, &gc),
+                    print_in_addr_t(ep[0], IA_NET_ORDER, &gc),
+                    print_in_addr_t(ep[2], IA_NET_ORDER, &gc),
+                    status ? "SUCCEEDED" : "FAILED");
+            }
+            else
+            {
+                msg(status ? M_INFO : M_FATAL, "Set TAP-Windows TUN with fake IPv4 [%s]",
+                    status ? "SUCCEEDED" : "FAILED");
+            }
         }
         else
         {
Signature · 1 line
2.17.1
Acked-by on v4 2/8
#34 lore raw

[Openvpn-devel] [PATCH applied] Re: windows: properly configure TAP driver when no IPv4 is configured

Took us a while to get here, but here we are :-) - it compiles! (And it actually *works* - tested v4+v6 and v6-only on Win7/64 - with iservice - and it does the right thing and logs useful messages)

Your patch has been applied to the master branch.

commit 125e9df9539a0d3aa7894f959ef966464754f1da

Author: Antonio Quartulli
Date:   Sun Jun 24 02:31:08 2018 +0800
     windows: properly configure TAP driver when no IPv4 is configured

     Signed-off-by: Antonio Quartulli <[email protected]...>
     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: https://www.mail-archive.com/search?l=mid&[email protected]...
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#35 lore raw

PATCH v2 3/8 pool: convert pool 'type' to enum

In reply to Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

The pool 'type' member is actually an enumered type, therefore declare it as 'enum' to improve static code analisys and readability.

---
 src/openvpn/pool.c |  2 +-
 src/openvpn/pool.h | 11 +++++++----
 2 files changed, 8 insertions(+), 5 deletions(-)
src/openvpn/pool.c +1 -1
index 26eb0ebd..5d503a33 100644
@@ -147,7 +147,7 @@ ifconfig_pool_verify_range(const int msglevel, const in_addr_t start, const in_a
 }
 
 struct ifconfig_pool *
-ifconfig_pool_init(int type, in_addr_t start, in_addr_t end,
+ifconfig_pool_init(enum pool_type type, in_addr_t start, in_addr_t end,
                    const bool duplicate_cn,
                    const bool ipv6_pool, const struct in6_addr ipv6_base,
                    const int ipv6_netbits )
src/openvpn/pool.h +7 -4
index 544d4180..73ea5599 100644
@@ -34,8 +34,11 @@
 #define IFCONFIG_POOL_MAX         65536
 #define IFCONFIG_POOL_MIN_NETBITS    16
 
-#define IFCONFIG_POOL_30NET   0
-#define IFCONFIG_POOL_INDIV   1
+enum pool_type
+{
+    IFCONFIG_POOL_30NET,
+    IFCONFIG_POOL_INDIV
+};
 
 struct ifconfig_pool_entry
 {
@@ -49,7 +52,7 @@ struct ifconfig_pool
 {
     bool duplicate_cn;
     struct {
-        int type;
+        enum pool_type type;
         in_addr_t base;
         int size;
     } ipv4;
@@ -69,7 +72,7 @@ struct ifconfig_pool_persist
 
 typedef int ifconfig_pool_handle;
 
-struct ifconfig_pool *ifconfig_pool_init(int type, in_addr_t start, in_addr_t end, const bool duplicate_cn, const bool ipv6_pool, const struct in6_addr ipv6_base, const int ipv6_netbits );
+struct ifconfig_pool *ifconfig_pool_init(enum pool_type type, in_addr_t start, in_addr_t end, const bool duplicate_cn, const bool ipv6_pool, const struct in6_addr ipv6_base, const int ipv6_netbits );
 
 void ifconfig_pool_free(struct ifconfig_pool *pool);
 
Signature · 1 line
2.17.1
Acked-by on v2 3/8
#36 lore raw

[Openvpn-devel] [PATCH applied] Re: pool: convert pool 'type' to enum

Should-be-identical code, passes all tests, well-defined types are good.

Your patch has been applied to the master branch.

commit 3e1606fe86ba1b09d05ba828b5e4e280ceddd30a

Author: Antonio Quartulli
Date:   Fri Jun 8 13:20:12 2018 +0800
     pool: convert pool 'type' to enum

     Signed-off-by: Antonio Quartulli <[email protected]...>
     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: https://www.mail-archive.com/[email protected]/msg17000.html
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#37 lore raw

PATCH v2 4/8 pool: allow to configure an IPv6-only ifconfig-pool

In reply to Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

With this change a server is allowed to allocate an IPv6-only pool. This is required to make it capable of managing an IPv6-only tunnel.

Trac: #208

---
 src/openvpn/multi.c |   7 ++-
 src/openvpn/pool.c  | 139 ++++++++++++++++++++++++++++++--------------
 src/openvpn/pool.h  |   8 ++-
 3 files changed, 107 insertions(+), 47 deletions(-)
src/openvpn/multi.c +5 -2
index 3da8c110..20f8611b 100644
@@ -397,7 +397,8 @@ multi_init(struct multi_context *m, struct context *t, bool tcp_mode, int thread
             pool_type = IFCONFIG_POOL_30NET;
         }
 
-        m->ifconfig_pool = ifconfig_pool_init(pool_type,
+        m->ifconfig_pool = ifconfig_pool_init(t->options.ifconfig_pool_defined,
+                                              pool_type,
                                               t->options.ifconfig_pool_start,
                                               t->options.ifconfig_pool_end,
                                               t->options.duplicate_cn,
@@ -1497,7 +1498,9 @@ multi_select_virtual_addr(struct multi_context *m, struct multi_instance *mi)
             const int tunnel_topology = TUNNEL_TOPOLOGY(mi->context.c1.tuntap);
 
             msg( M_INFO, "MULTI_sva: pool returned IPv4=%s, IPv6=%s",
-                 print_in_addr_t( remote, 0, &gc ),
+                 (mi->context.options.ifconfig_pool_defined
+                  ? print_in_addr_t(remote, 0, &gc)
+                  : "(Not enabled)"),
                  (mi->context.options.ifconfig_ipv6_pool_defined
                   ? print_in6_addr( remote_ipv6, 0, &gc )
                   : "(Not enabled)") );
src/openvpn/pool.c +95 -44

224 lines not on this page · raw message

src/openvpn/pool.h +7 -1
index 73ea5599..6af04645 100644
@@ -52,6 +52,7 @@ struct ifconfig_pool
 {
     bool duplicate_cn;
     struct {
+        bool enabled;
         enum pool_type type;
         in_addr_t base;
         int size;
@@ -72,7 +73,12 @@ struct ifconfig_pool_persist
 
 typedef int ifconfig_pool_handle;
 
-struct ifconfig_pool *ifconfig_pool_init(enum pool_type type, in_addr_t start, in_addr_t end, const bool duplicate_cn, const bool ipv6_pool, const struct in6_addr ipv6_base, const int ipv6_netbits );
+struct ifconfig_pool *ifconfig_pool_init(const bool ipv4_pool,
+                                         enum pool_type type, in_addr_t start,
+                                         in_addr_t end, const bool duplicate_cn,
+                                         const bool ipv6_pool,
+                                         const struct in6_addr ipv6_base,
+                                         const int ipv6_netbits);
 
 void ifconfig_pool_free(struct ifconfig_pool *pool);
 
Signature · 1 line
2.17.1
#38 lore raw

PATCH v3 4/8 pool: allow to configure an IPv6-only ifconfig-pool

From: Antonio Quartulli <[email protected]...>

With this change a server is allowed to allocate an IPv6-only pool. This is required to make it capable of managing an IPv6-only tunnel.

Trac: #208

---

Changes from v2:
- patchset rebased on top of current master
- introduce missing condition in multi.c (it was previously added with patch 5/8)

 src/openvpn/multi.c |  10 +++-
 src/openvpn/pool.c  | 139 ++++++++++++++++++++++++++++++--------------
 src/openvpn/pool.h  |   8 ++-
 3 files changed, 109 insertions(+), 48 deletions(-)
src/openvpn/multi.c +7 -3
index 3da8c110..dbc8f370 100644
@@ -388,7 +388,8 @@ multi_init(struct multi_context *m, struct context *t, bool tcp_mode, int thread
      * differently based on whether a tun or tap style
      * tunnel.
      */
-    if (t->options.ifconfig_pool_defined)
+    if (t->options.ifconfig_pool_defined
+        || t->options.ifconfig_ipv6_pool_defined)
     {
         int pool_type = IFCONFIG_POOL_INDIV;
 
@@ -397,7 +398,8 @@ multi_init(struct multi_context *m, struct context *t, bool tcp_mode, int thread
             pool_type = IFCONFIG_POOL_30NET;
         }
 
-        m->ifconfig_pool = ifconfig_pool_init(pool_type,
+        m->ifconfig_pool = ifconfig_pool_init(t->options.ifconfig_pool_defined,
+                                              pool_type,
                                               t->options.ifconfig_pool_start,
                                               t->options.ifconfig_pool_end,
                                               t->options.duplicate_cn,
@@ -1497,7 +1499,9 @@ multi_select_virtual_addr(struct multi_context *m, struct multi_instance *mi)
             const int tunnel_topology = TUNNEL_TOPOLOGY(mi->context.c1.tuntap);
 
             msg( M_INFO, "MULTI_sva: pool returned IPv4=%s, IPv6=%s",
-                 print_in_addr_t( remote, 0, &gc ),
+                 (mi->context.options.ifconfig_pool_defined
+                  ? print_in_addr_t(remote, 0, &gc)
+                  : "(Not enabled)"),
                  (mi->context.options.ifconfig_ipv6_pool_defined
                   ? print_in6_addr( remote_ipv6, 0, &gc )
                   : "(Not enabled)") );
src/openvpn/pool.c +95 -44

224 lines not on this page · raw message

src/openvpn/pool.h +7 -1
index 73ea5599..6af04645 100644
@@ -52,6 +52,7 @@ struct ifconfig_pool
 {
     bool duplicate_cn;
     struct {
+        bool enabled;
         enum pool_type type;
         in_addr_t base;
         int size;
@@ -72,7 +73,12 @@ struct ifconfig_pool_persist
 
 typedef int ifconfig_pool_handle;
 
-struct ifconfig_pool *ifconfig_pool_init(enum pool_type type, in_addr_t start, in_addr_t end, const bool duplicate_cn, const bool ipv6_pool, const struct in6_addr ipv6_base, const int ipv6_netbits );
+struct ifconfig_pool *ifconfig_pool_init(const bool ipv4_pool,
+                                         enum pool_type type, in_addr_t start,
+                                         in_addr_t end, const bool duplicate_cn,
+                                         const bool ipv6_pool,
+                                         const struct in6_addr ipv6_base,
+                                         const int ipv6_netbits);
 
 void ifconfig_pool_free(struct ifconfig_pool *pool);
 
Signature · 1 line
2.17.1
#39 lore raw

Re: [Openvpn-devel] [PATCH v3 4/8] pool: allow to configure an IPv6-only ifconfig-pool

Hi,

Quoted 5 lines · Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

With this change a server is allowed to allocate an IPv6-only pool. This is required to make it capable of managing an IPv6-only tunnel.

After discussing with Gert, I'd say that maybe this last sentence can be removed because "an ipv6-only tunnel" is already possible on a server (just without a pool).

Quoted 3 lines

Trac: #208

This single patch has been applied on top of master and thrown at buildbot. No failure has been recorded.

Cheers,

Signature · 1 line
Antonio Quartulli
#40 lore raw

PATCH v2 5/8 make server capable of starting with an IPv6-only tunnel

In reply to Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

Due to the current logic it is not possible for a server to create an IPv6-only tunnel, because OpenVPN mandates the existance of an IPv4 configuration (even if fake).

This change relaxes this constraint and allows servers to bring up tunnels without any IPv4 setting at all.

For the user this means that a server can be configured with just the "--server-ipv6" directive and no "--server" at all.

Trac: #208

---
 src/openvpn/helper.c | 8 ++++++--
 src/openvpn/multi.c  | 3 ++-
 2 files changed, 8 insertions(+), 3 deletions(-)
src/openvpn/helper.c +6 -2
index ff9df506..42ba5b2c 100644
@@ -177,10 +177,11 @@ helper_client_server(struct options *o)
      */
     if (o->server_ipv6_defined)
     {
-        if (!o->server_defined)
+        if (o->client)
         {
-            msg(M_USAGE, "--server-ipv6 must be used together with --server");
+            msg(M_USAGE, "--server and --client cannot be used together");
         }
+
         if (o->server_flags & SF_NOPOOL)
         {
             msg( M_USAGE, "--server-ipv6 is incompatible with 'nopool' option" );
@@ -190,6 +191,9 @@ helper_client_server(struct options *o)
             msg( M_USAGE, "--server-ipv6 already defines an ifconfig-ipv6-pool, so you can't also specify --ifconfig-pool explicitly");
         }
 
+        o->mode = MODE_SERVER;
+        o->tls_server = true;
+
         /* local ifconfig is "base address + 1" and "+2" */
         o->ifconfig_ipv6_local =
             print_in6_addr( add_in6_addr( o->server_network_ipv6, 1), 0, &o->gc );
src/openvpn/multi.c +2 -1
index 20f8611b..dbc8f370 100644
@@ -388,7 +388,8 @@ multi_init(struct multi_context *m, struct context *t, bool tcp_mode, int thread
      * differently based on whether a tun or tap style
      * tunnel.
      */
-    if (t->options.ifconfig_pool_defined)
+    if (t->options.ifconfig_pool_defined
+        || t->options.ifconfig_ipv6_pool_defined)
     {
         int pool_type = IFCONFIG_POOL_INDIV;
 
Signature · 1 line
2.17.1
#41 lore raw

PATCH v3 5/8 allow usage of --server-ipv6 even when no --server is specified

From: Antonio Quartulli <[email protected]...>

Until now OpenVPN has not allowed to specify --server-ipv6 if no --server was also set. This constraint comes from the fact that most of the IPv6 logic (i.e. ifconfig-pool handling) relied on IPv4 components to be activated and configured as well.

Now that the IPv6 code path has been made independent from IPv4, it is finally possible to to relax the constraint mentioned above and make it possible for the user to have a configurations with --server-ipv6 only.

Trac: #208

---

Changes from v2:
- patchset rebased on top of pre-ipv6-only patchset
- change commit subject/message
- move ifconfig-ipv6-pool check change into 4/8

 src/openvpn/helper.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
src/openvpn/helper.c +6 -2
index ff9df506..42ba5b2c 100644
@@ -177,10 +177,11 @@ helper_client_server(struct options *o)
      */
     if (o->server_ipv6_defined)
     {
-        if (!o->server_defined)
+        if (o->client)
         {
-            msg(M_USAGE, "--server-ipv6 must be used together with --server");
+            msg(M_USAGE, "--server and --client cannot be used together");
         }
+
         if (o->server_flags & SF_NOPOOL)
         {
             msg( M_USAGE, "--server-ipv6 is incompatible with 'nopool' option" );
@@ -190,6 +191,9 @@ helper_client_server(struct options *o)
             msg( M_USAGE, "--server-ipv6 already defines an ifconfig-ipv6-pool, so you can't also specify --ifconfig-pool explicitly");
         }
 
+        o->mode = MODE_SERVER;
+        o->tls_server = true;
+
         /* local ifconfig is "base address + 1" and "+2" */
         o->ifconfig_ipv6_local =
             print_in6_addr( add_in6_addr( o->server_network_ipv6, 1), 0, &o->gc );
Signature · 1 line
2.17.1
#42 lore raw

PATCH v2 6/8 pool: add support for ifconfig-pool-persist with IPv6 only

In reply to Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

Without altering the pool logic, this patch enables using a persistent IP pool also when the server is configured with IPv6 only.

---
 src/openvpn/options.c |   7 ++-
 src/openvpn/pool.c    | 136 ++++++++++++++++++++++++++++++++----------
 2 files changed, 110 insertions(+), 33 deletions(-)
src/openvpn/options.c +5 -2
index 426057ab..4d9e4a3f 100644
@@ -2349,9 +2349,12 @@ options_postprocess_verify_ce(const struct options *options, const struct connec
         {
             msg(M_USAGE, "--up-delay cannot be used with --mode server");
         }
-        if (!options->ifconfig_pool_defined && options->ifconfig_pool_persist_filename)
+        if (!options->ifconfig_pool_defined
+            && !options->ifconfig_ipv6_pool_defined
+            && options->ifconfig_pool_persist_filename)
         {
-            msg(M_USAGE, "--ifconfig-pool-persist must be used with --ifconfig-pool");
+            msg(M_USAGE,
+                "--ifconfig-pool-persist must be used with --ifconfig-pool or --ifconfig-ipv6-pool");
         }
         if (options->ifconfig_ipv6_pool_defined && !options->ifconfig_ipv6_local)
         {
src/openvpn/pool.c +105 -31

204 lines not on this page · raw message

Signature · 1 line
2.17.1
#43 lore raw

PATCH v2 7/8 route: warn on IPv4 routes installation when no IPv4 is configured

In reply to Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

---
 src/openvpn/route.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
src/openvpn/route.c +9 -1
index 8990a986..64fd08c0 100644
@@ -981,7 +981,7 @@ del_bypass_routes(struct route_bypass *rb,
 static void
 redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
 {
-    const char err[] = "NOTE: unable to redirect default gateway --";
+    const char err[] = "NOTE: unable to redirect IPv4 default gateway --";
 
     if (rl && rl->flags & RG_ENABLE)
     {
@@ -1171,6 +1171,14 @@ add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tunt
     {
         struct route_ipv4 *r;
 
+        if (rl->routes && !tt->did_ifconfig_setup)
+        {
+            msg(M_INFO, "WARNING: OpenVPN was configured to add an IPv4 "
+                "route over %s. However, no IPv4 has been configured for "
+                "this interface, therefore the route installation may "
+                "fail or may not work as expected.", tt->actual_name);
+        }
+
 #ifdef ENABLE_MANAGEMENT
         if (management && rl->routes)
         {
Signature · 1 line
2.17.1
#44 lore raw

PATCH v2 8/8 options: enable IPv4 redirection logic only if really required

In reply to Antonio Quartulli

From: Antonio Quartulli <[email protected]...>

If no IPv4 redirection flag is set, do not enable the IPv4 redireciton logic at all so that it won't bother adding any useless IPv4 route.

At the same the warning message (for both IPv4 and IPv6) have been modified by removing the tunnel interface name, as routes being added might actually be going over other interfaces.

---
 src/openvpn/options.c | 9 ++++++++-
 src/openvpn/route.c   | 8 ++++----
 2 files changed, 12 insertions(+), 5 deletions(-)
src/openvpn/options.c +8 -1
index 4d9e4a3f..90dee4f2 100644
@@ -6337,7 +6337,14 @@ add_option(struct options *options,
         /* we need this here to handle pushed --redirect-gateway */
         remap_redirect_gateway_flags(options);
 #endif
-        options->routes->flags |= RG_ENABLE;
+        /* enable IPv4 redirection logic only if at least one IPv4 flag is set.
+         * For instance, when "redirect-gateway !ipv4 ipv6" is specified no
+         * IPv4 redirection should be activated.
+         */
+        if (options->routes->flags)
+        {
+            options->routes->flags |= RG_ENABLE;
+        }
     }
     else if (streq(p[0], "remote-random-hostname") && !p[1])
     {
src/openvpn/route.c +4 -4
index 64fd08c0..a9c2934f 100644
@@ -1174,9 +1174,9 @@ add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tunt
         if (rl->routes && !tt->did_ifconfig_setup)
         {
             msg(M_INFO, "WARNING: OpenVPN was configured to add an IPv4 "
-                "route over %s. However, no IPv4 has been configured for "
+                "route. However, no IPv4 has been configured for "
                 "this interface, therefore the route installation may "
-                "fail or may not work as expected.", tt->actual_name);
+                "fail or may not work as expected.");
         }
 
 #ifdef ENABLE_MANAGEMENT
@@ -1210,9 +1210,9 @@ add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tunt
         if (!tt->did_ifconfig_ipv6_setup)
         {
             msg(M_INFO, "WARNING: OpenVPN was configured to add an IPv6 "
-                "route over %s. However, no IPv6 has been configured for "
+                "route. However, no IPv6 has been configured for "
                 "this interface, therefore the route installation may "
-                "fail or may not work as expected.", tt->actual_name);
+                "fail or may not work as expected.");
         }
 
         for (r = rl6->routes_ipv6; r; r = r->next)
Signature · 1 line
2.17.1