[Openvpn-devel,v5] Allow route_ipv6_match_host to be used outside of route.c

Message ID 20251007160826.4614-1-gert@greenie.muc.de
State New
Headers show
Series [Openvpn-devel,v5] Allow route_ipv6_match_host to be used outside of route.c | expand

Commit Message

Gert Doering Oct. 7, 2025, 4:08 p.m. UTC
From: Arne Schwabe <arne@rfc2549.org>

Also adjust style a bit to C99

Change-Id: Ief1495b52ea81cac35d78e40264372d3869423f1
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1191
---

This change was reviewed on Gerrit and approved by at least one
developer. I request to merge it to master.

Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1191
This mail reflects revision 5 of this Change.

Acked-by according to Gerrit (reflected above):
Gert Doering <gert@greenie.muc.de>

Comments

Gert Doering Oct. 7, 2025, 4:41 p.m. UTC | #1
I do remember this function! ;-)

Tested with the lone caller...

2025-10-07 18:05:47 ROUTE6: 2607:fc50:1001:5200::1:8/111 overlaps IPv6 remote 2607:fc50:1001:5200::4, adding host route to VPN endpoint

.. still works, for "match" and "no match" and "slightly odd netbits".

At some point we might see if we can move this "somewhere" (socket_util.c?)
that is suitable for an unit test, and add one...  but not today.

Your patch has been applied to the master branch.

commit 790b812014708aa21a12743d5a73dfc4fc29d938
Author: Arne Schwabe
Date:   Tue Oct 7 18:08:18 2025 +0200

     Allow route_ipv6_match_host to be used outside of route.c

     Signed-off-by: Arne Schwabe <arne@rfc2549.org>
     Acked-by: Gert Doering <gert@greenie.muc.de>
     Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1191
     Message-Id: <20251007160826.4614-1-gert@greenie.muc.de>
     URL: https://sourceforge.net/p/openvpn/mailman/message/59243387/
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering

Patch

diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index 05a0c8f..0044794 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -710,25 +710,20 @@ 
     return ret;
 }
 
-/* check whether an IPv6 host address is covered by a given route_ipv6
- * (not the most beautiful implementation in the world, but portable and
- * "good enough")
- */
-static bool
-route_ipv6_match_host(const struct route_ipv6 *r6, const struct in6_addr *host)
+bool
+ipv6_net_contains_host(const struct in6_addr *network, unsigned int bits, const struct in6_addr *host)
 {
-    unsigned int bits = r6->netbits;
-    int i;
-    unsigned int mask;
-
+    /* not the most beautiful implementation in the world, but portable and
+     * "good enough" */
     if (bits > 128)
     {
         return false;
     }
 
+    int i;
     for (i = 0; bits >= 8; i++, bits -= 8)
     {
-        if (r6->network.s6_addr[i] != host->s6_addr[i])
+        if (network->s6_addr[i] != host->s6_addr[i])
         {
             return false;
         }
@@ -739,9 +734,9 @@ 
         return true;
     }
 
-    mask = 0xff << (8 - bits);
+    unsigned int mask = 0xff << (8 - bits);
 
-    if ((r6->network.s6_addr[i] & mask) == (host->s6_addr[i] & mask))
+    if ((network->s6_addr[i] & mask) == (host->s6_addr[i] & mask))
     {
         return true;
     }
@@ -830,7 +825,8 @@ 
                  * avoiding routing loops, so ignore this part and let
                  * need_remote_ipv6_route always evaluate to false
                  */
-                if (remote_host_ipv6 && route_ipv6_match_host(r6, remote_host_ipv6))
+                if (remote_host_ipv6
+                    && ipv6_net_contains_host(&r6->network, r6->netbits, remote_host_ipv6))
                 {
                     need_remote_ipv6_route = true;
                     msg(D_ROUTE,
diff --git a/src/openvpn/route.h b/src/openvpn/route.h
index c5006ae..54fa137 100644
--- a/src/openvpn/route.h
+++ b/src/openvpn/route.h
@@ -426,4 +426,17 @@ 
     return rl && BOOL_CAST(rl->iflags & RL_DID_REDIRECT_DEFAULT_GATEWAY);
 }
 
+
+/**
+ * check whether an IPv6 host address is covered by a given network/bits
+ * @param network the network address
+ * @param bits the network mask
+ * @param host the host address to be checked if it is contained by the network
+ *
+ * @return true if the host address is covered by the network with the given
+ *         network mask by bits
+ */
+bool
+ipv6_net_contains_host(const struct in6_addr *network, unsigned int bits, const struct in6_addr *host);
+
 #endif /* ifndef ROUTE_H */