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;
!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;
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;
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);