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>
... | ... |
@@ -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 |