From: Yu Watanabe Date: Mon, 12 Jul 2021 06:46:44 +0000 (+0900) Subject: network: also check addresses when determine a gateway address is reachable or not X-Git-Tag: v250-rc1~958^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=11046cea1414c70b5d7aab37ea88d5a839cbd209;p=thirdparty%2Fsystemd.git network: also check addresses when determine a gateway address is reachable or not Fixes #20201. --- diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 7b36b481419..0ab4419eba9 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -746,6 +746,26 @@ static bool route_address_is_reachable(const Route *route, int family, const uni FAMILY_ADDRESS_SIZE(family) * 8) > 0; } +static bool prefix_route_address_is_reachable(const Address *a, int family, const union in_addr_union *address) { + assert(a); + assert(IN_SET(family, AF_INET, AF_INET6)); + assert(address); + + if (a->family != family) + return false; + if (FLAGS_SET(a->flags, IFA_F_NOPREFIXROUTE)) + return false; + if (in_addr_is_set(a->family, &a->in_addr_peer)) + return false; + + return in_addr_prefix_intersect( + family, + &a->in_addr, + a->prefixlen, + address, + FAMILY_ADDRESS_SIZE(family) * 8) > 0; +} + bool manager_address_is_reachable(Manager *manager, int family, const union in_addr_union *address) { Link *link; @@ -764,6 +784,20 @@ bool manager_address_is_reachable(Manager *manager, int family, const union in_a return true; } + /* If we do not manage foreign routes, then there may exist a prefix route we do not know, + * which was created on configuring an address. Hence, also check the addresses. */ + if (!manager->manage_foreign_routes) + HASHMAP_FOREACH(link, manager->links_by_index) { + Address *a; + + SET_FOREACH(a, link->addresses) + if (prefix_route_address_is_reachable(a, family, address)) + return true; + SET_FOREACH(a, link->addresses_foreign) + if (prefix_route_address_is_reachable(a, family, address)) + return true; + } + return false; }