Browse code

Platform cleanup for OpenBSD

Turn around initialization order (IFCONFIG_AFTER_TUN_OPEN) to make it
"the same as all other platforms besides Windows" (tun.h).

Remove "ifconfig destroy / ifconfig create" from open_tun() and change
to generic "create tun device by opening /dev/tunN" approach, thus
cleaning up the IFCONFIG_BEFORE_TUN_OPEN bit.

Add "-link0" for ifconfig calls in tun mode, to make sure that even if
we happen to re-use a not-cleaned-up tun interface in tap mode, it will
then be setup correctly (-link0 -> tun, link0 -> tap).

Add correct ifconfig calls for "topology subnet".

On tunnel close, only call "ifconfig destroy" if it was a tap interface
(tun + link0), because those do not auto-disappear (OpenBSD bug?)

Get rid of READV/WRITEV #ifdef's - as per the man page, these calls have
been added to 4.2BSD, and there never was an OpenBSD version without.

Tested on OpenBSD 4.9 with tun+tap, ipv4+ipv6, topology net30+subnet

Signed-off-by: Gert Doering <gert@greenie.muc.de>
Acked-by: David Sommerseth <davids@redhat.com>
Signed-off-by: David Sommerseth <davids@redhat.com>

Gert Doering authored on 2012/02/05 21:35:03
Showing 2 changed files
... ...
@@ -880,29 +880,15 @@ do_ifconfig (struct tuntap *tt,
880 880
 #elif defined(TARGET_OPENBSD)
881 881
 
882 882
       /*
883
-       * OpenBSD tun devices appear to be persistent by default.  It seems in order
884
-       * to make this work correctly, we need to delete the previous instance
885
-       * (if it exists), and re-ifconfig.  Let me know if you know a better way.
883
+       * On OpenBSD, tun interfaces are persistant if created with
884
+       * "ifconfig tunX create", and auto-destroyed if created by
885
+       * opening "/dev/tunX" (so we just use the /dev/tunX)
886 886
        */
887 887
 
888
-      argv_printf (&argv,
889
-			"%s %s destroy",
890
-			IFCONFIG_PATH,
891
-			actual);
892
-      argv_msg (M_INFO, &argv);
893
-      openvpn_execve_check (&argv, es, 0, NULL);
894
-      argv_printf (&argv,
895
-			"%s %s create",
896
-			IFCONFIG_PATH,
897
-			actual);
898
-      argv_msg (M_INFO, &argv);
899
-      openvpn_execve_check (&argv, es, 0, NULL);
900
-      msg (M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
901
-
902 888
       /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
903 889
       if (tun)
904 890
 	argv_printf (&argv,
905
-			  "%s %s %s %s mtu %d netmask 255.255.255.255 up",
891
+			  "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
906 892
 			  IFCONFIG_PATH,
907 893
 			  actual,
908 894
 			  ifconfig_local,
... ...
@@ -910,6 +896,19 @@ do_ifconfig (struct tuntap *tt,
910 910
 			  tun_mtu
911 911
 			  );
912 912
       else
913
+	if ( tt->topology == TOP_SUBNET )
914
+	{
915
+	    argv_printf (&argv,
916
+			  "%s %s %s %s mtu %d netmask %s up -link0",
917
+			  IFCONFIG_PATH,
918
+			  actual,
919
+			  ifconfig_local,
920
+			  ifconfig_local,
921
+			  tun_mtu,
922
+			  ifconfig_remote_netmask
923
+			  );
924
+	}
925
+      else
913 926
 	argv_printf (&argv,
914 927
 			  "%s %s %s netmask %s mtu %d broadcast %s link0",
915 928
 			  IFCONFIG_PATH,
... ...
@@ -1959,10 +1958,6 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len)
1959 1959
 
1960 1960
 #elif defined(TARGET_OPENBSD)
1961 1961
 
1962
-#if !defined(HAVE_READV) || !defined(HAVE_WRITEV)
1963
-#error openbsd build requires readv & writev library functions
1964
-#endif
1965
-
1966 1962
 /*
1967 1963
  * OpenBSD has a slightly incompatible TUN device from
1968 1964
  * the rest of the world, in that it prepends a
... ...
@@ -2006,15 +2001,26 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
2006 2006
     }
2007 2007
 }
2008 2008
 
2009
-/* the current way OpenVPN handles tun devices on OpenBSD leads to
2010
- * lingering tunX interfaces after close -> for a full cleanup, they
2011
- * need to be explicitely destroyed
2009
+/* tun(4): "If the device was created by opening /dev/tunN, it will be
2010
+ *          automatically destroyed.  Devices created via ifconfig(8) are
2011
+ *          only marked as not running and traffic will be dropped
2012
+ *          returning EHOSTDOWN."
2013
+ * --> no special handling should be needed - *but* OpenBSD is misbehaving
2014
+ * here: if the interface was put in tap mode ("ifconfig tunN link0"), it
2015
+ * *will* stay around, and needs to be cleaned up manually
2012 2016
  */
2013 2017
 
2014 2018
 void
2015 2019
 close_tun (struct tuntap* tt)
2016 2020
 {
2017
-  if (tt)
2021
+  /* only *TAP* devices need destroying, tun devices auto-self-destruct
2022
+   */
2023
+  if (tt && tt->type == DEV_TYPE_TUN )
2024
+    {
2025
+      close_tun_generic (tt);
2026
+      free(tt);
2027
+    }
2028
+  else if (tt)
2018 2029
     {
2019 2030
       struct gc_arena gc = gc_new ();
2020 2031
       struct argv argv;
... ...
@@ -283,7 +283,7 @@ ifconfig_order(void)
283 283
 #elif defined(TARGET_SOLARIS)
284 284
   return IFCONFIG_AFTER_TUN_OPEN;
285 285
 #elif defined(TARGET_OPENBSD)
286
-  return IFCONFIG_BEFORE_TUN_OPEN;
286
+  return IFCONFIG_AFTER_TUN_OPEN;
287 287
 #elif defined(TARGET_DARWIN)
288 288
   return IFCONFIG_AFTER_TUN_OPEN;
289 289
 #elif defined(TARGET_NETBSD)