(Claude report on another crash experienced on a greenfields BIRD3 deployment):
Hello,
On BIRD 3.3.2, an RPKI cache configured by name with a local address of the other address family logs an assertion at startup and then simply never connects:
bird: Assertion 'ipa_zero(s->saddr) || ipa_zero(s->daddr) || (ipa_is_ip4(s->saddr) == ipa_is_ip4(s->daddr))' failed at sysdep/unix/io.c:1766
Config (four caches, all by name, all with the same IPv4 local address = our loopback; two of the four produced the assertion, one each at two consecutive starts):
protocol rpki rpki_3_rtr_rpki_cloudflare_com {
roa4 { table roa_v4; };
roa6 { table roa_v6; };
remote "rtr.rpki.cloudflare.com" port 8282;
local address 102.205.240.1;
refresh 300;
retry 600;
expire 7200;
transport tcp;
}
Cause, reading 3.3.2: rpki_tr_open() (proto/rpki/transport.c) sets sk->saddr = cf->local_ip first, and only then resolves the name if cf->ip is unset. rpki_hostname_autoresolv() asks getaddrinfo() with .ai_family = AF_UNSPEC and takes res->ai_addr, i.e. whichever family the resolver happens to return first, without consulting cf->local_ip. If that is the other family, sk_open() is reached with mismatched saddr/daddr. In a release build the ASSERT only logs (lib/birdlib.h:270), and af is then derived as (ipa_is_ip4(saddr) || ipa_is_ip4(daddr)) ? AF_INET : AF_INET6, so the socket cannot work — with no error message that points at the cause.
Two things would make this diagnosable:
pass the family as a hint when it is known:
.ai_family = ipa_zero(cf->local_ip) ? AF_UNSPEC :
(ipa_is_ip4(cf->local_ip) ? AF_INET : AF_INET6),
which is also what an operator means by pinning a source address;
if they still disagree, log(L_ERR "%s: local address %I and resolved %I are different address families", …) and return RPKI_TR_ERROR instead of falling into the assert.
A related nicety: rpki_hostname_autoresolv() uses only the first addrinfo, so a dual-stacked cache is effectively "whatever the resolver ordered first" even without a local address. An explicit per-protocol family selector would remove the guesswork.
Dropping local address from all four rpki protocols was enough for us; the pin was never a requirement on our side.
Environment: bird3 3.3.2 from the BIRD Debian repository, amd64, Devuan 6 (trixie-equivalent), kernel 7.0.14-4-pve, KVM guest.
Hendrik Visage
Director/Owner
HeViS.Co Systems t/a Envisage Cloud SolutionsAS213481
hvisage@hevis.co.za
GSM/SMS/Signal: +27-84-612-5345
InstantMessenger: https://t.me/hvisage