From: George Tsiamasiotis Date: Tue, 17 Jun 2025 12:30:41 +0000 (+0300) Subject: resolved: Tweak link-local addresses relevancy X-Git-Tag: v258-rc1~297 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c60d2a626b88aec24e6f029f799b6631c1aaeee2;p=thirdparty%2Fsystemd.git resolved: Tweak link-local addresses relevancy We now consider link-local addresses routable when we have configured unicast link-local dns servers. This allows creating the DNS scope, even when the interface doesn't get a routable address. --- diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index 6d79d1709c5..94b7e3df164 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -674,14 +674,35 @@ int link_update(Link *l) { return 0; } +static bool link_has_link_local_dns(Link *l, int family) { + + /* Check if the link has a link-local dns server for the specified family */ + + LIST_FOREACH(servers, s, l->dns_servers) + if ((family == AF_UNSPEC || s->family == family) && + in_addr_is_link_local(s->family, &s->address)) + return true; + + return false; +} + bool link_relevant(Link *l, int family, bool local_multicast) { + bool allow_link_local; + assert(l); - /* A link is relevant for local multicast traffic if it isn't a loopback device, has a link - * beat, can do multicast and has at least one link-local (or better) IP address. - * - * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at - * least one routable address. */ + /* + * A link is relevant if: + * - it isn't a loopback device + * - has a link beat + * - for multicast traffic: + * - can do multicast + * - has at least one link-local (or better) IP address. + * - for non-multicast traffic: + * - has at least one address that must be: + * - At least link-local, if using a link-local dns server to this interface. + * - Better than link-local. + */ if ((l->flags & (IFF_LOOPBACK | IFF_DORMANT)) != 0) return false; @@ -700,8 +721,11 @@ bool link_relevant(Link *l, int family, bool local_multicast) { !IN_SET(l->networkd_operstate, LINK_OPERSTATE_DEGRADED_CARRIER, LINK_OPERSTATE_DEGRADED, LINK_OPERSTATE_ROUTABLE)) return false; + allow_link_local = local_multicast || link_has_link_local_dns(l, family); + LIST_FOREACH(addresses, a, l->addresses) - if ((family == AF_UNSPEC || a->family == family) && link_address_relevant(a, local_multicast)) + if ((family == AF_UNSPEC || a->family == family) && + link_address_relevant(a, allow_link_local)) return true; return false; @@ -1179,13 +1203,13 @@ int link_address_update_rtnl(LinkAddress *a, sd_netlink_message *m) { return 0; } -bool link_address_relevant(LinkAddress *a, bool local_multicast) { +bool link_address_relevant(LinkAddress *a, bool allow_link_local) { assert(a); if (a->flags & (IFA_F_DEPRECATED|IFA_F_TENTATIVE)) return false; - if (a->scope >= (local_multicast ? RT_SCOPE_HOST : RT_SCOPE_LINK)) + if (a->scope >= (allow_link_local ? RT_SCOPE_HOST : RT_SCOPE_LINK)) return false; return true; diff --git a/src/resolve/resolved-link.h b/src/resolve/resolved-link.h index 3f9002fa107..71f92039d57 100644 --- a/src/resolve/resolved-link.h +++ b/src/resolve/resolved-link.h @@ -114,7 +114,7 @@ int link_address_new(Link *l, const union in_addr_union *in_addr_broadcast); LinkAddress *link_address_free(LinkAddress *a); int link_address_update_rtnl(LinkAddress *a, sd_netlink_message *m); -bool link_address_relevant(LinkAddress *l, bool local_multicast); +bool link_address_relevant(LinkAddress *l, bool allow_link_local); void link_address_add_rrs(LinkAddress *a, bool force_remove); bool link_negative_trust_anchor_lookup(Link *l, const char *name);