What is this?
A daily-refreshed measurement of how every Serbian autonomous system that announces IPv6 prefixes treats ICMPv6, RPKI, and ASPA. Each row in the summary carries small badges next to the operator name:
ICMPv6 / RFC 4890
- RFC 4890 ✓ - the active Type 2 test definitively proved the destination accepts and acts on a forged ICMPv6 Packet-Too-Big from us. PMTUD works toward this network.
- RFC 4890 ✗ - either the active Type 2 test proved the destination did not act on a forged Packet-Too-Big, or the path is provably broken (small Echo passes but 1500-byte Echo with DF silently fails - a clear case of someone on the route dropping Type 2). RFC 4890 (Recommendations for Filtering ICMPv6 Messages in Firewalls) explicitly says Type 2 must be permitted. Networks that drop it break PMTUD for every IPv6 user.
- (no badge) - we couldn't reach a definitive verdict.
RPKI ROA coverage (per IPv6 prefix)
- RPKI ✓ N/M - every announced prefix
is covered by a Validated ROA Payload (VRP) whose origin AS matches and whose
maxLengthpermits the announced length. - RPKI ⚠ N/M - some prefixes are valid, others have no covering ROA yet (partial rollout).
- RPKI ✗ - at least one announced prefix is RPKI-invalid (wrong origin or maxLength too short).
- RPKI - - the AS has not signed any of its prefixes.
ASPA (RFC 9774)
- ASPA ✓ - the AS has published an ASPA record listing the upstream provider ASes that may propagate its routes (hover the badge for the provider list).
- ASPA - - the AS has not yet published an ASPA record. ASPA is brand-new (RFC 9774, 2024); the yellow colour reflects an opportunity rather than a violation.
Address space (RIPE inet6num status)
- PA - Provider Aggregatable space (allocated by an upstream / sub-allocated to the holder).
- PI - Provider Independent space (the holder received their own allocation directly from the RIR).
- mixed - the AS holds both PA and PI prefixes.
What is this measurement?
This site is a continuously-updated, two-vantage-point measurement of how every
Serbian autonomous system that announces IPv6 prefixes treats ICMPv6
- specifically Echo Request/Reply (the ping6 primitive),
Time-Exceeded (used by traceroute), Packet-Too-Big (the foundation of Path-MTU
Discovery on IPv6), and Destination-Unreachable.
ICMPv6 is not optional in IPv6 the way ICMP often is in IPv4 - PMTUD,
Neighbor Discovery, and a number of error semantics depend on specific ICMPv6
types being permitted end-to-end. So testing how SRB networks actually treat
ICMPv6 is genuinely useful, both for operators tuning their ACLs and for
end-users diagnosing weird connectivity.
Why this matters (the engineering motivation)
- Echo Request/Reply (Types 128 / 129) - the basic
ping6. Operators sometimes block this thinking it improves "security"; in practice it just makes user-side diagnostics harder. - Packet Too Big (Type 2) - required for IPv6 PMTUD. Routers along a path generate Type 2 when a packet is too large for the next link's MTU. If anything between source and destination silently drops Type 2, senders never learn to shrink and TCP/UDP flows hang on certain sites. There is no IPv6 fragmentation in routers, so this is a hard requirement of the protocol.
- Time Exceeded (Type 3) - what makes traceroute work. If routers drop their own generated Time-Exceeded responses, paths look mysteriously broken even when forwarding is fine.
- Destination Unreachable (Type 1) - how a host signals "no process listening here". If filtered, applications fall back to long timeouts instead of failing fast.
RFC 4890 ("Recommendations for Filtering ICMPv6 Messages in Firewalls") is the authoritative guidance: drop the chatty multicast/discovery types if you must, but keep error reporting intact.
Vantage points
We measure from three distinct vantage points so the results show the destination AS' own behavior rather than a single transit's idiosyncrasy:
- SLO host (6connect) -
odin, Ljubljana (uplinks Telekom Slovenije + Xenya). Native IPv6, MTU 1500. - NL host (go6lab) -
console.go6lab.si, Apeldoorn, NL (transit Steffann-DC + Inter.link). Native IPv6, MTU 1500. - ITA host (Karsolink) -
karsolink.go6lab.si, Italy (Karsolink, transit via go6lab.si infrastructure). Native IPv6, MTU 1500.
If a destination is open from one vantage but blocked from the others, that almost always points to a transit-level filter rather than a destination policy.
Discovering pingable targets
Every announced SRB IPv6 ASN is enumerated from RIPEstat. For each, we try to find up to 10 addresses inside the AS' own announced prefix that respond to ICMPv6 Echo. Discovery is run from a single host (the orchestrator); the resulting target list is then synced to every measurement vantage so all vantages probe the same hosts. Sources, accumulated (no early-exit) and ranked by priority:
- Curated names: well-known country operator domains (curated
per country in
config/<cc>.json) and direct host overrides. - DNS NS / SOA / MX / SPF / DMARC on every plausible apex domain
(curated, slug-derived, whois-scraped). NS records typically point at the
operator's own authoritative name servers (which live inside their prefixes
and answer ICMPv6 reliably). SOA gives the primary master. MX gives mail
servers.
v=spf1TXT records are parsed forip6:literals and fora:/mx:/include:references. DMARCrua/rufURIs reveal report-handler domains. SPF in particular is a goldmine: operators routinely list every outbound mail relay's IPv6 there. - Holder-derived service hostnames: a broad set of generic
service prefixes (
www.,ns1..4.,mx1..4.,mail.,smtp.,vpn.,gw.,edge.,core.,pe.,git.,monitor.,lg., …) on names derived from the AS holder. - RIPE whois
-B: pulle-mail:,notify:, andorg:contacts from the AS object & its inline person/role/org objects. - PeeringDB:
websitefield from the network record; plus IX peer addresses fromnetixlanfor SRB exchanges. - RIPE Atlas: the public IPv6 addresses of Atlas probes located in SRB - verified to be inside an SRB ASN's announced prefix.
- IPv6 Hitlist Service (TUM Alcatraz): ~19 million globally responsive IPv6 addresses, streamed through a longest-prefix matcher against every SRB ASN's announced prefixes.
- Certificate Transparency (crt.sh), NTP Pool, Ookla speedtest server list: filtered to SRB-prefix matches.
- Path-hop promotion: any hop on a yarrp / traceroute path whose IP falls inside an SRB ASN's own prefix is re-tested with Echo and adopted as a router target. This usually surfaces internal PE / core routers that wouldn't be discoverable via DNS.
For each candidate, the AAAA must fall inside the ASN's announced prefix and ping6 must elicit an Echo Reply -- otherwise it's discarded. Per-AS targets are deduplicated by IP (highest-priority source wins) and the cap of 10 is enforced in 03_finalize. The full per-target list and per-vantage probe outcomes are shown on every per-ASN page.
For ASNs where every approach still finds no pingable target, that is itself a finding. The page distinguishes three cases based on how far our traceroutes get and whether any real IPv6 host was discoverable in the first place: transit only unreachable (traceroute never enters the AS), blocked in destination AS (traceroute enters and a real host was discovered, but every probed address is silent - typical for banks, ministries, air-traffic-control networks filtering at the AS edge), and no IPv6 implementation detected (traceroute enters the AS but no discovery source found any live host - typical for ASes that have an IPv6 allocation and announce it but have not yet deployed anything in it).
Source-code legend
Each target row in the per-ASN page carries a small badge identifying the discovery source. Hovering the badge shows the full description; quick reference:
CUR | curated - hand-verified mapping for the largest country operators |
NS | DNS NS record on the org's apex domain (operator's own name servers) |
SOA | DNS SOA primary nameserver |
MX | DNS MX record (mail-exchange host) |
SPF | SPF (TXT record): ip6: literal address, or hostname from a:/mx:/include: |
DMARC | DMARC report-handler URI from _dmarc TXT record |
DRV | holder-derived - guessed <service>.<holder-slug>.<tld> (www, ns1, mail, gw, vpn, edge, …) |
ATL | RIPE Atlas probe public IPv6 address |
PDB | PeeringDB netixlan / website |
RDAP | RDAP autnum entity vcard email/url (modern replacement for RIPE whois) |
WHOIS | RIPE whois -B scrape (descr, email-domain, org) |
CT | Certificate Transparency log subject (crt.sh) |
NTP | <country>.pool.ntp.org member |
OOKLA | Ookla Speedtest server in country |
HIT | TUM Alcatraz IPv6 Hitlist (~19M responsive addresses) |
RTR | router - hop seen in this AS' own prefix on a prior traceroute or yarrp |
PRB | static prefix probe (::1, ::25, ::53, ::80, ::443, …) |
SYN | synthetic prefix::1 fallback when no live host was found anywhere |
What we measure per target
- Echo Request, small (56-byte payload) - baseline ping.
- Echo Request, 1500 B with DF set - tests whether the path can carry full-MTU packets and whether PMTUD signaling is required and working.
traceroute6 -q 2- path discovery; identifies which hops respond with Time-Exceeded vs go silent.mtr -6 -c 10 -i 1.0- same path with 10 cycles per hop at 1 pps so we can see partial Time-Exceeded loss per hop. Mid-range loss (5-95%) usually means a router is rate-limiting its own ICMPv6 generation via CoPP / control-plane policing rather than truly blocking.tracepath -6- walks the path with size-varying probes so any actual PMTU step-down (with returned Type 2) is captured.- UDP probe to a high closed port - if the kernel surfaces
ECONNREFUSED, the destination's stack returned ICMPv6 Type 1 Code 4 (Port Unreachable). - TCP SYN to 80 and 443 - a basic liveness check that bypasses ICMP filters, so we can distinguish "host is dead" from "ICMP blocked".
- Yarrp pass - a parallel ICMPv6 traceroute (
yarrp) runs once per daily cycle against every SRB target IP. Faster and denser than per-target traceroute (uses ICMP6 echo, sees hops that drop UDP traceroute). Output stored indata/yarrp_latest.json.
Active ICMPv6 Type 2 (Packet Too Big) acceptance test
For each target we additionally try to determine whether the destination network will accept and act on an inbound ICMPv6 Type 2 - the Packet Too Big message, abbreviated PTB below - per RFC 8201 PMTU Discovery validation. We run all four methods in parallel at every vantage and record a 4×N matrix of (method, vantage) verdicts; the per-AS page exposes that matrix in full so an operator can see whether two vantages disagree because of method-mismatch (each vantage's first-success method landed on different protocols) or because of an actually-asymmetric filter on the path. A row collapses to a single verdict when its methods agree; when methods inside a single vantage disagree the row is flagged as a measurement artifact rather than a real-world finding.
- icmp6-echo - the universal method. Send a 1500-byte Echo Request, observe the (whole) Echo Reply. Forge an ICMPv6 Type 2 (MTU=1280) toward the destination with the captured Reply embedded (RFC 4884 / RFC 8201 require the embedded packet to match a real flow). Send another 1500-byte Echo. If the next Reply arrives fragmented via the IPv6 Fragment Header, the destination cached PMTU=1280 and honored our Type 2. If the path PMTU is below 1500 B (so even the natural Echo Reply comes back fragmented and the test cannot tell whether shrinkage is our doing), the script automatically steps down to 1400 B / PTB 1200 and then 1300 B / PTB 1100, so a smaller path PMTU on one vantage doesn't force a fall-through to a TCP-based method.
- dns-tcp - for nameserver targets (port 53). Pipeline 8 queries (ANY ., NS ., DNSKEY com, NS net, ANY example.com, ANY isoc.org, …) on one TCP connection so the response stream is large enough; sniff segments; forge PTB; reconnect; compare segment sizes.
- tls - for HTTPS targets (port 443). Initiate a TLS handshake (cert chain is typically 2-8 KB); sniff segments; forge PTB; redo handshake; compare.
- http - the original test on port 80. HTTP GET that elicits a multi-KB response.
Each method reports one of honored, not_honored,
partial, inconclusive, no_tcp, no_echo.
The vantage-level summary is the most decisive verdict across the four methods
(honored/not_honored dominate; inconclusive
is broken only by another method on the same vantage). The forged Type 2 source
IP is our own address, not a path router - per RFC 8201, implementations that
validate the embedded packet against a recent flow accept this.
Per-hop PTB acceptance walk
For every AS where the per-vantage Type 2 verdicts disagree, we additionally
run a per-hop walk from the local vantage: replay the same forged
Type 2 / large-Echo dance, but targeted at every hop on the forward path in
reverse order (deepest first). The first hop where the Echo Reply comes back at
the full 1460-byte payload after our PTB is the first break point -
the router that silently dropped (or didn't honour) the PTB. The walk lets
operators move from "AS X is somewhere on the bad path" to "the break is at hop
N, IP 2a…, AS Y, which is upstream of the destination". Walks
that produce no clear break (every hop opaque to traceroute) are reported as
inconclusive rather than fabricated.
Diagnostic interpretation (AI explainer)
Once the matrix and walk data are assembled, an LLM (Anthropic Claude) is asked to read the structured payload and write a short operator-facing explanation: which transit AS is the prime suspect, which specific hop the walk implicates, which side (destination ingress vs. transit hop) is the most actionable next step. The explainer never invents data - it only paraphrases the matrix + walk + path-divergence findings. Each explanation is cached per-AS and re- generated only when the disagreement signature changes (verdicts shift, divergence point moves, walk break-point moves), so a stable misconfiguration is summarised once and re-used across daily runs. Explanations appear as a "Diagnostic interpretation" callout on the per-AS page.
When the vantage points disagree
The same destination can produce different Type 2 verdicts from different vantage points. The per-ASN page tags every disagreement with one of these causes so you can tell apart "real-world finding" from "measurement artifact":
- path-asymmetric Type 2 filtering - vantages used the
same
icmp6-echomethod and reached opposite verdicts. The destination stack is the same in every case, so the difference must be in the path: a transit AS on one route silently drops our forged Type 2 (or its return ICMPv6) while the other route delivers it. Thehonoredverdict reflects the destination's actual behaviour; thenot_honoredverdict reflects the broken transit path. - method-mismatch (largely retired) - in the legacy
"first-method-wins" probe, vantages occasionally landed on different methods
(e.g. one used
icmp6-echo, another fell through tohttp) when the path PMTU on one vantage was below 1500 B and the Echo Reply came back already fragmented. The matrix probe described above runs all four methods on every vantage in parallel, so disagreements that were really method-mismatch artifacts now fold into a single decisive vantage verdict. Whatever method-mismatch noise survives is detected from the matrix and excluded from the "real" disagreement count rather than treated as a finding. - reachability mismatch - one vantage couldn't drive a flow to the destination at all (no Echo, no responding TCP port). The other vantage's verdict is the meaningful one.
- measurement artifact - one vantage's probe didn't generate enough data to detect segment shrinkage. The other vantage's verdict is the meaningful one.
Classification
Each (AS, vantage) result lands in exactly one bucket:
- open - small Echo and 1500-byte Echo both work. The path can carry full-MTU and the host answers ICMPv6.
- echo only - small Echo works, 1500-byte does not. Suggests either a path-MTU constraint plus broken PMTUD signaling, or oversize- packet filtering.
- ptb only - rare; only 1500-byte works.
- icmp blocked - no Echo, but TCP responds. The destination is alive; ICMPv6 is filtered at the host firewall.
- all blocked - nothing answered. The probed address may be cold or every protocol is dropped inbound.
- blocked in destination AS - traceroute entered the destination AS, a real IPv6 host was discovered for the AS via DNS / hitlist / Atlas / certificate transparency, but every probed address inside its prefix was silent on ICMPv6. The filter is at the AS edge or applied to all hosts within.
- no IPv6 implementation detected -
the AS announces an IPv6 prefix in BGP and traceroute reaches inside its
routing infrastructure, but no real IPv6 host was ever found by any
discovery source (DNS, IPv6 hitlist, RIPE Atlas, Certificate Transparency,
NTP Pool, Ookla, holder-derived service names, PeeringDB). The test fell
back to a synthetic
prefix::1probe that also did not reply. The most common cause is an AS that has an IPv6 allocation and announces it, but has not yet deployed any host into it (allocate-and-park). Different operator action than "blocked in destination AS": deploy a host, not review your firewall. - transit only unreachable - the path went silent before entering the destination AS; the responses stop somewhere in transit and we cannot identify the exact filtering router. "Filter likely at" then says past AS X (Y) - past, because AS X is the last AS that did reply, not the one filtering.
How to read a row
- Hover Classification → hover-card shows the full traceroute with reverse-DNS hostnames, the AS each hop belongs to, and per-hop mtr loss.
- Last hop = the deepest hop number that returned a Time-Exceeded. A check mark (✓) means traceroute reached the actual target IP.
- Filter likely at - destination AS… means the AS itself is the filter; past AS X (Y) means AS X did reply - the silence begins on the next hop (some unknown AS downstream).
- Analysis button at the right opens a multi-paragraph plain-English explanation of that specific row: what was measured, where it stops, what the likely problem is. Generated deterministically from the structured data.
- An mtr-loss number shown as 0%* means we masked a known control-plane-policing artifact on our own first hops (mostly the local router) so it does not pollute the rate-limited-hops report. Hover for the raw value.
RPKI & ASPA methodology
Resource Public Key Infrastructure (RFC 6480) cryptographically binds an IP prefix to its origin AS. ASPA - Autonomous System Provider Authorisation (RFC 9774, ratified 2024) - extends RPKI so a customer AS can additionally publish the list of upstream providers authorised to propagate its routes; routes that arrive via any other path are then ASPA-invalid.
For every announced IPv6 prefix and every AS we query a local Routinator at
rpki-lju.6connect.com: GET /json returns the full set of
Validated ROA Payloads (VRPs) and ASPA records. We classify each prefix locally as
valid (covering VRP with matching origin and adequate maxLength),
invalid (covering VRP exists but origin or maxLength mismatch), or
not-found (no covering VRP). The aggregated state drives the RPKI badge
on the main table and the per-prefix breakdown on each per-ASN page. ASPA records
are surfaced as ASPA ✓ with the provider
list on hover; ASes that have not yet published an ASPA record carry a yellow
ASPA - badge.
Other pages
- State of IPv6 in Serbia - narrative summary derived from this run: adoption, classification mix, RFC 4890 / RPKI / ASPA rollout, peering at SOX, asymmetry, BGP visibility.
- Topology - AS-level graph built from the 12-vantage-point global yarrp mesh plus observations from our three local vantages. Four layout variants (A/B/C/D) explore different visual approaches.
- SOX peering - live route-server session state, prefixes announced by each member, transit-customer relationships visible in the BGP table.
- Country picker (landing page) - the pipeline runs the same measurement against multiple countries; the landing page draws a Europe map, highlights every measured country, and shows a stat card per country with a five-bucket issue breakdown that sums to the total of measured ASNs.
- Cross-country PTB filter atlas - every transit AS that appears on a path through which our forged PTBs are dropped, ranked by how often they show up across all measured countries. Operators of those transits typically didn't realise their ICMPv6 ACL or rate-limit was breaking PMTUD for downstream networks.
Limitations and honest disclaimers
- The active Type 2 test (above) is the authoritative test for whether the
destination accepts an inbound PTB and updates its PMTUD cache. The
small-vs-1500 B Echo difference and
tracepathremain useful corroborating signals, but the active test is what drives the RFC 4890 badge. - "Open" only means our two specific probe sources see ICMPv6 work. It does not mean the destination accepts ICMPv6 from the entire Internet.
- Some routers rate-limit ICMPv6 Time-Exceeded via CoPP. Our 24-worker concurrent measurement bursts against our own first hop trip this; that is masked in the UI for the local router. We do not mask suspected rate-limiting on third-party hops - that is reported with mid-range loss in orange.
- For ASes where no echo target was found, we send all probes to
prefix::1; the path data is still meaningful but echo-related fields are uninformative. - RPKI / ASPA snapshots come from a single Routinator instance
(
rpki-lju.6connect.com). If that validator is unreachable on a given run we keep the previous day's data so badges don't flicker; if it's wrong (e.g. a stale RIR repository), our results inherit that error. - Discovery (the per-AS target list) runs only on the orchestrator. The list is then sync'd to every measurement vantage point so the same hosts get probed everywhere - the per-vantage results column reflects only the path differences, not different target sets.
Cadence and provenance
The pipeline runs daily at 12:00 Europe/Ljubljana via cron on the orchestrator
(scripts/08_daily_run.sh) under a flock single-instance
lock so a manual re-run cannot collide with the scheduled one. Each run keeps its
raw per-vantage-point JSON in results/ so historical trends are
derivable.
External services consulted: RIPEstat (ASN list, prefix
announcements, RIS BGP visibility); RIPE whois port 43 plus
RIPE RDAP (rdap.db.ripe.net) - we maintain the
RDAP path as a futureproof replacement since RIPE NCC has signalled the deprecation
of plaintext whois; PeeringDB; RIPE Atlas;
TUM IPv6 Hitlist Service; crt.sh (Certificate
Transparency); SOX (IXP Manager / PeeringDB); Team Cymru bulk
whois (hop AS attribution); local Routinator
rpki-lju.6connect.com (RPKI ROA + ASPA validation).
All scripts and data live on the orchestrator; per-vantage probe results are mirrored from each remote vantage into the orchestrator's tree at the end of every daily run.
Built and maintained by Jan Žorž with assistance from Sparky. · Raw analyzed dataset: data.json.