rpki local address + remote "<hostname>": AF mismatch reaches an assert in sk_open() (3.3.2)
(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. Thanks, --- 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
participants (1)
-
Hendrik Visage