[Openvpn-devel] implement net_gateway_ipv6 for --route-ipv6

Message ID 20211123083758.15933-1-fkooman@tuxed.net
State New
Headers show
Series
  • [Openvpn-devel] implement net_gateway_ipv6 for --route-ipv6
Related show

Commit Message

François Kooman Nov. 23, 2021, 8:37 a.m.
fix for #1161

Signed-off-by: François Kooman <fkooman@tuxed.net>
---
 src/openvpn/options.c |  2 +-
 src/openvpn/route.c   | 67 +++++++++++++++++++++++++++++++++++++++++--
 src/openvpn/route.h   |  1 +
 3 files changed, 67 insertions(+), 3 deletions(-)

Comments

Gert Doering Nov. 23, 2021, 8:59 a.m. | #1
Hi,

On Tue, Nov 23, 2021 at 09:37:58AM +0100, François Kooman wrote:
> fix for #1161
> 
> Signed-off-by: François Kooman <fkooman@tuxed.net>

Is this a v2, or a re-sent "because nobody picked it up"?

The commit message *could* have a few more words, though :-) - and
the Ticket number wants to be "Trac: #1161".  But this is minor, and
I can handle this on the fly, if the rest is reviewed and ACKed
(not doing this right now, just clarifying the v1 vs. v2 status).

gert
François Kooman Nov. 23, 2021, 9:05 a.m. | #2
On 23.11.21 09:59, Gert Doering wrote:
> Hi,

Hi Gert,

> Is this a v2, or a re-sent "because nobody picked it up"?

Well, if you consider the PR on GitHub [PR#160] the v1, then yes, this 
is v2.

> The commit message *could* have a few more words, though :-) - and
> the Ticket number wants to be "Trac: #1161".  But this is minor, and
> I can handle this on the fly, if the rest is reviewed and ACKed
> (not doing this right now, just clarifying the v1 vs. v2 status).

I could fix that for a v2 (or v3) as well.

Regards,
François
Gert Doering Nov. 23, 2021, 9:11 a.m. | #3
Hi,

On Tue, Nov 23, 2021 at 10:05:16AM +0100, François Kooman wrote:
> > Is this a v2, or a re-sent "because nobody picked it up"?
> 
> Well, if you consider the PR on GitHub [PR#160] the v1, then yes, this 
> is v2.

Oh.  I really need more coffee.  I remembered I had seen a mail about
this, but my mailbox tells me it was only the GH PR notificaiton
(we decided at the hackathon that we want to be a bit more open about
GH PRs, and now I'm even more confused about "where have I seen 
this before?" :-) )

So, yeah, thanks for sending the patch to the list, so it's in patchwork
now and will be properly tracked there.

Sending a v2 for the commit message improvements is not needed (I can fix
that on the fly).  If code changes are requested, the v2 for those can
then include the message fixes.

gert

Patch

diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index cc3d9fa0..3d530d7a 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -6558,7 +6558,7 @@  add_option(struct options *options,
                 msg(msglevel, "route-ipv6 parameter network/IP '%s' must be a valid address", p[1]);
                 goto err;
             }
-            if (p[2] && !ipv6_addr_safe(p[2]))
+            if (p[2] && !ipv6_addr_safe(p[2]) && !ipv6_is_special_addr(p[2]))
             {
                 msg(msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]);
                 goto err;
diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index fd1125ef..bd62b99a 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -287,6 +287,38 @@  get_special_addr(const struct route_list *rl,
     return false;
 }
 
+static bool
+ipv6_get_special_addr(const struct route_ipv6_list *rl,
+                 const char *string,
+                 struct in6_addr *out,
+                 bool *status)
+{
+    if (status)
+    {
+        *status = true;
+    }
+    if (!strcmp(string, "net_gateway_ipv6"))
+    {
+        if (rl)
+        {
+            if (rl->rgi6.flags & RGI_ADDR_DEFINED)
+            {
+                *out = rl->rgi6.gateway.addr_ipv6;
+            }
+            else
+            {
+                msg(M_INFO, PACKAGE_NAME " ROUTE: net_gateway_ipv6 undefined -- unable to get default gateway from system");
+                if (status)
+                {
+                    *status = false;
+                }
+            }
+        }
+        return true;
+    }
+    return false;
+}
+
 bool
 is_special_addr(const char *addr_str)
 {
@@ -300,6 +332,19 @@  is_special_addr(const char *addr_str)
     }
 }
 
+bool
+ipv6_is_special_addr(const char *addr_str)
+{
+    if (addr_str)
+    {
+        return ipv6_get_special_addr(NULL, addr_str, NULL, NULL);
+    }
+    else
+    {
+        return false;
+    }
+}
+
 static bool
 init_route(struct route_ipv4 *r,
            struct addrinfo **network_list,
@@ -438,6 +483,7 @@  init_route_ipv6(struct route_ipv6 *r6,
                 const struct route_ipv6_option *r6o,
                 const struct route_ipv6_list *rl6 )
 {
+    bool status;
     CLEAR(*r6);
 
     if (!get_ipv6_addr( r6o->prefix, &r6->network, &r6->netbits, M_WARN ))
@@ -448,9 +494,26 @@  init_route_ipv6(struct route_ipv6 *r6,
     /* gateway */
     if (is_route_parm_defined(r6o->gateway))
     {
-        if (inet_pton( AF_INET6, r6o->gateway, &r6->gateway ) != 1)
+        if (ipv6_get_special_addr(rl6, r6o->gateway, &r6->gateway, &status))
         {
-            msg( M_WARN, PACKAGE_NAME "ROUTE6: cannot parse gateway spec '%s'", r6o->gateway );
+            r6->metric = 1;
+#ifdef _WIN32
+            r6->adapter_index = rl6->rgi6.adapter_index;
+#else
+            r6->iface = rl6->rgi6.iface;
+#endif
+            r6->flags = RT_DEFINED | RT_METRIC_DEFINED;
+        }
+        else
+        {
+            if (inet_pton( AF_INET6, r6o->gateway, &r6->gateway ) != 1)
+            {
+                msg( M_WARN, PACKAGE_NAME "ROUTE6: cannot parse gateway spec '%s'", r6o->gateway );
+            }
+        }
+        if (!status)
+        {
+            goto fail;
         }
     }
     else if (rl6->spec_flags & RTSA_REMOTE_ENDPOINT)
diff --git a/src/openvpn/route.h b/src/openvpn/route.h
index dc448c74..bbb8d2f8 100644
--- a/src/openvpn/route.h
+++ b/src/openvpn/route.h
@@ -320,6 +320,7 @@  void setenv_routes(struct env_set *es, const struct route_list *rl);
 void setenv_routes_ipv6(struct env_set *es, const struct route_ipv6_list *rl6);
 
 bool is_special_addr(const char *addr_str);
+bool ipv6_is_special_addr(const char *addr_str);
 
 void get_default_gateway(struct route_gateway_info *rgi,
                          openvpn_net_ctx_t *ctx);