Browse code

tun: ensure interface can be configured with IPv6 only

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
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>

Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20180618074733.19773-1-a@unstable.cc>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg17064.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Antonio Quartulli authored on 2018/06/18 16:47:33
Showing 2 changed files
... ...
@@ -871,714 +871,562 @@ create_arbitrary_remote( struct tuntap *tt )
871 871
 }
872 872
 #endif
873 873
 
874
-/* execute the ifconfig command through the shell */
875
-void
876
-do_ifconfig(struct tuntap *tt,
877
-            const char *actual,     /* actual device name */
878
-            int tun_mtu,
879
-            const struct env_set *es)
874
+/**
875
+ * do_ifconfig_ipv6 - perform platform specific ifconfig6 commands
876
+ *
877
+ * @param tt        the tuntap interface context
878
+ * @param ifname    the human readable interface name
879
+ * @param mtu       the MTU value to set the interface to
880
+ * @param es        the environment to be used when executing the commands
881
+ */
882
+static void
883
+do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
884
+                 const struct env_set *es)
880 885
 {
886
+    const char *ifconfig_ipv6_local = NULL;
887
+    struct argv argv = argv_new();
881 888
     struct gc_arena gc = gc_new();
882 889
 
883
-    if (tt->did_ifconfig_setup)
884
-    {
885
-        bool tun = false;
886
-        const char *ifconfig_local = NULL;
887
-        const char *ifconfig_remote_netmask = NULL;
888
-        const char *ifconfig_broadcast = NULL;
889
-        const char *ifconfig_ipv6_local = NULL;
890
-        bool do_ipv6 = false;
891
-        struct argv argv = argv_new();
890
+    ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
892 891
 
893
-        msg( D_LOW, "do_ifconfig, tt->did_ifconfig_ipv6_setup=%d",
894
-             tt->did_ifconfig_ipv6_setup );
892
+#if defined(TARGET_LINUX)
893
+#ifdef ENABLE_IPROUTE
894
+    /* set the MTU for the device and bring it up */
895
+    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
896
+                tun_mtu);
897
+    argv_msg(M_INFO, &argv);
898
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
895 899
 
896
-        /*
897
-         * We only handle TUN/TAP devices here, not --dev null devices.
898
-         */
899
-        tun = is_tun_p2p(tt);
900
+    argv_printf(&argv, "%s -6 addr add %s/%d dev %s", iproute_path,
901
+                ifconfig_ipv6_local, tt->netbits_ipv6, ifname);
902
+    argv_msg(M_INFO, &argv);
903
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip -6 addr add failed");
904
+#else
905
+    argv_printf(&argv, "%s %s add %s/%d mtu %d up", IFCONFIG_PATH, ifname,
906
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
907
+    argv_msg(M_INFO, &argv);
908
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
909
+#endif
910
+#elif defined(TARGET_ANDROID)
911
+    char out6[64];
900 912
 
901
-        /*
902
-         * Set ifconfig parameters
903
-         */
904
-        ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
905
-        ifconfig_remote_netmask = print_in_addr_t(tt->remote_netmask, 0, &gc);
913
+    openvpn_snprintf(out6, sizeof(out6), "%s/%d",
914
+                     ifconfig_ipv6_local,tt->netbits_ipv6);
915
+    management_android_control(management, "IFCONFIG6", out6);
916
+#elif defined(TARGET_SOLARIS)
917
+    argv_printf(&argv, "%s %s inet6 unplumb", IFCONFIG_PATH, ifname);
918
+    argv_msg(M_INFO, &argv);
919
+    openvpn_execve_check(&argv, es, 0, NULL);
906 920
 
907
-        if (tt->did_ifconfig_ipv6_setup)
921
+    if (tt->type == DEV_TYPE_TUN)
922
+    {
923
+        const char *ifconfig_ipv6_remote = print_in6_addr(tt->remote_ipv6, 0, &gc);
924
+
925
+        argv_printf(&argv, "%s %s inet6 plumb %s/%d %s mtu %d up",
926
+                    IFCONFIG_PATH, ifname, ifconfig_ipv6_local,
927
+                    tt->netbits_ipv6, ifconfig_ipv6_remote, tun_mtu);
928
+    }
929
+    else /* tap mode */
930
+    {
931
+        /* base IPv6 tap interface needs to be brought up first */
932
+        argv_printf(&argv, "%s %s inet6 plumb up", IFCONFIG_PATH, ifname);
933
+        argv_msg(M_INFO, &argv);
934
+
935
+        if (!openvpn_execve_check(&argv, es, 0,
936
+                                  "Solaris ifconfig IPv6 (prepare) failed"))
908 937
         {
909
-            ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
910
-            do_ipv6 = true;
938
+            solaris_error_close(tt, es, ifname, true);
911 939
         }
912 940
 
913
-        /*
914
-         * If TAP-style device, generate broadcast address.
941
+        /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
942
+         * after the system has noticed the interface and fired up
943
+         * the DHCPv6 client - but this takes quite a while, and the
944
+         * server will ignore the DHCPv6 packets anyway.  So we don't.
915 945
          */
916
-        if (!tun)
917
-        {
918
-            ifconfig_broadcast = print_in_addr_t(tt->broadcast, 0, &gc);
919
-        }
920 946
 
921
-#ifdef ENABLE_MANAGEMENT
922
-        if (management)
923
-        {
924
-            management_set_state(management,
925
-                                 OPENVPN_STATE_ASSIGN_IP,
926
-                                 NULL,
927
-                                 &tt->local,
928
-                                 &tt->local_ipv6,
929
-                                 NULL,
930
-                                 NULL);
931
-        }
947
+        /* static IPv6 addresses need to go to a subinterface (tap0:1) */
948
+        argv_printf(&argv, "%s %s inet6 addif %s/%d mtu %d up", IFCONFIG_PATH,
949
+                    ifname, ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
950
+    }
951
+    argv_msg(M_INFO, &argv);
952
+
953
+    if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 failed"))
954
+    {
955
+        solaris_error_close(tt, es, ifname, true);
956
+    }
957
+#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
958
+    || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
959
+    || defined(TARGET_DRAGONFLY)
960
+    argv_printf(&argv, "%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
961
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
962
+    argv_msg(M_INFO, &argv);
963
+
964
+    openvpn_execve_check(&argv, es, S_FATAL,
965
+                         "generic BSD ifconfig inet6 failed");
966
+
967
+#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
968
+    || defined(TARGET_DARWIN)
969
+    /* and, hooray, we explicitely need to add a route... */
970
+    add_route_connected_v6_net(tt, es);
932 971
 #endif
972
+#elif defined(TARGET_AIX)
973
+    argv_printf(&argv, "%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
974
+                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
975
+    argv_msg(M_INFO, &argv);
933 976
 
977
+    /* AIX ifconfig will complain if it can't find ODM path in env */
978
+    es = env_set_create(NULL);
979
+    env_set_add(es, "ODMDIR=/etc/objrepos");
934 980
 
935
-#if defined(TARGET_LINUX)
936
-#ifdef ENABLE_IPROUTE
937
-        /*
938
-         * Set the MTU for the device
939
-         */
940
-        argv_printf(&argv,
941
-                    "%s link set dev %s up mtu %d",
942
-                    iproute_path,
943
-                    actual,
944
-                    tun_mtu
945
-                    );
946
-        argv_msg(M_INFO, &argv);
947
-        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
981
+    openvpn_execve_check(&argv, es, S_FATAL,
982
+                         "generic BSD ifconfig inet6 failed");
948 983
 
949
-        if (tun)
950
-        {
984
+    env_set_destroy(es);
985
+#elif defined (_WIN32)
986
+    if (tt->options.ip_win32_type == IPW32_SET_MANUAL)
987
+    {
988
+        msg(M_INFO, "******** NOTE:  Please manually set the v6 IP of '%s' to %s (if it is not already set)",
989
+            ifname, ifconfig_ipv6_local);
990
+    }
991
+    else if (tt->options.msg_channel)
992
+    {
993
+        do_address_service(true, AF_INET6, tt);
994
+        do_dns6_service(true, tt);
995
+    }
996
+    else
997
+    {
998
+        /* example: netsh interface ipv6 set address interface=42
999
+         *                  2001:608:8003::d store=active
1000
+         */
1001
+        char iface[64];
951 1002
 
952
-            /*
953
-             * Set the address for the device
954
-             */
955
-            argv_printf(&argv,
956
-                        "%s addr add dev %s local %s peer %s",
957
-                        iproute_path,
958
-                        actual,
959
-                        ifconfig_local,
960
-                        ifconfig_remote_netmask
961
-                        );
962
-            argv_msg(M_INFO, &argv);
963
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
964
-        }
965
-        else
966
-        {
967
-            argv_printf(&argv,
968
-                        "%s addr add dev %s %s/%d broadcast %s",
969
-                        iproute_path,
970
-                        actual,
971
-                        ifconfig_local,
972
-                        netmask_to_netbits2(tt->remote_netmask),
973
-                        ifconfig_broadcast
974
-                        );
975
-            argv_msg(M_INFO, &argv);
976
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
977
-        }
978
-        if (do_ipv6)
979
-        {
980
-            argv_printf( &argv,
981
-                         "%s -6 addr add %s/%d dev %s",
982
-                         iproute_path,
983
-                         ifconfig_ipv6_local,
984
-                         tt->netbits_ipv6,
985
-                         actual
986
-                         );
987
-            argv_msg(M_INFO, &argv);
988
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ip -6 addr add failed");
989
-        }
990
-#else  /* ifdef ENABLE_IPROUTE */
991
-        if (tun)
992
-        {
993
-            argv_printf(&argv,
994
-                        "%s %s %s pointopoint %s mtu %d",
995
-                        IFCONFIG_PATH,
996
-                        actual,
997
-                        ifconfig_local,
998
-                        ifconfig_remote_netmask,
999
-                        tun_mtu
1000
-                        );
1001
-        }
1002
-        else
1003
-        {
1004
-            argv_printf(&argv,
1005
-                        "%s %s %s netmask %s mtu %d broadcast %s",
1006
-                        IFCONFIG_PATH,
1007
-                        actual,
1008
-                        ifconfig_local,
1009
-                        ifconfig_remote_netmask,
1010
-                        tun_mtu,
1011
-                        ifconfig_broadcast
1012
-                        );
1013
-        }
1014
-        argv_msg(M_INFO, &argv);
1015
-        openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig failed");
1016
-        if (do_ipv6)
1017
-        {
1018
-            argv_printf(&argv,
1019
-                        "%s %s add %s/%d",
1020
-                        IFCONFIG_PATH,
1021
-                        actual,
1022
-                        ifconfig_ipv6_local,
1023
-                        tt->netbits_ipv6
1024
-                        );
1025
-            argv_msg(M_INFO, &argv);
1026
-            openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
1027
-        }
1003
+        openvpn_snprintf(iface, sizeof(iface), "interface=%lu",
1004
+                         tt->adapter_index);
1005
+        argv_printf(&argv, "%s%sc interface ipv6 set address %s %s store=active",
1006
+                    get_win_sys_path(), NETSH_PATH_SUFFIX, iface,
1007
+                    ifconfig_ipv6_local);
1008
+        netsh_command(&argv, 4, M_FATAL);
1009
+        /* set ipv6 dns servers if any are specified */
1010
+        netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, ifname);
1011
+    }
1028 1012
 
1029
-#endif /*ENABLE_IPROUTE*/
1030
-#elif defined(TARGET_ANDROID)
1013
+    /* explicit route needed */
1014
+    if (tt->options.ip_win32_type != IPW32_SET_MANUAL)
1015
+    {
1016
+        add_route_connected_v6_net(tt, es);
1017
+    }
1018
+#else /* platforms we have no IPv6 code for */
1019
+    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.");
1020
+#endif /* outer "if defined(TARGET_xxx)" conditional */
1031 1021
 
1032
-        if (do_ipv6)
1033
-        {
1034
-            char out6[64];
1035
-            openvpn_snprintf(out6, sizeof(out6), "%s/%d", ifconfig_ipv6_local,tt->netbits_ipv6);
1036
-            management_android_control(management, "IFCONFIG6", out6);
1037
-        }
1022
+    gc_free(&gc);
1023
+    argv_reset(&argv);
1024
+}
1038 1025
 
1039
-        char out[64];
1026
+/**
1027
+ * do_ifconfig_ipv4 - perform platform specific ifconfig commands
1028
+ *
1029
+ * @param tt        the tuntap interface context
1030
+ * @param ifname    the human readable interface name
1031
+ * @param mtu       the MTU value to set the interface to
1032
+ * @param es        the environment to be used when executing the commands
1033
+ */
1034
+static void
1035
+do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
1036
+                 const struct env_set *es)
1037
+{
1038
+    bool tun = false;
1039
+    const char *ifconfig_local = NULL;
1040
+    const char *ifconfig_remote_netmask = NULL;
1041
+    const char *ifconfig_broadcast = NULL;
1042
+    struct argv argv = argv_new();
1043
+    struct gc_arena gc = gc_new();
1040 1044
 
1041
-        char *top;
1042
-        switch (tt->topology)
1043
-        {
1044
-            case TOP_NET30:
1045
-                top = "net30";
1046
-                break;
1045
+    /*
1046
+     * We only handle TUN/TAP devices here, not --dev null devices.
1047
+     */
1048
+    tun = is_tun_p2p(tt);
1047 1049
 
1048
-            case TOP_P2P:
1049
-                top = "p2p";
1050
-                break;
1050
+    /*
1051
+     * Set ifconfig parameters
1052
+     */
1053
+    ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
1054
+    ifconfig_remote_netmask = print_in_addr_t(tt->remote_netmask, 0, &gc);
1051 1055
 
1052
-            case TOP_SUBNET:
1053
-                top = "subnet";
1054
-                break;
1056
+    /*
1057
+     * If TAP-style device, generate broadcast address.
1058
+     */
1059
+    if (!tun)
1060
+    {
1061
+        ifconfig_broadcast = print_in_addr_t(tt->broadcast, 0, &gc);
1062
+    }
1055 1063
 
1056
-            default:
1057
-                top = "undef";
1058
-        }
1064
+#if defined(TARGET_LINUX)
1065
+#ifdef ENABLE_IPROUTE
1066
+    /*
1067
+     * Set the MTU for the device
1068
+     */
1069
+    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
1070
+                tun_mtu);
1071
+    argv_msg(M_INFO, &argv);
1072
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
1059 1073
 
1060
-        openvpn_snprintf(out, sizeof(out), "%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu, top);
1061
-        management_android_control(management, "IFCONFIG", out);
1074
+    if (tun)
1075
+    {
1062 1076
 
1063
-#elif defined(TARGET_SOLARIS)
1064
-        /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
1065
-         * example:
1066
-         *    ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
1067
-         *    ifconfig tun2 netmask 255.255.255.255
1077
+        /*
1078
+         * Set the address for the device
1068 1079
          */
1069
-        if (tun)
1070
-        {
1071
-            argv_printf(&argv,
1072
-                        "%s %s %s %s mtu %d up",
1073
-                        IFCONFIG_PATH,
1074
-                        actual,
1075
-                        ifconfig_local,
1076
-                        ifconfig_remote_netmask,
1077
-                        tun_mtu
1078
-                        );
1079
-
1080
-            argv_msg(M_INFO, &argv);
1081
-            if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-1 failed"))
1082
-            {
1083
-                solaris_error_close(tt, es, actual, false);
1084
-            }
1080
+        argv_printf(&argv, "%s addr add dev %s local %s peer %s", iproute_path,
1081
+                    ifname, ifconfig_local, ifconfig_remote_netmask);
1082
+        argv_msg(M_INFO, &argv);
1083
+        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
1084
+    }
1085
+    else
1086
+    {
1087
+        argv_printf(&argv, "%s addr add dev %s %s/%d broadcast %s",
1088
+                    iproute_path, ifname, ifconfig_local,
1089
+                    netmask_to_netbits2(tt->remote_netmask),
1090
+                    ifconfig_broadcast);
1091
+        argv_msg(M_INFO, &argv);
1092
+        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
1093
+    }
1094
+#else  /* ifdef ENABLE_IPROUTE */
1095
+    if (tun)
1096
+    {
1097
+        argv_printf(&argv, "%s %s %s pointopoint %s mtu %d", IFCONFIG_PATH,
1098
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1099
+    }
1100
+    else
1101
+    {
1102
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s",
1103
+                    IFCONFIG_PATH, ifname, ifconfig_local,
1104
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
1105
+    }
1106
+    argv_msg(M_INFO, &argv);
1107
+    openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig failed");
1085 1108
 
1086
-            argv_printf(&argv,
1087
-                        "%s %s netmask 255.255.255.255",
1088
-                        IFCONFIG_PATH,
1089
-                        actual
1090
-                        );
1091
-        }
1092
-        else if (tt->topology == TOP_SUBNET)
1093
-        {
1094
-            argv_printf(&argv,
1095
-                        "%s %s %s %s netmask %s mtu %d up",
1096
-                        IFCONFIG_PATH,
1097
-                        actual,
1098
-                        ifconfig_local,
1099
-                        ifconfig_local,
1100
-                        ifconfig_remote_netmask,
1101
-                        tun_mtu
1102
-                        );
1103
-        }
1104
-        else
1105
-        {
1106
-            argv_printf(&argv,
1107
-                        " %s %s %s netmask %s broadcast + up",
1108
-                        IFCONFIG_PATH,
1109
-                        actual,
1110
-                        ifconfig_local,
1111
-                        ifconfig_remote_netmask
1112
-                        );
1113
-        }
1109
+#endif /*ENABLE_IPROUTE*/
1110
+#elif defined(TARGET_ANDROID)
1111
+    char out[64];
1114 1112
 
1115
-        argv_msg(M_INFO, &argv);
1116
-        if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-2 failed"))
1117
-        {
1118
-            solaris_error_close(tt, es, actual, false);
1119
-        }
1113
+    char *top;
1114
+    switch (tt->topology)
1115
+    {
1116
+        case TOP_NET30:
1117
+            top = "net30";
1118
+            break;
1120 1119
 
1121
-        if (do_ipv6)
1122
-        {
1123
-            argv_printf(&argv, "%s %s inet6 unplumb",
1124
-                        IFCONFIG_PATH, actual );
1125
-            argv_msg(M_INFO, &argv);
1126
-            openvpn_execve_check(&argv, es, 0, NULL);
1120
+        case TOP_P2P:
1121
+            top = "p2p";
1122
+            break;
1127 1123
 
1128
-            if (tt->type == DEV_TYPE_TUN)
1129
-            {
1130
-                const char *ifconfig_ipv6_remote =
1131
-                    print_in6_addr(tt->remote_ipv6, 0, &gc);
1124
+        case TOP_SUBNET:
1125
+            top = "subnet";
1126
+            break;
1132 1127
 
1133
-                argv_printf(&argv,
1134
-                            "%s %s inet6 plumb %s/%d %s up",
1135
-                            IFCONFIG_PATH,
1136
-                            actual,
1137
-                            ifconfig_ipv6_local,
1138
-                            tt->netbits_ipv6,
1139
-                            ifconfig_ipv6_remote
1140
-                            );
1141
-            }
1142
-            else                                        /* tap mode */
1143
-            {
1144
-                /* base IPv6 tap interface needs to be brought up first
1145
-                 */
1146
-                argv_printf(&argv, "%s %s inet6 plumb up",
1147
-                            IFCONFIG_PATH, actual );
1148
-                argv_msg(M_INFO, &argv);
1149
-                if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 (prepare) failed"))
1150
-                {
1151
-                    solaris_error_close(tt, es, actual, true);
1152
-                }
1128
+        default:
1129
+            top = "undef";
1130
+    }
1153 1131
 
1154
-                /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
1155
-                 * after the system has noticed the interface and fired up
1156
-                 * the DHCPv6 client - but this takes quite a while, and the
1157
-                 * server will ignore the DHCPv6 packets anyway.  So we don't.
1158
-                 */
1132
+    openvpn_snprintf(out, sizeof(out), "%s %s %d %s", ifconfig_local,
1133
+                     ifconfig_remote_netmask, tun_mtu, top);
1134
+    management_android_control(management, "IFCONFIG", out);
1159 1135
 
1160
-                /* static IPv6 addresses need to go to a subinterface (tap0:1)
1161
-                 */
1162
-                argv_printf(&argv,
1163
-                            "%s %s inet6 addif %s/%d up",
1164
-                            IFCONFIG_PATH, actual,
1165
-                            ifconfig_ipv6_local, tt->netbits_ipv6 );
1166
-            }
1167
-            argv_msg(M_INFO, &argv);
1168
-            if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig IPv6 failed"))
1169
-            {
1170
-                solaris_error_close(tt, es, actual, true);
1171
-            }
1172
-        }
1136
+#elif defined(TARGET_SOLARIS)
1137
+    /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
1138
+     * example:
1139
+     *    ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
1140
+     *    ifconfig tun2 netmask 255.255.255.255
1141
+     */
1142
+    if (tun)
1143
+    {
1144
+        argv_printf(&argv, "%s %s %s %s mtu %d up", IFCONFIG_PATH, ifname,
1145
+                    ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1173 1146
 
1174
-        if (!tun && tt->topology == TOP_SUBNET)
1147
+        argv_msg(M_INFO, &argv);
1148
+        if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-1 failed"))
1175 1149
         {
1176
-            /* Add a network route for the local tun interface */
1177
-            struct route_ipv4 r;
1178
-            CLEAR(r);
1179
-            r.flags = RT_DEFINED | RT_METRIC_DEFINED;
1180
-            r.network = tt->local & tt->remote_netmask;
1181
-            r.netmask = tt->remote_netmask;
1182
-            r.gateway = tt->local;
1183
-            r.metric = 0;
1184
-            add_route(&r, tt, 0, NULL, es);
1150
+            solaris_error_close(tt, es, ifname, false);
1185 1151
         }
1186 1152
 
1187
-#elif defined(TARGET_OPENBSD)
1188
-
1189
-        in_addr_t remote_end;           /* for "virtual" subnet topology */
1190
-
1191
-        /*
1192
-         * On OpenBSD, tun interfaces are persistent if created with
1193
-         * "ifconfig tunX create", and auto-destroyed if created by
1194
-         * opening "/dev/tunX" (so we just use the /dev/tunX)
1195
-         */
1153
+        argv_printf(&argv, "%s %s netmask 255.255.255.255", IFCONFIG_PATH,
1154
+                    ifname);
1155
+    }
1156
+    else if (tt->topology == TOP_SUBNET)
1157
+    {
1158
+        argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
1159
+                    ifname, ifconfig_local, ifconfig_local,
1160
+                    ifconfig_remote_netmask, tun_mtu);
1161
+    }
1162
+    else
1163
+    {
1164
+        argv_printf(&argv, "%s %s %s netmask %s broadcast + up",
1165
+                    IFCONFIG_PATH, ifname, ifconfig_local,
1166
+                    ifconfig_remote_netmask);
1167
+    }
1196 1168
 
1197
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1198
-        if (tun)
1199
-        {
1200
-            argv_printf(&argv,
1201
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
1202
-                        IFCONFIG_PATH,
1203
-                        actual,
1204
-                        ifconfig_local,
1205
-                        ifconfig_remote_netmask,
1206
-                        tun_mtu
1207
-                        );
1208
-        }
1209
-        else if (tt->topology == TOP_SUBNET)
1210
-        {
1211
-            remote_end = create_arbitrary_remote( tt );
1212
-            argv_printf(&argv,
1213
-                        "%s %s %s %s mtu %d netmask %s up -link0",
1214
-                        IFCONFIG_PATH,
1215
-                        actual,
1216
-                        ifconfig_local,
1217
-                        print_in_addr_t(remote_end, 0, &gc),
1218
-                        tun_mtu,
1219
-                        ifconfig_remote_netmask
1220
-                        );
1221
-        }
1222
-        else
1223
-        {
1224
-            argv_printf(&argv,
1225
-                        "%s %s %s netmask %s mtu %d broadcast %s link0",
1226
-                        IFCONFIG_PATH,
1227
-                        actual,
1228
-                        ifconfig_local,
1229
-                        ifconfig_remote_netmask,
1230
-                        tun_mtu,
1231
-                        ifconfig_broadcast
1232
-                        );
1233
-        }
1234
-        argv_msg(M_INFO, &argv);
1235
-        openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed");
1169
+    argv_msg(M_INFO, &argv);
1170
+    if (!openvpn_execve_check(&argv, es, 0, "Solaris ifconfig phase-2 failed"))
1171
+    {
1172
+        solaris_error_close(tt, es, ifname, false);
1173
+    }
1236 1174
 
1175
+    if (!tun && tt->topology == TOP_SUBNET)
1176
+    {
1237 1177
         /* Add a network route for the local tun interface */
1238
-        if (!tun && tt->topology == TOP_SUBNET)
1239
-        {
1240
-            struct route_ipv4 r;
1241
-            CLEAR(r);
1242
-            r.flags = RT_DEFINED;
1243
-            r.network = tt->local & tt->remote_netmask;
1244
-            r.netmask = tt->remote_netmask;
1245
-            r.gateway = remote_end;
1246
-            add_route(&r, tt, 0, NULL, es);
1247
-        }
1178
+        struct route_ipv4 r;
1179
+        CLEAR(r);
1180
+        r.flags = RT_DEFINED | RT_METRIC_DEFINED;
1181
+        r.network = tt->local & tt->remote_netmask;
1182
+        r.netmask = tt->remote_netmask;
1183
+        r.gateway = tt->local;
1184
+        r.metric = 0;
1185
+        add_route(&r, tt, 0, NULL, es);
1186
+    }
1248 1187
 
1249
-        if (do_ipv6)
1250
-        {
1251
-            argv_printf(&argv,
1252
-                        "%s %s inet6 %s/%d",
1253
-                        IFCONFIG_PATH,
1254
-                        actual,
1255
-                        ifconfig_ipv6_local,
1256
-                        tt->netbits_ipv6
1257
-                        );
1258
-            argv_msg(M_INFO, &argv);
1259
-            openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig inet6 failed");
1188
+#elif defined(TARGET_OPENBSD)
1260 1189
 
1261
-            /* and, hooray, we explicitely need to add a route... */
1262
-            add_route_connected_v6_net(tt, es);
1263
-        }
1190
+    in_addr_t remote_end;           /* for "virtual" subnet topology */
1264 1191
 
1265
-#elif defined(TARGET_NETBSD)
1192
+    /*
1193
+     * On OpenBSD, tun interfaces are persistent if created with
1194
+     * "ifconfig tunX create", and auto-destroyed if created by
1195
+     * opening "/dev/tunX" (so we just use the /dev/tunX)
1196
+     */
1266 1197
 
1267
-        if (tun)
1268
-        {
1269
-            argv_printf(&argv,
1270
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1271
-                        IFCONFIG_PATH,
1272
-                        actual,
1273
-                        ifconfig_local,
1274
-                        ifconfig_remote_netmask,
1275
-                        tun_mtu
1276
-                        );
1277
-        }
1278
-        else if (tt->topology == TOP_SUBNET)
1279
-        {
1280
-            argv_printf(&argv,
1281
-                        "%s %s %s %s mtu %d netmask %s up",
1282
-                        IFCONFIG_PATH,
1283
-                        actual,
1284
-                        ifconfig_local,
1285
-                        ifconfig_local,
1286
-                        tun_mtu,
1287
-                        ifconfig_remote_netmask
1288
-                        );
1289
-        }
1290
-        else
1291
-        {
1292
-            /*
1293
-             * NetBSD has distinct tun and tap devices
1294
-             * so we don't need the "link0" extra parameter to specify we want to do
1295
-             * tunneling at the ethernet level
1296
-             */
1297
-            argv_printf(&argv,
1298
-                        "%s %s %s netmask %s mtu %d broadcast %s",
1299
-                        IFCONFIG_PATH,
1300
-                        actual,
1301
-                        ifconfig_local,
1302
-                        ifconfig_remote_netmask,
1303
-                        tun_mtu,
1304
-                        ifconfig_broadcast
1305
-                        );
1306
-        }
1307
-        argv_msg(M_INFO, &argv);
1308
-        openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed");
1198
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1199
+    if (tun)
1200
+    {
1201
+        argv_printf(&argv,
1202
+                    "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
1203
+                    IFCONFIG_PATH, ifname, ifconfig_local,
1204
+                    ifconfig_remote_netmask, tun_mtu);
1205
+    }
1206
+    else if (tt->topology == TOP_SUBNET)
1207
+    {
1208
+        remote_end = create_arbitrary_remote( tt );
1209
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up -link0",
1210
+                    IFCONFIG_PATH, ifname, ifconfig_local,
1211
+                    print_in_addr_t(remote_end, 0, &gc), tun_mtu,
1212
+                    ifconfig_remote_netmask);
1213
+    }
1214
+    else
1215
+    {
1216
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s link0",
1217
+                    IFCONFIG_PATH, ifname, ifconfig_local,
1218
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
1219
+    }
1220
+    argv_msg(M_INFO, &argv);
1221
+    openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed");
1309 1222
 
1310
-        if (do_ipv6)
1311
-        {
1312
-            argv_printf(&argv,
1313
-                        "%s %s inet6 %s/%d",
1314
-                        IFCONFIG_PATH,
1315
-                        actual,
1316
-                        ifconfig_ipv6_local,
1317
-                        tt->netbits_ipv6
1318
-                        );
1319
-            argv_msg(M_INFO, &argv);
1320
-            openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig inet6 failed");
1223
+    /* Add a network route for the local tun interface */
1224
+    if (!tun && tt->topology == TOP_SUBNET)
1225
+    {
1226
+        struct route_ipv4 r;
1227
+        CLEAR(r);
1228
+        r.flags = RT_DEFINED;
1229
+        r.network = tt->local & tt->remote_netmask;
1230
+        r.netmask = tt->remote_netmask;
1231
+        r.gateway = remote_end;
1232
+        add_route(&r, tt, 0, NULL, es);
1233
+    }
1321 1234
 
1322
-            /* and, hooray, we explicitely need to add a route... */
1323
-            add_route_connected_v6_net(tt, es);
1324
-        }
1235
+#elif defined(TARGET_NETBSD)
1325 1236
 
1326
-#elif defined(TARGET_DARWIN)
1237
+    if (tun)
1238
+    {
1239
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1240
+                    IFCONFIG_PATH, ifname, ifconfig_local,
1241
+                    ifconfig_remote_netmask, tun_mtu);
1242
+    }
1243
+    else if (tt->topology == TOP_SUBNET)
1244
+    {
1245
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
1246
+                    ifname, ifconfig_local, ifconfig_local, tun_mtu,
1247
+                    ifconfig_remote_netmask);
1248
+    }
1249
+    else
1250
+    {
1327 1251
         /*
1328
-         * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
1252
+         * NetBSD has distinct tun and tap devices
1253
+         * so we don't need the "link0" extra parameter to specify we want to do
1254
+         * tunneling at the ethernet level
1329 1255
          */
1256
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s",
1257
+                    IFCONFIG_PATH, ifname, ifconfig_local,
1258
+                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
1259
+    }
1260
+    argv_msg(M_INFO, &argv);
1261
+    openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed");
1330 1262
 
1331
-        argv_printf(&argv,
1332
-                    "%s %s delete",
1333
-                    IFCONFIG_PATH,
1334
-                    actual);
1335
-        argv_msg(M_INFO, &argv);
1336
-        openvpn_execve_check(&argv, es, 0, NULL);
1337
-        msg(M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1263
+#elif defined(TARGET_DARWIN)
1264
+    /*
1265
+     * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
1266
+     */
1338 1267
 
1268
+    argv_printf(&argv, "%s %s delete", IFCONFIG_PATH, ifname);
1269
+    argv_msg(M_INFO, &argv);
1270
+    openvpn_execve_check(&argv, es, 0, NULL);
1271
+    msg(M_INFO,
1272
+        "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1339 1273
 
1340
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1341
-        if (tun)
1274
+
1275
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1276
+    if (tun)
1277
+    {
1278
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1279
+                    IFCONFIG_PATH, ifname, ifconfig_local,
1280
+                    ifconfig_remote_netmask, tun_mtu);
1281
+    }
1282
+    else
1283
+    {
1284
+        if (tt->topology == TOP_SUBNET)
1342 1285
         {
1343
-            argv_printf(&argv,
1344
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1345
-                        IFCONFIG_PATH,
1346
-                        actual,
1347
-                        ifconfig_local,
1348
-                        ifconfig_remote_netmask,
1349
-                        tun_mtu
1350
-                        );
1286
+            argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up",
1287
+                        IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_local,
1288
+                        ifconfig_remote_netmask, tun_mtu);
1351 1289
         }
1352 1290
         else
1353 1291
         {
1354
-            if (tt->topology == TOP_SUBNET)
1355
-            {
1356
-                argv_printf(&argv,
1357
-                            "%s %s %s %s netmask %s mtu %d up",
1358
-                            IFCONFIG_PATH,
1359
-                            actual,
1360
-                            ifconfig_local,
1361
-                            ifconfig_local,
1362
-                            ifconfig_remote_netmask,
1363
-                            tun_mtu
1364
-                            );
1365
-            }
1366
-            else
1367
-            {
1368
-                argv_printf(&argv,
1369
-                            "%s %s %s netmask %s mtu %d up",
1370
-                            IFCONFIG_PATH,
1371
-                            actual,
1372
-                            ifconfig_local,
1373
-                            ifconfig_remote_netmask,
1374
-                            tun_mtu
1375
-                            );
1376
-            }
1292
+            argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
1293
+                        ifname, ifconfig_local, ifconfig_remote_netmask,
1294
+                        tun_mtu);
1377 1295
         }
1296
+    }
1378 1297
 
1379
-        argv_msg(M_INFO, &argv);
1380
-        openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed");
1298
+    argv_msg(M_INFO, &argv);
1299
+    openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed");
1381 1300
 
1382
-        /* Add a network route for the local tun interface */
1383
-        if (!tun && tt->topology == TOP_SUBNET)
1384
-        {
1385
-            struct route_ipv4 r;
1386
-            CLEAR(r);
1387
-            r.flags = RT_DEFINED;
1388
-            r.network = tt->local & tt->remote_netmask;
1389
-            r.netmask = tt->remote_netmask;
1390
-            r.gateway = tt->local;
1391
-            add_route(&r, tt, 0, NULL, es);
1392
-        }
1301
+    /* Add a network route for the local tun interface */
1302
+    if (!tun && tt->topology == TOP_SUBNET)
1303
+    {
1304
+        struct route_ipv4 r;
1305
+        CLEAR(r);
1306
+        r.flags = RT_DEFINED;
1307
+        r.network = tt->local & tt->remote_netmask;
1308
+        r.netmask = tt->remote_netmask;
1309
+        r.gateway = tt->local;
1310
+        add_route(&r, tt, 0, NULL, es);
1311
+    }
1393 1312
 
1394
-        if (do_ipv6)
1395
-        {
1396
-            argv_printf(&argv,
1397
-                        "%s %s inet6 %s/%d",
1398
-                        IFCONFIG_PATH,
1399
-                        actual,
1400
-                        ifconfig_ipv6_local,
1401
-                        tt->netbits_ipv6
1402
-                        );
1403
-            argv_msg(M_INFO, &argv);
1404
-            openvpn_execve_check(&argv, es, S_FATAL, "MacOS X ifconfig inet6 failed");
1313
+#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1405 1314
 
1406
-            /* and, hooray, we explicitely need to add a route... */
1407
-            add_route_connected_v6_net(tt, es);
1408
-        }
1315
+    in_addr_t remote_end;           /* for "virtual" subnet topology */
1409 1316
 
1410
-#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1317
+    /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1318
+    if (tun)
1319
+    {
1320
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1321
+                    IFCONFIG_PATH, ifname, ifconfig_local,
1322
+                    ifconfig_remote_netmask, tun_mtu);
1323
+    }
1324
+    else if (tt->topology == TOP_SUBNET)
1325
+    {
1326
+        remote_end = create_arbitrary_remote( tt );
1327
+        argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH,
1328
+                    ifname, ifconfig_local, print_in_addr_t(remote_end, 0, &gc),
1329
+                    tun_mtu, ifconfig_remote_netmask);
1330
+    }
1331
+    else
1332
+    {
1333
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
1334
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1335
+    }
1336
+
1337
+    argv_msg(M_INFO, &argv);
1338
+    openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed");
1339
+
1340
+    /* Add a network route for the local tun interface */
1341
+    if (!tun && tt->topology == TOP_SUBNET)
1342
+    {
1343
+        struct route_ipv4 r;
1344
+        CLEAR(r);
1345
+        r.flags = RT_DEFINED;
1346
+        r.network = tt->local & tt->remote_netmask;
1347
+        r.netmask = tt->remote_netmask;
1348
+        r.gateway = remote_end;
1349
+        add_route(&r, tt, 0, NULL, es);
1350
+    }
1411 1351
 
1412
-        in_addr_t remote_end;           /* for "virtual" subnet topology */
1352
+#elif defined(TARGET_AIX)
1353
+    {
1354
+        /* AIX ifconfig will complain if it can't find ODM path in env */
1355
+        struct env_set *aix_es = env_set_create(NULL);
1356
+        env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
1413 1357
 
1414
-        /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1415 1358
         if (tun)
1416 1359
         {
1417
-            argv_printf(&argv,
1418
-                        "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1419
-                        IFCONFIG_PATH,
1420
-                        actual,
1421
-                        ifconfig_local,
1422
-                        ifconfig_remote_netmask,
1423
-                        tun_mtu
1424
-                        );
1425
-        }
1426
-        else if (tt->topology == TOP_SUBNET)
1427
-        {
1428
-            remote_end = create_arbitrary_remote( tt );
1429
-            argv_printf(&argv,
1430
-                        "%s %s %s %s mtu %d netmask %s up",
1431
-                        IFCONFIG_PATH,
1432
-                        actual,
1433
-                        ifconfig_local,
1434
-                        print_in_addr_t(remote_end, 0, &gc),
1435
-                        tun_mtu,
1436
-                        ifconfig_remote_netmask
1437
-                        );
1438
-        }
1439
-        else
1440
-        {
1441
-            argv_printf(&argv,
1442
-                        "%s %s %s netmask %s mtu %d up",
1443
-                        IFCONFIG_PATH,
1444
-                        actual,
1445
-                        ifconfig_local,
1446
-                        ifconfig_remote_netmask,
1447
-                        tun_mtu
1448
-                        );
1360
+            msg(M_FATAL, "no tun support on AIX (canthappen)");
1449 1361
         }
1450 1362
 
1451
-        argv_msg(M_INFO, &argv);
1452
-        openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed");
1363
+        /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
1364
+        argv_printf(&argv, "%s %s %s netmask %s mtu %d up", IFCONFIG_PATH,
1365
+                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1453 1366
 
1454
-        /* Add a network route for the local tun interface */
1455
-        if (!tun && tt->topology == TOP_SUBNET)
1456
-        {
1457
-            struct route_ipv4 r;
1458
-            CLEAR(r);
1459
-            r.flags = RT_DEFINED;
1460
-            r.network = tt->local & tt->remote_netmask;
1461
-            r.netmask = tt->remote_netmask;
1462
-            r.gateway = remote_end;
1463
-            add_route(&r, tt, 0, NULL, es);
1464
-        }
1367
+        argv_msg(M_INFO, &argv);
1368
+        openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig failed");
1465 1369
 
1466
-        if (do_ipv6)
1467
-        {
1468
-            argv_printf(&argv,
1469
-                        "%s %s inet6 %s/%d",
1470
-                        IFCONFIG_PATH,
1471
-                        actual,
1472
-                        ifconfig_ipv6_local,
1473
-                        tt->netbits_ipv6
1474
-                        );
1475
-            argv_msg(M_INFO, &argv);
1476
-            openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed");
1477
-        }
1370
+        env_set_destroy(aix_es);
1371
+    }
1372
+#elif defined (_WIN32)
1373
+    {
1374
+        ASSERT(ifname != NULL);
1478 1375
 
1479
-#elif defined(TARGET_AIX)
1376
+        switch (tt->options.ip_win32_type)
1480 1377
         {
1481
-            /* AIX ifconfig will complain if it can't find ODM path in env */
1482
-            struct env_set *aix_es = env_set_create(NULL);
1483
-            env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
1484
-
1485
-            if (tun)
1486
-            {
1487
-                msg(M_FATAL, "no tun support on AIX (canthappen)");
1488
-            }
1378
+            case IPW32_SET_MANUAL:
1379
+                msg(M_INFO,
1380
+                    "******** NOTE:  Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1381
+                    ifname, ifconfig_local,
1382
+                    print_in_addr_t(tt->adapter_netmask, 0, &gc));
1383
+                break;
1384
+            case IPW32_SET_NETSH:
1385
+                netsh_ifconfig(&tt->options, ifname, tt->local,
1386
+                               tt->adapter_netmask, NI_IP_NETMASK|NI_OPTIONS);
1489 1387
 
1490
-            /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
1491
-            argv_printf(&argv,
1492
-                        "%s %s %s netmask %s mtu %d up",
1493
-                        IFCONFIG_PATH,
1494
-                        actual,
1495
-                        ifconfig_local,
1496
-                        ifconfig_remote_netmask,
1497
-                        tun_mtu
1498
-                        );
1499
-
1500
-            argv_msg(M_INFO, &argv);
1501
-            openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig failed");
1502
-
1503
-            if (do_ipv6)
1504
-            {
1505
-                argv_printf(&argv,
1506
-                            "%s %s inet6 %s/%d",
1507
-                            IFCONFIG_PATH,
1508
-                            actual,
1509
-                            ifconfig_ipv6_local,
1510
-                            tt->netbits_ipv6
1511
-                            );
1512
-                argv_msg(M_INFO, &argv);
1513
-                openvpn_execve_check(&argv, aix_es, S_FATAL, "AIX ifconfig inet6 failed");
1514
-            }
1515
-            env_set_destroy(aix_es);
1388
+                break;
1516 1389
         }
1517
-#elif defined (_WIN32)
1518
-        {
1519
-            ASSERT(actual != NULL);
1390
+    }
1520 1391
 
1521
-            switch (tt->options.ip_win32_type)
1522
-            {
1523
-                case IPW32_SET_MANUAL:
1524
-                    msg(M_INFO, "******** NOTE:  Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1525
-                        actual,
1526
-                        ifconfig_local,
1527
-                        print_in_addr_t(tt->adapter_netmask, 0, &gc));
1528
-                    break;
1392
+#else  /* if defined(TARGET_LINUX) */
1393
+    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.");
1394
+#endif /* if defined(TARGET_LINUX) */
1529 1395
 
1530
-                case IPW32_SET_NETSH:
1531
-                    netsh_ifconfig(&tt->options,
1532
-                                   actual,
1533
-                                   tt->local,
1534
-                                   tt->adapter_netmask,
1535
-                                   NI_IP_NETMASK|NI_OPTIONS);
1396
+    gc_free(&gc);
1397
+    argv_reset(&argv);
1398
+}
1536 1399
 
1537
-                    break;
1538
-            }
1539
-        }
1400
+/* execute the ifconfig command through the shell */
1401
+void
1402
+do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
1403
+            const struct env_set *es)
1404
+{
1405
+    msg(D_LOW, "do_ifconfig, ipv4=%d, ipv6=%d", tt->did_ifconfig_setup,
1406
+        tt->did_ifconfig_ipv6_setup);
1540 1407
 
1541
-        if (do_ipv6)
1542
-        {
1543
-            if (tt->options.ip_win32_type == IPW32_SET_MANUAL)
1544
-            {
1545
-                msg(M_INFO, "******** NOTE:  Please manually set the v6 IP of '%s' to %s (if it is not already set)",
1546
-                    actual,
1547
-                    ifconfig_ipv6_local);
1548
-            }
1549
-            else if (tt->options.msg_channel)
1550
-            {
1551
-                do_address_service(true, AF_INET6, tt);
1552
-                do_dns6_service(true, tt);
1553
-            }
1554
-            else
1555
-            {
1556
-                /* example: netsh interface ipv6 set address interface=42 2001:608:8003::d store=active */
1557
-                char iface[64];
1558
-                openvpn_snprintf(iface, sizeof(iface), "interface=%lu", tt->adapter_index );
1559
-                argv_printf(&argv,
1560
-                            "%s%sc interface ipv6 set address %s %s store=active",
1561
-                            get_win_sys_path(),
1562
-                            NETSH_PATH_SUFFIX,
1563
-                            iface,
1564
-                            ifconfig_ipv6_local );
1565
-                netsh_command(&argv, 4, M_FATAL);
1566
-                /* set ipv6 dns servers if any are specified */
1567
-                netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, actual);
1568
-            }
1408
+#ifdef ENABLE_MANAGEMENT
1409
+    if (management)
1410
+    {
1411
+        management_set_state(management,
1412
+                             OPENVPN_STATE_ASSIGN_IP,
1413
+                             NULL,
1414
+                             &tt->local,
1415
+                             &tt->local_ipv6,
1416
+                             NULL,
1417
+                             NULL);
1418
+    }
1419
+#endif
1569 1420
 
1570
-            /* explicit route needed */
1571
-            if (tt->options.ip_win32_type != IPW32_SET_MANUAL)
1572
-            {
1573
-                add_route_connected_v6_net(tt, es);
1574
-            }
1575
-        }
1576
-#else  /* if defined(TARGET_LINUX) */
1577
-        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.");
1578
-#endif /* if defined(TARGET_LINUX) */
1579
-        argv_reset(&argv);
1421
+    if (tt->did_ifconfig_setup)
1422
+    {
1423
+        do_ifconfig_ipv4(tt, ifname, tun_mtu, es);
1424
+    }
1425
+
1426
+    if (tt->did_ifconfig_ipv6_setup)
1427
+    {
1428
+        do_ifconfig_ipv6(tt, ifname, tun_mtu, es);
1580 1429
     }
1581
-    gc_free(&gc);
1582 1430
 }
1583 1431
 
1584 1432
 static void
... ...
@@ -2090,76 +1938,75 @@ tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_
2090 2090
 #endif /* ENABLE_FEATURE_TUN_PERSIST */
2091 2091
 
2092 2092
 void
2093
+undo_ifconfig_ipv4(struct tuntap *tt, struct gc_arena *gc)
2094
+{
2095
+    struct argv argv = argv_new();
2096
+
2097
+#ifdef ENABLE_IPROUTE
2098
+    if (is_tun_p2p(tt))
2099
+    {
2100
+        argv_printf(&argv, "%s addr del dev %s local %s peer %s", iproute_path,
2101
+                    tt->actual_name, print_in_addr_t(tt->local, 0, gc),
2102
+                    print_in_addr_t(tt->remote_netmask, 0, gc));
2103
+    }
2104
+    else
2105
+    {
2106
+        argv_printf(&argv, "%s addr del dev %s %s/%d", iproute_path,
2107
+                    tt->actual_name, print_in_addr_t(tt->local, 0, gc),
2108
+                    netmask_to_netbits2(tt->remote_netmask));
2109
+    }
2110
+#else  /* ifdef ENABLE_IPROUTE */
2111
+    argv_printf(&argv, "%s %s 0.0.0.0", IFCONFIG_PATH, tt->actual_name);
2112
+#endif /* ifdef ENABLE_IPROUTE */
2113
+
2114
+    argv_msg(M_INFO, &argv);
2115
+    openvpn_execve_check(&argv, NULL, 0, "Linux ip addr del failed");
2116
+
2117
+    argv_reset(&argv);
2118
+}
2119
+
2120
+void
2121
+undo_ifconfig_ipv6(struct tuntap *tt, struct gc_arena *gc)
2122
+{
2123
+    const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, gc);
2124
+    struct argv argv = argv_new();
2125
+
2126
+#ifdef ENABLE_IPROUTE
2127
+    argv_printf(&argv, "%s -6 addr del %s/%d dev %s", iproute_path,
2128
+                ifconfig_ipv6_local, tt->netbits_ipv6, tt->actual_name);
2129
+#else  /* ifdef ENABLE_IPROUTE */
2130
+    argv_printf(&argv, "%s %s del %s/%d", IFCONFIG_PATH, tt->actual_name,
2131
+                ifconfig_ipv6_local, tt->netbits_ipv6);
2132
+#endif
2133
+
2134
+    argv_msg(M_INFO, &argv);
2135
+    openvpn_execve_check(&argv, NULL, 0, "Linux ip -6 addr del failed");
2136
+
2137
+    argv_reset(&argv);
2138
+}
2139
+
2140
+void
2093 2141
 close_tun(struct tuntap *tt)
2094 2142
 {
2095 2143
     ASSERT(tt);
2096 2144
 
2097
-    if (tt->type != DEV_TYPE_NULL && tt->did_ifconfig_setup)
2145
+    if (tt->type != DEV_TYPE_NULL)
2098 2146
     {
2099
-        struct argv argv = argv_new();
2100 2147
         struct gc_arena gc = gc_new();
2101 2148
 
2102
-#ifdef ENABLE_IPROUTE
2103
-        if (is_tun_p2p(tt))
2149
+        if (tt->did_ifconfig_setup)
2104 2150
         {
2105
-            argv_printf(&argv,
2106
-                        "%s addr del dev %s local %s peer %s",
2107
-                        iproute_path,
2108
-                        tt->actual_name,
2109
-                        print_in_addr_t(tt->local, 0, &gc),
2110
-                        print_in_addr_t(tt->remote_netmask, 0, &gc)
2111
-                       );
2112
-        }
2113
-        else
2114
-        {
2115
-            argv_printf(&argv,
2116
-                        "%s addr del dev %s %s/%d",
2117
-                        iproute_path,
2118
-                        tt->actual_name,
2119
-                        print_in_addr_t(tt->local, 0, &gc),
2120
-                        netmask_to_netbits2(tt->remote_netmask)
2121
-                       );
2151
+            undo_ifconfig_ipv4(tt, &gc);
2122 2152
         }
2123
-#else  /* ifdef ENABLE_IPROUTE */
2124
-        argv_printf(&argv,
2125
-                    "%s %s 0.0.0.0",
2126
-                    IFCONFIG_PATH,
2127
-                    tt->actual_name
2128
-                   );
2129
-#endif /* ifdef ENABLE_IPROUTE */
2130
-
2131
-        argv_msg(M_INFO, &argv);
2132
-        openvpn_execve_check(&argv, NULL, 0, "Linux ip addr del failed");
2133 2153
 
2134 2154
         if (tt->did_ifconfig_ipv6_setup)
2135 2155
         {
2136
-            const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
2137
-
2138
-#ifdef ENABLE_IPROUTE
2139
-            argv_printf(&argv, "%s -6 addr del %s/%d dev %s",
2140
-                        iproute_path,
2141
-                        ifconfig_ipv6_local,
2142
-                        tt->netbits_ipv6,
2143
-                        tt->actual_name
2144
-                       );
2145
-            argv_msg(M_INFO, &argv);
2146
-            openvpn_execve_check(&argv, NULL, 0, "Linux ip -6 addr del failed");
2147
-#else  /* ifdef ENABLE_IPROUTE */
2148
-            argv_printf(&argv,
2149
-                        "%s %s del %s/%d",
2150
-                        IFCONFIG_PATH,
2151
-                        tt->actual_name,
2152
-                        ifconfig_ipv6_local,
2153
-                        tt->netbits_ipv6
2154
-                       );
2155
-            argv_msg(M_INFO, &argv);
2156
-            openvpn_execve_check(&argv, NULL, 0, "Linux ifconfig inet6 del failed");
2157
-#endif
2156
+            undo_ifconfig_ipv6(tt, &gc);
2158 2157
         }
2159 2158
 
2160
-        argv_reset(&argv);
2161 2159
         gc_free(&gc);
2162 2160
     }
2161
+
2163 2162
     close_tun_generic(tt);
2164 2163
     free(tt);
2165 2164
 }
... ...
@@ -5851,7 +5698,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
5851 5851
 
5852 5852
     if (tt->type == DEV_TYPE_TUN)
5853 5853
     {
5854
-        if (!tt->did_ifconfig_setup)
5854
+        if (!tt->did_ifconfig_setup && !tt->did_ifconfig_ipv6_setup)
5855 5855
         {
5856 5856
             msg(M_FATAL, "ERROR: --dev tun also requires --ifconfig");
5857 5857
         }
... ...
@@ -246,9 +246,15 @@ void init_tun_post(struct tuntap *tt,
246 246
 void do_ifconfig_setenv(const struct tuntap *tt,
247 247
                         struct env_set *es);
248 248
 
249
-void do_ifconfig(struct tuntap *tt,
250
-                 const char *actual,     /* actual device name */
251
-                 int tun_mtu,
249
+/**
250
+ * do_ifconfig - configure the tunnel interface
251
+ *
252
+ * @param tt        the tuntap interface context
253
+ * @param ifname    the human readable interface name
254
+ * @param mtu       the MTU value to set the interface to
255
+ * @param es        the environment to be used when executing the commands
256
+ */
257
+void do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
252 258
                  const struct env_set *es);
253 259
 
254 260
 bool is_dev_type(const char *dev, const char *dev_type, const char *match_type);