Browse code

Add tap driver initialization and ifconfig for AIX.

AIX is special... ifconfig only works if it can add the data to
the ODM right away, so setup a local enviromnment set that has
"ODMDIR=/etc/objrepos" in it (hard-coded, nobody changes that).

Only --dev tap or --dev tapNN are supported right now. AIX has no
tun driver (so tun mode would need to dynamically add/remove ethernet
headers to/from AIX).

Signed-off-by: Gert Doering <gd@medat.de>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <1402409073-54067216-3-git-send-email-gert@greenie.muc.de>
URL: http://article.gmane.org/gmane.network.openvpn.devel/8788
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Gert Doering authored on 2014/06/10 23:04:31
Showing 1 changed files
... ...
@@ -1194,6 +1194,43 @@ do_ifconfig (struct tuntap *tt,
1194 1194
 	  openvpn_execve_check (&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed");
1195 1195
 	}
1196 1196
 
1197
+#elif defined(TARGET_AIX)
1198
+      {
1199
+	/* AIX ifconfig will complain if it can't find ODM path in env */
1200
+	struct env_set *aix_es = env_set_create (NULL);
1201
+	env_set_add( aix_es, "ODMDIR=/etc/objrepos" );
1202
+
1203
+	if (tun)
1204
+	  msg(M_FATAL, "no tun support on AIX (canthappen)");
1205
+
1206
+	/* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */
1207
+	argv_printf (&argv,
1208
+		     "%s %s %s netmask %s mtu %d up",
1209
+			    IFCONFIG_PATH,
1210
+			    actual,
1211
+			    ifconfig_local,
1212
+			    ifconfig_remote_netmask,
1213
+			    tun_mtu
1214
+			    );
1215
+
1216
+	argv_msg (M_INFO, &argv);
1217
+	openvpn_execve_check (&argv, aix_es, S_FATAL, "AIX ifconfig failed");
1218
+	tt->did_ifconfig = true;
1219
+
1220
+	if ( do_ipv6 )
1221
+	  {
1222
+	    argv_printf (&argv,
1223
+				"%s %s inet6 %s/%d",
1224
+				IFCONFIG_PATH,
1225
+				actual,
1226
+				ifconfig_ipv6_local,
1227
+				tt->netbits_ipv6
1228
+				);
1229
+	    argv_msg (M_INFO, &argv);
1230
+	    openvpn_execve_check (&argv, aix_es, S_FATAL, "AIX ifconfig inet6 failed");
1231
+	  }
1232
+	env_set_destroy (aix_es);
1233
+      }
1197 1234
 #elif defined (WIN32)
1198 1235
       {
1199 1236
 	/*
... ...
@@ -2825,6 +2862,139 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len)
2825 2825
     return read (tt->fd, buf, len);
2826 2826
 }
2827 2827
 
2828
+#elif defined(TARGET_AIX)
2829
+
2830
+void
2831
+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
2832
+{
2833
+  char tunname[256];
2834
+  char dynamic_name[20];
2835
+  const char *p;
2836
+  struct argv argv;
2837
+
2838
+  if (tt->type == DEV_TYPE_NULL)
2839
+    {
2840
+      open_null (tt);
2841
+      return;
2842
+    }
2843
+
2844
+  if ( tt->type == DEV_TYPE_TUN)
2845
+    {
2846
+      msg(M_FATAL, "no support for 'tun' devices on AIX" );
2847
+    }
2848
+
2849
+  if ( strncmp( dev, "tap", 3 ) != 0 || dev_node )
2850
+    {
2851
+      msg(M_FATAL, "'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.", dev );
2852
+    }
2853
+
2854
+  if ( strcmp( dev, "tap" ) == 0 )		/* find first free tap dev */
2855
+    {						/* (= no /dev/tapN node) */
2856
+      int i;
2857
+      for (i=0; i<99; i++ )
2858
+	{
2859
+	  openvpn_snprintf (tunname, sizeof (tunname), "/dev/tap%d", i);
2860
+	  if ( access( tunname, F_OK ) < 0 && errno == ENOENT )
2861
+	    { break; }
2862
+	}
2863
+      if ( i >= 99 )
2864
+	msg( M_FATAL, "cannot find unused tap device" );
2865
+
2866
+      openvpn_snprintf( dynamic_name, sizeof(dynamic_name), "tap%d", i );
2867
+      dev = dynamic_name;
2868
+    }
2869
+  else						/* name given, sanity check */
2870
+    {
2871
+      /* ensure that dev name is "tap+<digits>" *only* */
2872
+      p = &dev[3];
2873
+      while( isdigit(*p) ) p++;
2874
+      if ( *p != '\0' )
2875
+	msg( M_FATAL, "TAP device name must be '--dev tapNNNN'" );
2876
+
2877
+      openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dev);
2878
+    }
2879
+
2880
+  /* pre-existing device?
2881
+   */
2882
+  if ( access( tunname, F_OK ) < 0 && errno == ENOENT )
2883
+    {
2884
+
2885
+      /* tunnel device must be created with 'ifconfig tapN create'
2886
+       */
2887
+      struct env_set *es = env_set_create (NULL);
2888
+      argv_init (&argv);
2889
+      argv_printf (&argv, "%s %s create", IFCONFIG_PATH, dev);
2890
+      argv_msg (M_INFO, &argv);
2891
+      env_set_add( es, "ODMDIR=/etc/objrepos" );
2892
+      openvpn_execve_check (&argv, es, S_FATAL, "AIX 'create tun interface' failed");
2893
+      env_set_destroy (es);
2894
+    }
2895
+  else
2896
+    {
2897
+      /* we didn't make it, we're not going to break it */
2898
+      tt->persistent_if = TRUE;
2899
+    }
2900
+
2901
+  if ((tt->fd = open (tunname, O_RDWR)) < 0)
2902
+    {
2903
+      msg (M_ERR, "Cannot open TAP device '%s'", tunname);
2904
+    }
2905
+
2906
+  set_nonblock (tt->fd);
2907
+  set_cloexec (tt->fd); /* don't pass fd to scripts */
2908
+  msg (M_INFO, "TUN/TAP device %s opened", tunname);
2909
+
2910
+  /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
2911
+  tt->actual_name = string_alloc(dev, NULL);
2912
+}
2913
+
2914
+/* tap devices need to be manually destroyed on AIX
2915
+ */
2916
+void
2917
+close_tun (struct tuntap* tt)
2918
+{
2919
+  struct gc_arena gc = gc_new ();
2920
+  struct argv argv;
2921
+  struct env_set *es = env_set_create (NULL);
2922
+
2923
+  if (!tt) return;
2924
+
2925
+  /* persistent devices need IP address unconfig, others need destroyal
2926
+   */
2927
+  argv_init (&argv);
2928
+
2929
+  if (tt->persistent_if)
2930
+    {
2931
+      argv_printf (&argv, "%s %s 0.0.0.0 down",
2932
+                          IFCONFIG_PATH, tt->actual_name);
2933
+    }
2934
+  else
2935
+    {
2936
+      argv_printf (&argv, "%s %s destroy",
2937
+                          IFCONFIG_PATH, tt->actual_name);
2938
+    }
2939
+
2940
+  close_tun_generic (tt);
2941
+  argv_msg (M_INFO, &argv);
2942
+  env_set_add( es, "ODMDIR=/etc/objrepos" );
2943
+  openvpn_execve_check (&argv, es, 0, "AIX 'destroy tap interface' failed (non-critical)");
2944
+
2945
+  free(tt);
2946
+  env_set_destroy (es);
2947
+}
2948
+
2949
+int
2950
+write_tun (struct tuntap* tt, uint8_t *buf, int len)
2951
+{
2952
+    return write (tt->fd, buf, len);
2953
+}
2954
+
2955
+int
2956
+read_tun (struct tuntap* tt, uint8_t *buf, int len)
2957
+{
2958
+    return read (tt->fd, buf, len);
2959
+}
2960
+
2828 2961
 #elif defined(WIN32)
2829 2962
 
2830 2963
 int