Browse code

tun.c: use new networking API to handle tun interface on Linux

By switching to the networking API (for Linux) openvpn will
now use any of the available implementations to handle the tun
interface.

At the moment only iproute2 and sitnl (NetLink) is implemented.

Signed-off-by: Antonio Quartulli <a@unstable.cc>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <20181219050118.6568-4-a@unstable.cc>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg18028.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Antonio Quartulli authored on 2018/12/19 14:01:14
Showing 9 changed files
... ...
@@ -1105,7 +1105,7 @@ do_genkey(const struct options *options)
1105 1105
  * Persistent TUN/TAP device management mode?
1106 1106
  */
1107 1107
 bool
1108
-do_persist_tuntap(const struct options *options)
1108
+do_persist_tuntap(const struct options *options, openvpn_net_ctx_t *ctx)
1109 1109
 {
1110 1110
     if (options->persist_config)
1111 1111
     {
... ...
@@ -1123,7 +1123,8 @@ do_persist_tuntap(const struct options *options)
1123 1123
 #ifdef ENABLE_FEATURE_TUN_PERSIST
1124 1124
         tuncfg(options->dev, options->dev_type, options->dev_node,
1125 1125
                options->persist_mode,
1126
-               options->username, options->groupname, &options->tuntap_options);
1126
+               options->username, options->groupname, &options->tuntap_options,
1127
+               ctx);
1127 1128
         if (options->persist_mode && options->lladdr)
1128 1129
         {
1129 1130
             set_lladdr(options->dev, options->lladdr, NULL);
... ...
@@ -1694,7 +1695,8 @@ do_init_tun(struct context *c)
1694 1694
                             c->c1.link_socket_addr.bind_local,
1695 1695
                             c->c1.link_socket_addr.remote_list,
1696 1696
                             !c->options.ifconfig_nowarn,
1697
-                            c->c2.es);
1697
+                            c->c2.es,
1698
+                            &c->net_ctx);
1698 1699
 
1699 1700
     init_tun_post(c->c1.tuntap,
1700 1701
                   &c->c2.frame,
... ...
@@ -1766,7 +1768,8 @@ do_open_tun(struct context *c)
1766 1766
                                              c->options.dev_type,
1767 1767
                                              c->options.dev_node,
1768 1768
                                              &gc);
1769
-        do_ifconfig(c->c1.tuntap, guess, TUN_MTU_SIZE(&c->c2.frame), c->c2.es);
1769
+        do_ifconfig(c->c1.tuntap, guess, TUN_MTU_SIZE(&c->c2.frame), c->c2.es,
1770
+                    &c->net_ctx);
1770 1771
     }
1771 1772
 
1772 1773
     /* possibly add routes */
... ...
@@ -1794,7 +1797,8 @@ do_open_tun(struct context *c)
1794 1794
     if (!c->options.ifconfig_noexec
1795 1795
         && ifconfig_order() == IFCONFIG_AFTER_TUN_OPEN)
1796 1796
     {
1797
-        do_ifconfig(c->c1.tuntap, c->c1.tuntap->actual_name, TUN_MTU_SIZE(&c->c2.frame), c->c2.es);
1797
+        do_ifconfig(c->c1.tuntap, c->c1.tuntap->actual_name,
1798
+                    TUN_MTU_SIZE(&c->c2.frame), c->c2.es, &c->net_ctx);
1798 1799
     }
1799 1800
 
1800 1801
     /* run the up script */
... ...
@@ -1902,7 +1906,7 @@ do_close_tun_simple(struct context *c)
1902 1902
     msg(D_CLOSE, "Closing TUN/TAP interface");
1903 1903
     if (c->c1.tuntap)
1904 1904
     {
1905
-        close_tun(c->c1.tuntap);
1905
+        close_tun(c->c1.tuntap, &c->net_ctx);
1906 1906
         c->c1.tuntap = NULL;
1907 1907
     }
1908 1908
     c->c1.tuntap_owned = false;
... ...
@@ -3380,9 +3384,11 @@ do_compute_occ_strings(struct context *c)
3380 3380
     struct gc_arena gc = gc_new();
3381 3381
 
3382 3382
     c->c2.options_string_local =
3383
-        options_string(&c->options, &c->c2.frame, c->c1.tuntap, false, &gc);
3383
+        options_string(&c->options, &c->c2.frame, c->c1.tuntap, &c->net_ctx,
3384
+                       false, &gc);
3384 3385
     c->c2.options_string_remote =
3385
-        options_string(&c->options, &c->c2.frame, c->c1.tuntap, true, &gc);
3386
+        options_string(&c->options, &c->c2.frame, c->c1.tuntap, &c->net_ctx,
3387
+                       true, &gc);
3386 3388
 
3387 3389
     msg(D_SHOW_OCC, "Local Options String (VER=%s): '%s'",
3388 3390
         options_string_version(c->c2.options_string_local, &gc),
... ...
@@ -56,7 +56,7 @@ bool print_openssl_info(const struct options *options);
56 56
 
57 57
 bool do_genkey(const struct options *options);
58 58
 
59
-bool do_persist_tuntap(const struct options *options);
59
+bool do_persist_tuntap(const struct options *options, openvpn_net_ctx_t *ctx);
60 60
 
61 61
 bool possibly_become_daemon(const struct options *options);
62 62
 
... ...
@@ -21,12 +21,6 @@
21 21
 #ifndef NETWORKING_H_
22 22
 #define NETWORKING_H_
23 23
 
24
-#ifdef HAVE_CONFIG_H
25
-#include "config.h"
26
-#elif defined(_MSC_VER)
27
-#include "config-msvc.h"
28
-#endif
29
-
30 24
 #include "syshead.h"
31 25
 
32 26
 struct context;
... ...
@@ -215,6 +215,8 @@ openvpn_main(int argc, char *argv[])
215 215
             open_plugins(&c, true, OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE);
216 216
 #endif
217 217
 
218
+            net_ctx_init(&c, &c.net_ctx);
219
+
218 220
             /* init verbosity and mute levels */
219 221
             init_verb_mute(&c, IVM_LEVEL_1);
220 222
 
... ...
@@ -234,7 +236,7 @@ openvpn_main(int argc, char *argv[])
234 234
             }
235 235
 
236 236
             /* tun/tap persist command? */
237
-            if (do_persist_tuntap(&c.options))
237
+            if (do_persist_tuntap(&c.options, &c.net_ctx))
238 238
             {
239 239
                 break;
240 240
             }
... ...
@@ -522,6 +522,8 @@ struct context
522 522
 
523 523
     struct env_set *es;         /**< Set of environment variables. */
524 524
 
525
+    openvpn_net_ctx_t net_ctx;	/**< Networking API opaque context */
526
+
525 527
     struct signal_info *sig;    /**< Internal error signaling object. */
526 528
 
527 529
     struct plugin_list *plugins; /**< List of plug-ins. */
... ...
@@ -3548,6 +3548,7 @@ char *
3548 3548
 options_string(const struct options *o,
3549 3549
                const struct frame *frame,
3550 3550
                struct tuntap *tt,
3551
+               openvpn_net_ctx_t *ctx,
3551 3552
                bool remote,
3552 3553
                struct gc_arena *gc)
3553 3554
 {
... ...
@@ -3590,7 +3591,8 @@ options_string(const struct options *o,
3590 3590
                       NULL,
3591 3591
                       NULL,
3592 3592
                       false,
3593
-                      NULL);
3593
+                      NULL,
3594
+                      ctx);
3594 3595
         if (tt)
3595 3596
         {
3596 3597
             tt_local = true;
... ...
@@ -744,6 +744,7 @@ const char *options_string_version(const char *s, struct gc_arena *gc);
744 744
 char *options_string(const struct options *o,
745 745
                      const struct frame *frame,
746 746
                      struct tuntap *tt,
747
+                     openvpn_net_ctx_t *ctx,
747 748
                      bool remote,
748 749
                      struct gc_arena *gc);
749 750
 
... ...
@@ -46,6 +46,7 @@
46 46
 #include "route.h"
47 47
 #include "win32.h"
48 48
 #include "block_dns.h"
49
+#include "networking.h"
49 50
 
50 51
 #include "memdbg.h"
51 52
 
... ...
@@ -631,7 +632,8 @@ init_tun(const char *dev,        /* --dev option */
631 631
          struct addrinfo *local_public,
632 632
          struct addrinfo *remote_public,
633 633
          const bool strict_warn,
634
-         struct env_set *es)
634
+         struct env_set *es,
635
+         openvpn_net_ctx_t *ctx)
635 636
 {
636 637
     struct gc_arena gc = gc_new();
637 638
     struct tuntap *tt;
... ...
@@ -870,35 +872,37 @@ create_arbitrary_remote( struct tuntap *tt )
870 870
  * @param ifname    the human readable interface name
871 871
  * @param mtu       the MTU value to set the interface to
872 872
  * @param es        the environment to be used when executing the commands
873
+ * @param ctx       the networking API opaque context
873 874
  */
874 875
 static void
875 876
 do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
876
-                 const struct env_set *es)
877
+                 const struct env_set *es, openvpn_net_ctx_t *ctx)
877 878
 {
878
-    const char *ifconfig_ipv6_local = NULL;
879
+#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
880
+    || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
881
+    || defined(TARGET_DRAGONFLY) || defined(TARGET_AIX) \
882
+    || defined(TARGET_SOLARIS) || defined(_WIN32)
879 883
     struct argv argv = argv_new();
880 884
     struct gc_arena gc = gc_new();
881
-
882
-    ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
885
+    const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, &gc);
886
+#endif
883 887
 
884 888
 #if defined(TARGET_LINUX)
885
-#ifdef ENABLE_IPROUTE
886
-    /* set the MTU for the device and bring it up */
887
-    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
888
-                tun_mtu);
889
-    argv_msg(M_INFO, &argv);
890
-    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
889
+    if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
890
+    {
891
+        msg(M_FATAL, "Linux can't set mtu (%d) on %s", tun_mtu, ifname);
892
+    }
891 893
 
892
-    argv_printf(&argv, "%s -6 addr add %s/%d dev %s", iproute_path,
893
-                ifconfig_ipv6_local, tt->netbits_ipv6, ifname);
894
-    argv_msg(M_INFO, &argv);
895
-    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip -6 addr add failed");
896
-#else  /* ifdef ENABLE_IPROUTE */
897
-    argv_printf(&argv, "%s %s add %s/%d mtu %d up", IFCONFIG_PATH, ifname,
898
-                ifconfig_ipv6_local, tt->netbits_ipv6, tun_mtu);
899
-    argv_msg(M_INFO, &argv);
900
-    openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
901
-#endif
894
+    if (net_iface_up(ctx, ifname, true) < 0)
895
+    {
896
+        msg(M_FATAL, "Linux can't bring %s up", ifname);
897
+    }
898
+
899
+    if (net_addr_v6_add(ctx, ifname, &tt->local_ipv6,
900
+                        tt->netbits_ipv6) < 0)
901
+    {
902
+        msg(M_FATAL, "Linux can't add IPv6 to interface %s", ifname);
903
+    }
902 904
 #elif defined(TARGET_ANDROID)
903 905
     char out6[64];
904 906
 
... ...
@@ -1011,8 +1015,13 @@ do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
1011 1011
     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.");
1012 1012
 #endif /* outer "if defined(TARGET_xxx)" conditional */
1013 1013
 
1014
+#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
1015
+    || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
1016
+    || defined(TARGET_DRAGONFLY) || defined(TARGET_AIX) \
1017
+    || defined(TARGET_SOLARIS) || defined(_WIN32)
1014 1018
     gc_free(&gc);
1015 1019
     argv_reset(&argv);
1020
+#endif
1016 1021
 }
1017 1022
 
1018 1023
 /**
... ...
@@ -1022,12 +1031,21 @@ do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
1022 1022
  * @param ifname    the human readable interface name
1023 1023
  * @param mtu       the MTU value to set the interface to
1024 1024
  * @param es        the environment to be used when executing the commands
1025
+ * @param ctx       the networking API opaque context
1025 1026
  */
1026 1027
 static void
1027 1028
 do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
1028
-                 const struct env_set *es)
1029
+                 const struct env_set *es, openvpn_net_ctx_t *ctx)
1029 1030
 {
1030
-    bool tun = false;
1031
+    /*
1032
+     * We only handle TUN/TAP devices here, not --dev null devices.
1033
+     */
1034
+    bool tun = is_tun_p2p(tt);
1035
+
1036
+#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
1037
+    || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
1038
+    || defined(TARGET_DRAGONFLY) || defined(TARGET_AIX) \
1039
+    || defined(TARGET_SOLARIS) || defined(_WIN32)
1031 1040
     const char *ifconfig_local = NULL;
1032 1041
     const char *ifconfig_remote_netmask = NULL;
1033 1042
     const char *ifconfig_broadcast = NULL;
... ...
@@ -1035,11 +1053,6 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
1035 1035
     struct gc_arena gc = gc_new();
1036 1036
 
1037 1037
     /*
1038
-     * We only handle TUN/TAP devices here, not --dev null devices.
1039
-     */
1040
-    tun = is_tun_p2p(tt);
1041
-
1042
-    /*
1043 1038
      * Set ifconfig parameters
1044 1039
      */
1045 1040
     ifconfig_local = print_in_addr_t(tt->local, 0, &gc);
... ...
@@ -1052,53 +1065,36 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
1052 1052
     {
1053 1053
         ifconfig_broadcast = print_in_addr_t(tt->broadcast, 0, &gc);
1054 1054
     }
1055
+#endif
1055 1056
 
1056 1057
 #if defined(TARGET_LINUX)
1057
-#ifdef ENABLE_IPROUTE
1058
-    /*
1059
-     * Set the MTU for the device
1060
-     */
1061
-    argv_printf(&argv, "%s link set dev %s up mtu %d", iproute_path, ifname,
1062
-                tun_mtu);
1063
-    argv_msg(M_INFO, &argv);
1064
-    openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
1065
-
1066
-    if (tun)
1058
+    if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1067 1059
     {
1068
-
1069
-        /*
1070
-         * Set the address for the device
1071
-         */
1072
-        argv_printf(&argv, "%s addr add dev %s local %s peer %s", iproute_path,
1073
-                    ifname, ifconfig_local, ifconfig_remote_netmask);
1074
-        argv_msg(M_INFO, &argv);
1075
-        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
1060
+        msg(M_FATAL, "Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1076 1061
     }
1077
-    else
1062
+
1063
+    if (net_iface_up(ctx, ifname, true) < 0)
1078 1064
     {
1079
-        argv_printf(&argv, "%s addr add dev %s %s/%d broadcast %s",
1080
-                    iproute_path, ifname, ifconfig_local,
1081
-                    netmask_to_netbits2(tt->remote_netmask),
1082
-                    ifconfig_broadcast);
1083
-        argv_msg(M_INFO, &argv);
1084
-        openvpn_execve_check(&argv, es, S_FATAL, "Linux ip addr add failed");
1065
+        msg(M_FATAL, "Linux can't bring %s up", ifname);
1085 1066
     }
1086
-#else  /* ifdef ENABLE_IPROUTE */
1067
+
1087 1068
     if (tun)
1088 1069
     {
1089
-        argv_printf(&argv, "%s %s %s pointopoint %s mtu %d", IFCONFIG_PATH,
1090
-                    ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1070
+        if (net_addr_ptp_v4_add(ctx, ifname, &tt->local,
1071
+                                &tt->remote_netmask) < 0)
1072
+        {
1073
+            msg(M_FATAL, "Linux can't add IP to TUN interface %s", ifname);
1074
+        }
1091 1075
     }
1092 1076
     else
1093 1077
     {
1094
-        argv_printf(&argv, "%s %s %s netmask %s mtu %d broadcast %s",
1095
-                    IFCONFIG_PATH, ifname, ifconfig_local,
1096
-                    ifconfig_remote_netmask, tun_mtu, ifconfig_broadcast);
1078
+        if (net_addr_v4_add(ctx, ifname, &tt->local,
1079
+                            netmask_to_netbits2(tt->remote_netmask),
1080
+                            &tt->remote_netmask) < 0)
1081
+        {
1082
+            msg(M_FATAL, "Linux can't add IP to TAP interface %s", ifname);
1083
+        }
1097 1084
     }
1098
-    argv_msg(M_INFO, &argv);
1099
-    openvpn_execve_check(&argv, es, S_FATAL, "Linux ifconfig failed");
1100
-
1101
-#endif /*ENABLE_IPROUTE*/
1102 1085
 #elif defined(TARGET_ANDROID)
1103 1086
     char out[64];
1104 1087
 
... ...
@@ -1400,14 +1396,19 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
1400 1400
     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.");
1401 1401
 #endif /* if defined(TARGET_LINUX) */
1402 1402
 
1403
+#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
1404
+    || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
1405
+    || defined(TARGET_DRAGONFLY) || defined(TARGET_AIX) \
1406
+    || defined(TARGET_SOLARIS) || defined(_WIN32)
1403 1407
     gc_free(&gc);
1404 1408
     argv_reset(&argv);
1409
+#endif
1405 1410
 }
1406 1411
 
1407 1412
 /* execute the ifconfig command through the shell */
1408 1413
 void
1409 1414
 do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
1410
-            const struct env_set *es)
1415
+            const struct env_set *es, openvpn_net_ctx_t *ctx)
1411 1416
 {
1412 1417
     msg(D_LOW, "do_ifconfig, ipv4=%d, ipv6=%d", tt->did_ifconfig_setup,
1413 1418
         tt->did_ifconfig_ipv6_setup);
... ...
@@ -1427,12 +1428,12 @@ do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
1427 1427
 
1428 1428
     if (tt->did_ifconfig_setup)
1429 1429
     {
1430
-        do_ifconfig_ipv4(tt, ifname, tun_mtu, es);
1430
+        do_ifconfig_ipv4(tt, ifname, tun_mtu, es, ctx);
1431 1431
     }
1432 1432
 
1433 1433
     if (tt->did_ifconfig_ipv6_setup)
1434 1434
     {
1435
-        do_ifconfig_ipv6(tt, ifname, tun_mtu, es);
1435
+        do_ifconfig_ipv6(tt, ifname, tun_mtu, es, ctx);
1436 1436
     }
1437 1437
 }
1438 1438
 
... ...
@@ -1743,7 +1744,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
1743 1743
 }
1744 1744
 
1745 1745
 void
1746
-close_tun(struct tuntap *tt)
1746
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
1747 1747
 {
1748 1748
     ASSERT(tt);
1749 1749
 
... ...
@@ -1899,7 +1900,9 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
1899 1899
 #ifdef ENABLE_FEATURE_TUN_PERSIST
1900 1900
 
1901 1901
 void
1902
-tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options)
1902
+tuncfg(const char *dev, const char *dev_type, const char *dev_node,
1903
+       int persist_mode, const char *username, const char *groupname,
1904
+       const struct tuntap_options *options, openvpn_net_ctx_t *ctx)
1903 1905
 {
1904 1906
     struct tuntap *tt;
1905 1907
 
... ...
@@ -1938,62 +1941,74 @@ tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_
1938 1938
             msg(M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", groupname, dev);
1939 1939
         }
1940 1940
     }
1941
-    close_tun(tt);
1941
+    close_tun(tt, ctx);
1942 1942
     msg(M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF"));
1943 1943
 }
1944 1944
 
1945 1945
 #endif /* ENABLE_FEATURE_TUN_PERSIST */
1946 1946
 
1947 1947
 void
1948
-undo_ifconfig_ipv4(struct tuntap *tt, struct gc_arena *gc)
1948
+undo_ifconfig_ipv4(struct tuntap *tt, struct gc_arena *gc,
1949
+                   openvpn_net_ctx_t *ctx)
1949 1950
 {
1950
-    struct argv argv = argv_new();
1951
+#if defined(TARGET_LINUX)
1952
+    int netbits = netmask_to_netbits2(tt->remote_netmask);
1951 1953
 
1952
-#ifdef ENABLE_IPROUTE
1953 1954
     if (is_tun_p2p(tt))
1954 1955
     {
1955
-        argv_printf(&argv, "%s addr del dev %s local %s peer %s", iproute_path,
1956
-                    tt->actual_name, print_in_addr_t(tt->local, 0, gc),
1957
-                    print_in_addr_t(tt->remote_netmask, 0, gc));
1956
+        if (net_addr_ptp_v4_del(ctx, tt->actual_name, &tt->local,
1957
+                                &tt->remote_netmask) < 0)
1958
+        {
1959
+            msg(M_WARN, "Linux can't del IP from TUN iface %s",
1960
+                tt->actual_name);
1961
+        }
1958 1962
     }
1959 1963
     else
1960 1964
     {
1961
-        argv_printf(&argv, "%s addr del dev %s %s/%d", iproute_path,
1962
-                    tt->actual_name, print_in_addr_t(tt->local, 0, gc),
1963
-                    netmask_to_netbits2(tt->remote_netmask));
1965
+        if (net_addr_v4_del(ctx, tt->actual_name, &tt->local, netbits) < 0)
1966
+        {
1967
+            msg(M_WARN, "Linux can't del IP from TAP iface %s",
1968
+                tt->actual_name);
1969
+        }
1964 1970
     }
1965
-#else  /* ifdef ENABLE_IPROUTE */
1971
+#else  /* ifdef TARGET_LINUX */
1972
+    struct argv argv = argv_new();
1973
+
1966 1974
     argv_printf(&argv, "%s %s 0.0.0.0", IFCONFIG_PATH, tt->actual_name);
1967
-#endif /* ifdef ENABLE_IPROUTE */
1968 1975
 
1969 1976
     argv_msg(M_INFO, &argv);
1970
-    openvpn_execve_check(&argv, NULL, 0, "Linux ip addr del failed");
1977
+    openvpn_execve_check(&argv, NULL, 0, "Generic ip addr del failed");
1971 1978
 
1972 1979
     argv_reset(&argv);
1980
+#endif /* ifdef TARGET_LINUX */
1973 1981
 }
1974 1982
 
1975 1983
 void
1976
-undo_ifconfig_ipv6(struct tuntap *tt, struct gc_arena *gc)
1984
+undo_ifconfig_ipv6(struct tuntap *tt, struct gc_arena *gc,
1985
+                   openvpn_net_ctx_t *ctx)
1977 1986
 {
1987
+#if defined(TARGET_LINUX)
1988
+    if (net_addr_v6_del(ctx, tt->actual_name, &tt->local_ipv6,
1989
+                        tt->netbits_ipv6) < 0)
1990
+    {
1991
+        msg(M_WARN, "Linux can't del IPv6 from iface %s", tt->actual_name);
1992
+    }
1993
+#else  /* ifdef TARGET_LINUX */
1978 1994
     const char *ifconfig_ipv6_local = print_in6_addr(tt->local_ipv6, 0, gc);
1979 1995
     struct argv argv = argv_new();
1980 1996
 
1981
-#ifdef ENABLE_IPROUTE
1982
-    argv_printf(&argv, "%s -6 addr del %s/%d dev %s", iproute_path,
1983
-                ifconfig_ipv6_local, tt->netbits_ipv6, tt->actual_name);
1984
-#else  /* ifdef ENABLE_IPROUTE */
1985 1997
     argv_printf(&argv, "%s %s del %s/%d", IFCONFIG_PATH, tt->actual_name,
1986 1998
                 ifconfig_ipv6_local, tt->netbits_ipv6);
1987
-#endif
1988 1999
 
1989 2000
     argv_msg(M_INFO, &argv);
1990 2001
     openvpn_execve_check(&argv, NULL, 0, "Linux ip -6 addr del failed");
1991 2002
 
1992 2003
     argv_reset(&argv);
2004
+#endif /* ifdef TARGET_LINUX */
1993 2005
 }
1994 2006
 
1995 2007
 void
1996
-close_tun(struct tuntap *tt)
2008
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
1997 2009
 {
1998 2010
     ASSERT(tt);
1999 2011
 
... ...
@@ -2003,12 +2018,12 @@ close_tun(struct tuntap *tt)
2003 2003
 
2004 2004
         if (tt->did_ifconfig_setup)
2005 2005
         {
2006
-            undo_ifconfig_ipv4(tt, &gc);
2006
+            undo_ifconfig_ipv4(tt, &gc, ctx);
2007 2007
         }
2008 2008
 
2009 2009
         if (tt->did_ifconfig_ipv6_setup)
2010 2010
         {
2011
-            undo_ifconfig_ipv6(tt, &gc);
2011
+            undo_ifconfig_ipv6(tt, &gc, ctx);
2012 2012
         }
2013 2013
 
2014 2014
         gc_free(&gc);
... ...
@@ -2328,7 +2343,7 @@ solaris_close_tun(struct tuntap *tt)
2328 2328
  * Close TUN device.
2329 2329
  */
2330 2330
 void
2331
-close_tun(struct tuntap *tt)
2331
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2332 2332
 {
2333 2333
     ASSERT(tt);
2334 2334
 
... ...
@@ -2364,7 +2379,7 @@ solaris_error_close(struct tuntap *tt, const struct env_set *es,
2364 2364
 
2365 2365
     argv_msg(M_INFO, &argv);
2366 2366
     openvpn_execve_check(&argv, es, 0, "Solaris ifconfig unplumb failed");
2367
-    close_tun(tt);
2367
+    close_tun(tt, NULL);
2368 2368
     msg(M_FATAL, "Solaris ifconfig failed");
2369 2369
     argv_reset(&argv);
2370 2370
 }
... ...
@@ -2427,7 +2442,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
2427 2427
  */
2428 2428
 
2429 2429
 void
2430
-close_tun(struct tuntap *tt)
2430
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2431 2431
 {
2432 2432
     ASSERT(tt);
2433 2433
 
... ...
@@ -2513,7 +2528,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
2513 2513
  * need to be explicitly destroyed
2514 2514
  */
2515 2515
 void
2516
-close_tun(struct tuntap *tt)
2516
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2517 2517
 {
2518 2518
     ASSERT(tt);
2519 2519
 
... ...
@@ -2654,7 +2669,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
2654 2654
  * we need to call "ifconfig ... destroy" for cleanup
2655 2655
  */
2656 2656
 void
2657
-close_tun(struct tuntap *tt)
2657
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2658 2658
 {
2659 2659
     ASSERT(tt);
2660 2660
 
... ...
@@ -2770,7 +2785,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
2770 2770
 }
2771 2771
 
2772 2772
 void
2773
-close_tun(struct tuntap *tt)
2773
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
2774 2774
 {
2775 2775
     ASSERT(tt);
2776 2776
 
... ...
@@ -3026,7 +3041,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
3026 3026
 }
3027 3027
 
3028 3028
 void
3029
-close_tun(struct tuntap *tt)
3029
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
3030 3030
 {
3031 3031
     ASSERT(tt);
3032 3032
 
... ...
@@ -3174,7 +3189,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
3174 3174
 /* tap devices need to be manually destroyed on AIX
3175 3175
  */
3176 3176
 void
3177
-close_tun(struct tuntap *tt)
3177
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
3178 3178
 {
3179 3179
     ASSERT(tt);
3180 3180
 
... ...
@@ -6067,7 +6082,7 @@ tun_show_debug(struct tuntap *tt)
6067 6067
 }
6068 6068
 
6069 6069
 void
6070
-close_tun(struct tuntap *tt)
6070
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
6071 6071
 {
6072 6072
     ASSERT(tt);
6073 6073
 
... ...
@@ -6242,7 +6257,7 @@ open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tun
6242 6242
 }
6243 6243
 
6244 6244
 void
6245
-close_tun(struct tuntap *tt)
6245
+close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
6246 6246
 {
6247 6247
     ASSERT(tt);
6248 6248
 
... ...
@@ -36,6 +36,7 @@
36 36
 #include "event.h"
37 37
 #include "proto.h"
38 38
 #include "misc.h"
39
+#include "networking.h"
39 40
 
40 41
 #if defined(_WIN32) || defined(TARGET_ANDROID)
41 42
 
... ...
@@ -211,7 +212,7 @@ tuntap_defined(const struct tuntap *tt)
211 211
 void open_tun(const char *dev, const char *dev_type, const char *dev_node,
212 212
               struct tuntap *tt);
213 213
 
214
-void close_tun(struct tuntap *tt);
214
+void close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx);
215 215
 
216 216
 int write_tun(struct tuntap *tt, uint8_t *buf, int len);
217 217
 
... ...
@@ -219,7 +220,8 @@ int read_tun(struct tuntap *tt, uint8_t *buf, int len);
219 219
 
220 220
 void tuncfg(const char *dev, const char *dev_type, const char *dev_node,
221 221
             int persist_mode, const char *username,
222
-            const char *groupname, const struct tuntap_options *options);
222
+            const char *groupname, const struct tuntap_options *options,
223
+            openvpn_net_ctx_t *ctx);
223 224
 
224 225
 const char *guess_tuntap_dev(const char *dev,
225 226
                              const char *dev_type,
... ...
@@ -237,7 +239,8 @@ struct tuntap *init_tun(const char *dev,        /* --dev option */
237 237
                         struct addrinfo *local_public,
238 238
                         struct addrinfo *remote_public,
239 239
                         const bool strict_warn,
240
-                        struct env_set *es);
240
+                        struct env_set *es,
241
+                        openvpn_net_ctx_t *ctx);
241 242
 
242 243
 void init_tun_post(struct tuntap *tt,
243 244
                    const struct frame *frame,
... ...
@@ -253,9 +256,10 @@ void do_ifconfig_setenv(const struct tuntap *tt,
253 253
  * @param ifname    the human readable interface name
254 254
  * @param mtu       the MTU value to set the interface to
255 255
  * @param es        the environment to be used when executing the commands
256
+ * @param ctx       the networking API opaque context
256 257
  */
257 258
 void do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
258
-                 const struct env_set *es);
259
+                 const struct env_set *es, openvpn_net_ctx_t *ctx);
259 260
 
260 261
 bool is_dev_type(const char *dev, const char *dev_type, const char *match_type);
261 262