From 790b812014708aa21a12743d5a73dfc4fc29d938 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Tue, 7 Oct 2025 18:08:18 +0200 Subject: [PATCH] Allow route_ipv6_match_host to be used outside of route.c Also adjust style a bit to C99 Change-Id: Ief1495b52ea81cac35d78e40264372d3869423f1 Signed-off-by: Arne Schwabe Acked-by: Gert Doering 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 --- src/openvpn/route.c | 24 ++++++++++-------------- src/openvpn/route.h | 13 +++++++++++++ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 05a0c8f43..00447945e 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -710,25 +710,20 @@ init_route_list(struct route_list *rl, const struct route_option_list *opt, 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 @@ route_ipv6_match_host(const struct route_ipv6 *r6, const struct in6_addr *host) 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 @@ init_route_ipv6_list(struct route_ipv6_list *rl6, const struct route_ipv6_option * 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 c5006aec3..54fa137a2 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -426,4 +426,17 @@ route_did_redirect_default_gateway(const struct route_list *rl) 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 */ -- 2.47.3