From: Maria Matejka Date: Wed, 2 Jul 2025 14:40:34 +0000 (+0200) Subject: Socket: Warnings for link-local addresses without interfaces X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2737b9769caf0d93adf0bcd52f97ef751730ad0;p=thirdparty%2Fbird.git Socket: Warnings for link-local addresses without interfaces In certain corner cases (e.g. mixed global and link-local IPv6 address) the kernel fails to give us the interface ID. We log a warning for such a case before a possibly misleading error message is spit out by BGP. Also pass TCP interface information from parent to child on accept, if the interface is bound to that interface. --- diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index cc422ee1c..0a32865fd 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -429,7 +429,12 @@ sockaddr_read6(struct sockaddr_in6 *sa, ip_addr *a, struct iface **ifa, uint *po *a = ipa_from_in6(sa->sin6_addr); if (ifa && ipa_is_link_local(*a)) + { *ifa = if_find_by_index(sa->sin6_scope_id); + if (!*ifa) + log(L_WARN "SOCK: Failed to resolve interface ID %d of link-local address %I", + sa->sin6_scope_id, *a); + } } int @@ -1312,12 +1317,27 @@ sk_passive_connected(sock *s, int type) if (type == SK_TCP) { + struct iface *sifa = NULL, *difa = NULL; if ((getsockname(fd, &loc_sa.sa, &loc_sa_len) < 0) || - (sockaddr_read(&loc_sa, s->af, &t->saddr, &t->iface, &t->sport) < 0)) + (sockaddr_read(&loc_sa, s->af, &t->saddr, &sifa, &t->sport) < 0)) log(L_WARN "SOCK: Cannot get local IP address for TCP<"); - if (sockaddr_read(&rem_sa, s->af, &t->daddr, &t->iface, &t->dport) < 0) + if (sockaddr_read(&rem_sa, s->af, &t->daddr, &difa, &t->dport) < 0) log(L_WARN "SOCK: Cannot get remote IP address for TCP<"); + + if (sifa && difa && (sifa != difa)) + log(L_WARN "SOCK: Interface collision for TCP<, got src %I%J, dst %I%J", + t->saddr, sifa, t->daddr, difa); + + if (s->iface && sifa && (sifa != s->iface)) + log(L_WARN "SOCK: Interface collision for TCP<%J, got src %I%J", + s->iface, t->saddr, sifa); + + if (s->iface && difa && (difa != s->iface)) + log(L_WARN "SOCK: Interface collision for TCP<%J, got dst %I%J", + s->iface, t->daddr, difa); + + t->iface = s->iface ?: difa ?: sifa; } if (sk_setup(t) < 0)