CentauriNetAS46307

Notes · RPKI

Exact-length ROAs

Every prefix I announce from AS46307 has its own ROA entry at exactly its own length, plus 2602:fb3c::/36 at maxLength 36 as a floor. That's the shape RFC 9319 recommends. I moved to it after a permissive ROA kept a new PoP's IPv6 dark for hours.

The old ROA

It was one entry: 2602:fb3c::/36, maxLength 48. RFC 6811 makes any /36 to /48 inside it Valid when AS46307 originates it, so a new PoP's /48 needed no registry step. It also let anyone forging a path ending in AS46307 validate any /48 in the /36.

fre0's dark IPv6

On 2026-09-24 I built fre0, my first PoP on a second provider, with no ROA entry for 2602:fb3c:13::/48. The session looked healthy, the provider's API showed all four IPv6 prefixes received and none filtered, and every health check passed. But its filter builder reads ROA prefixes literally and ignores maxLength, so the prefixes went no further. For hours:

  • 2602:fb3c:13::53, fre0's diagnostic nameserver, timed out.
  • bgp.tools showed 2602:fb3c:13::/48 missing from the global table. fre0's own bgp.tools session couldn't come up, because its source address is in that /48.
  • fre0's nameserver served 2 IPv6 queries to its siblings' 410 and 268, and 3,675 over IPv4.
  • Nothing alerted, because nothing was down.

One ROA, two readings

A validator reads an entry as a range up to maxLength. A literal filter builder reads only the prefix, so my old entry became a filter for exactly 2602:fb3c::/36, which I don't announce.

One ROA, read two ways Before: one entry, 2602:fb3c::/36 with maxLength 48. A validator reads the maxLength and finds 2602:fb3c:13::/48 Valid. A filter builder that ignores maxLength permits only the /36, so the /48 is filtered. After: 2602:fb3c::/36 at maxLength 36 as a floor, and one exact entry per announced prefix, such as 2602:fb3c:13::/48 at maxLength 48. Both readers permit 2602:fb3c:13::/48 by exact match. BEFORE: ONE ENTRY FOR THE WHOLE /36 2602:fb3c::/36 maxLength 48 ROV validator (RFC 6811) reads maxLength Literal filter builder ignores maxLength 2602:fb3c:13::/48 Valid: within /36 to /48 2602:fb3c:13::/48 Filtered: not the /36 AFTER: EXACT ENTRIES, PLUS A FLOOR 2602:fb3c::/36 maxLength 36, floor 2602:fb3c:13::/48 maxLength 48 and one exact entry per other prefix ROV validator (RFC 6811) reads maxLength Literal filter builder ignores maxLength 2602:fb3c:13::/48 Valid: exact match 2602:fb3c:13::/48 Permitted: exact match
Exact entries make the two readings agree. The floor makes anything else in the /36 Invalid.

Now both readings permit exactly what I announce, and anything unlisted in the /36 is Invalid.

Trade-offs

  • Each new PoP's /48 needs a ROA entry before it announces. ARIN's API is read-only for ROAs, so that's a step in ARIN Online.
  • A new entry takes minutes to hours to take effect, so I add it first.
  • ARIN's IRR Auto-Manager made the route6 objects for the ewr0 and ams0 /48s within minutes. No IRR step.
  • A forgotten entry is now RPKI-Invalid and dropped wherever ROV runs. Visibly broken beats silently missing.

Doing this yourself

  • Start with exact-length entries, plus your allocation at its own length as a floor.
  • Add the ROA before announcing, and check it from a router. In FRR:
show rpki prefix 2602:fb3c::/36 46307
  • Ask a new upstream whether it builds filters from the IRR or the RPKI, and whether it reads maxLength.
  • Watch traffic per address family per PoP. Healthy IPv4 hid dark IPv6 for hours.

Sources