AIX only has TAP interfaces, so always use gateway address as next hop,
not interface name.
AIX route works much more reliable if passed netbits than netmask - do so
(introducing a new helper function netmask_to_netbits2())
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <1402409073-54067216-4-git-send-email-gert@greenie.muc.de>
URL: http://article.gmane.org/gmane.network.openvpn.devel/8785
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -1482,6 +1482,17 @@ add_route (struct route_ipv4 *r, |
1482 | 1482 |
argv_msg (D_ROUTE, &argv); |
1483 | 1483 |
status = openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route add command failed"); |
1484 | 1484 |
|
1485 |
+#elif defined(TARGET_AIX) |
|
1486 |
+ |
|
1487 |
+ { |
|
1488 |
+ int netbits = netmask_to_netbits2(r->netmask); |
|
1489 |
+ argv_printf (&argv, "%s add -net %s/%d %s", |
|
1490 |
+ ROUTE_PATH, |
|
1491 |
+ network, netbits, gateway); |
|
1492 |
+ argv_msg (D_ROUTE, &argv); |
|
1493 |
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: AIX route add command failed"); |
|
1494 |
+ } |
|
1495 |
+ |
|
1485 | 1496 |
#else |
1486 | 1497 |
msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script"); |
1487 | 1498 |
#endif |
... | ... |
@@ -1701,6 +1712,14 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla |
1701 | 1701 |
argv_msg (D_ROUTE, &argv); |
1702 | 1702 |
status = openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route add -inet6 command failed"); |
1703 | 1703 |
|
1704 |
+#elif defined(TARGET_AIX) |
|
1705 |
+ |
|
1706 |
+ argv_printf (&argv, "%s add -inet6 %s/%d %s", |
|
1707 |
+ ROUTE_PATH, |
|
1708 |
+ network, r6->netbits, gateway); |
|
1709 |
+ argv_msg (D_ROUTE, &argv); |
|
1710 |
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: AIX route add command failed"); |
|
1711 |
+ |
|
1704 | 1712 |
#else |
1705 | 1713 |
msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-up script"); |
1706 | 1714 |
#endif |
... | ... |
@@ -1859,8 +1878,21 @@ delete_route (struct route_ipv4 *r, |
1859 | 1859 |
|
1860 | 1860 |
argv_msg (D_ROUTE, &argv); |
1861 | 1861 |
openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route delete command failed"); |
1862 |
+ |
|
1862 | 1863 |
#elif defined(TARGET_ANDROID) |
1863 | 1864 |
msg (M_NONFATAL, "Sorry, deleting routes on Android is not possible. The VpnService API allows routes to be set on connect only."); |
1865 |
+ |
|
1866 |
+#elif defined(TARGET_AIX) |
|
1867 |
+ |
|
1868 |
+ { |
|
1869 |
+ int netbits = netmask_to_netbits2(r->netmask); |
|
1870 |
+ argv_printf (&argv, "%s delete -net %s/%d %s", |
|
1871 |
+ ROUTE_PATH, |
|
1872 |
+ network, netbits, gateway); |
|
1873 |
+ argv_msg (D_ROUTE, &argv); |
|
1874 |
+ openvpn_execve_check (&argv, es, 0, "ERROR: AIX route delete command failed"); |
|
1875 |
+ } |
|
1876 |
+ |
|
1864 | 1877 |
#else |
1865 | 1878 |
msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script"); |
1866 | 1879 |
#endif |
... | ... |
@@ -2031,6 +2063,14 @@ delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigne |
2031 | 2031 |
argv_msg (D_ROUTE, &argv); |
2032 | 2032 |
openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route delete -inet6 command failed"); |
2033 | 2033 |
|
2034 |
+#elif defined(TARGET_AIX) |
|
2035 |
+ |
|
2036 |
+ argv_printf (&argv, "%s delete -inet6 %s/%d %s", |
|
2037 |
+ ROUTE_PATH, |
|
2038 |
+ network, r6->netbits, gateway); |
|
2039 |
+ argv_msg (D_ROUTE, &argv); |
|
2040 |
+ openvpn_execve_check (&argv, es, 0, "ERROR: AIX route add command failed"); |
|
2041 |
+ |
|
2034 | 2042 |
#else |
2035 | 2043 |
msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-down script"); |
2036 | 2044 |
#endif |
... | ... |
@@ -2868,6 +2908,26 @@ netmask_to_netbits (const in_addr_t network, const in_addr_t netmask, int *netbi |
2868 | 2868 |
return false; |
2869 | 2869 |
} |
2870 | 2870 |
|
2871 |
+/* similar to netmask_to_netbits(), but don't mess with base address |
|
2872 |
+ * etc., just convert to netbits - non-mappable masks are returned as "-1" |
|
2873 |
+ */ |
|
2874 |
+int netmask_to_netbits2 (in_addr_t netmask) |
|
2875 |
+{ |
|
2876 |
+ int i; |
|
2877 |
+ const int addrlen = sizeof (in_addr_t) * 8; |
|
2878 |
+ |
|
2879 |
+ for (i = 0; i <= addrlen; ++i) |
|
2880 |
+ { |
|
2881 |
+ in_addr_t mask = netbits_to_netmask (i); |
|
2882 |
+ if (mask == netmask) |
|
2883 |
+ { |
|
2884 |
+ return i; |
|
2885 |
+ } |
|
2886 |
+ } |
|
2887 |
+ return -1; |
|
2888 |
+} |
|
2889 |
+ |
|
2890 |
+ |
|
2871 | 2891 |
/* |
2872 | 2892 |
* get_bypass_addresses() is used by the redirect-gateway bypass-x |
2873 | 2893 |
* functions to build a route bypass to selected DHCP/DNS servers, |