[Openvpn-devel] Haiku: Route VPN networks through tunnel interface

Message ID 20260723105518.2363-1-haiku-os@quietcode.org
State New
Headers
Series [Openvpn-devel] Haiku: Route VPN networks through tunnel interface |

Commit Message

Andreas Just July 23, 2026, 10:55 a.m. UTC
  The Haiku IPv4 route implementation always passes rgi->iface to route(8).
That interface describes the pre-VPN default gateway, so ordinary VPN
routes are attached to the physical interface even when their gateway is
the tunnel peer.

Use the recorded physical interface only when the route gateway matches
the recorded pre-VPN default gateway. Use the actual tunnel interface for
other IPv4 VPN routes.

Apply the same interface selection to route addition and deletion.

Signed-off-by: Andreas Just <haiku-os@quietcode.org>
---
 src/openvpn/route.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)
  

Patch

diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index 81ce867..e1d00f4 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -1477,6 +1477,23 @@  is_on_link(const int is_local_route, const unsigned int flags, const struct rout
 }
 #endif
 
+#if defined(TARGET_HAIKU)
+static const char *
+haiku_route_interface(const struct route_ipv4 *r, const struct tuntap *tt,
+                      const struct route_gateway_info *rgi)
+{
+    const unsigned int required_flags = RGI_ADDR_DEFINED | RGI_IFACE_DEFINED;
+
+    if (rgi != NULL && (rgi->flags & required_flags) == required_flags
+        && r->gateway == rgi->gateway.addr)
+    {
+        return rgi->iface;
+    }
+
+    return tt->actual_name;
+}
+#endif
+
 bool
 add_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags,
           const struct route_gateway_info *rgi, /* may be NULL */
@@ -1733,8 +1750,8 @@  add_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags,
 #elif defined(TARGET_HAIKU)
 
     /* ex: route add /dev/net/ipro1000/0 0.0.0.0 gw 192.168.1.1 netmask 128.0.0.0 */
-    argv_printf(&argv, "%s add %s inet %s gw %s netmask %s", ROUTE_PATH, rgi->iface, network,
-                gateway, netmask);
+    argv_printf(&argv, "%s add %s inet %s gw %s netmask %s", ROUTE_PATH,
+                haiku_route_interface(r, tt, rgi), network, gateway, netmask);
     argv_msg(D_ROUTE, &argv);
     bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: Haiku inet route add command failed");
     status = ret ? RTA_SUCCESS : RTA_ERROR;
@@ -2176,8 +2193,8 @@  delete_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags,
 #elif defined(TARGET_HAIKU)
 
     /* ex: route delete /dev/net/ipro1000/0 inet 192.168.0.0 gw 192.168.1.1 netmask 255.255.0.0 */
-    argv_printf(&argv, "%s delete %s inet %s gw %s netmask %s", ROUTE_PATH, rgi->iface, network,
-                gateway, netmask);
+    argv_printf(&argv, "%s delete %s inet %s gw %s netmask %s", ROUTE_PATH,
+                haiku_route_interface(r, tt, rgi), network, gateway, netmask);
     argv_msg(D_ROUTE, &argv);
     openvpn_execve_check(&argv, es, 0, "ERROR: Haiku inet route delete command failed");