]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
route: handle default gateway (net_gateway) and nexthop towards VPN server separately
authorMarco Baffo <marco@mandelbit.com>
Wed, 19 Nov 2025 11:40:35 +0000 (12:40 +0100)
committerGert Doering <gert@greenie.muc.de>
Wed, 19 Nov 2025 13:32:56 +0000 (14:32 +0100)
Right now there is the assumption that the gateway used for net_gateway is the same used to reach the VPN server.
However, these two gateways may be different (i.e. when there is a specific hostroute for the VPN server using a different nexthop).
For this reason we must adapt init_route_list() to fetch the two gateways separately.

Github: fixes OpenVPN/openvpn#890

Change-Id: I16d90221d0a75193035253817ff195f6da9dc0b3
Signed-off-by: Marco Baffo <marco@mandelbit.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1222
Message-Id: <20251119114041.17665-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg34529.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
src/openvpn/route.c
src/openvpn/route.h

index 7d988da14f7ba683b4cd075b051713913d2e61b8..770300a6a9c10c05faab5770c5e0efdb3568a3a5 100644 (file)
@@ -257,9 +257,9 @@ get_special_addr(const struct route_list *rl, const char *string, in_addr_t *out
     {
         if (rl)
         {
-            if (rl->rgi.flags & RGI_ADDR_DEFINED)
+            if (rl->ngi.flags & RGI_ADDR_DEFINED)
             {
-                *out = rl->rgi.gateway.addr;
+                *out = rl->ngi.gateway.addr;
             }
             else
             {
@@ -624,10 +624,10 @@ init_route_list(struct route_list *rl, const struct route_option_list *opt,
         rl->spec.flags |= RTSA_DEFAULT_METRIC;
     }
 
-    get_default_gateway(&rl->rgi, remote_host != IPV4_INVALID_ADDR ? remote_host : INADDR_ANY, ctx);
-    if (rl->rgi.flags & RGI_ADDR_DEFINED)
+    get_default_gateway(&rl->ngi, INADDR_ANY, ctx);
+    if (rl->ngi.flags & RGI_ADDR_DEFINED)
     {
-        setenv_route_addr(es, "net_gateway", rl->rgi.gateway.addr, -1);
+        setenv_route_addr(es, "net_gateway", rl->ngi.gateway.addr, -1);
 #if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
         print_default_gateway(D_ROUTE, &rl->rgi, NULL);
 #endif
@@ -637,6 +637,8 @@ init_route_list(struct route_list *rl, const struct route_option_list *opt,
         dmsg(D_ROUTE, "ROUTE: default_gateway=UNDEF");
     }
 
+    get_default_gateway(&rl->rgi, remote_host != IPV4_INVALID_ADDR ? remote_host : INADDR_ANY, ctx);
+
     if (rl->spec.flags & RTSA_REMOTE_HOST)
     {
         rl->spec.remote_host_local = test_local_addr(remote_host, &rl->rgi);
@@ -773,10 +775,10 @@ init_route_ipv6_list(struct route_ipv6_list *rl6, const struct route_ipv6_option
     msg(D_ROUTE, "GDG6: remote_host_ipv6=%s",
         remote_host_ipv6 ? print_in6_addr(*remote_host_ipv6, 0, &gc) : "n/a");
 
-    get_default_gateway_ipv6(&rl6->rgi6, remote_host_ipv6, ctx);
-    if (rl6->rgi6.flags & RGI_ADDR_DEFINED)
+    get_default_gateway_ipv6(&rl6->ngi6, NULL, ctx);
+    if (rl6->ngi6.flags & RGI_ADDR_DEFINED)
     {
-        setenv_str(es, "net_gateway_ipv6", print_in6_addr(rl6->rgi6.gateway.addr_ipv6, 0, &gc));
+        setenv_str(es, "net_gateway_ipv6", print_in6_addr(rl6->ngi6.gateway.addr_ipv6, 0, &gc));
 #if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
         print_default_gateway(D_ROUTE, NULL, &rl6->rgi6);
 #endif
@@ -786,6 +788,8 @@ init_route_ipv6_list(struct route_ipv6_list *rl6, const struct route_ipv6_option
         dmsg(D_ROUTE, "ROUTE6: default_gateway=UNDEF");
     }
 
+    get_default_gateway_ipv6(&rl6->rgi6, remote_host_ipv6, ctx);
+
     if (is_route_parm_defined(remote_endpoint))
     {
         if (inet_pton(AF_INET6, remote_endpoint, &rl6->remote_endpoint_ipv6) == 1)
index 54fa137a24caceea5d867ded1a395284da2dcb2c..3d19dbd4eb8386816e512e1deb190b7c10942702 100644 (file)
@@ -234,7 +234,8 @@ struct route_list
 
     struct route_special_addr spec;
     struct route_gateway_info rgi;
-    unsigned int flags; /* RG_x flags */
+    struct route_gateway_info ngi; /* net_gateway */
+    unsigned int flags;            /* RG_x flags */
     struct route_ipv4 *routes;
     struct gc_arena gc;
 };
@@ -249,7 +250,8 @@ struct route_ipv6_list
     int default_metric;
 
     struct route_ipv6_gateway_info rgi6;
-    unsigned int flags; /* RG_x flags, see route_option_list */
+    struct route_ipv6_gateway_info ngi6; /* net_gateway_ipv6 */
+    unsigned int flags;                  /* RG_x flags, see route_option_list */
     struct route_ipv6 *routes_ipv6;
     struct gc_arena gc;
 };