Browse code

implement adding/deleting routes on AIX, for IPv4 and IPv6

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>

Gert Doering authored on 2014/06/10 23:04:32
Showing 1 changed files
... ...
@@ -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,