Possible logic error in ASPA validation (was: How to work with ASPA efficiently?)

Ondřej Caletka ondrej at caletka.cz
Thu Feb 5 18:33:51 CET 2026


Hello again!

On 29/01/2026 11:49, Ondřej Caletka wrote:
> I wonder whether there is a way how to see a ASPA table entry for 
> particular customer AS number. Something like:
> 
> bird> show route table aspas all for 2121
> syntax error, unexpected NUM, expecting IP4 or IP6 or VPN_RD or 
> CF_SYM_KNOWN
> 

Found it!

bird> show route all aspa 2121
Table aspas:
2121                  [rpki_validator 2026-01-29] * (100)
         preference: 100
         source: RPKI
         aspa_providers: 3333
         Internal route handling values: 0L 16G 1S id 10


> 
> Regarding the validation itself, a random trivial example where 
> aspa_check_downstream fails and I don't know why is this:
> 
> 80.254.230.0/24
>          bgp_path: 3333 12859 42695
> 
> (My ASN is 2121 and there is an ASPA stating that 3333 is provider for 
> 2121)
> 
> There is no ASPA for 3333
> There is ASPA for 12859 not stating 42695 as provider
> There is ASPA for 42695 not stating 12859 as provider
> 
> So the up ramp should be 42695
> and the down ramp should be 2121 3333 12859
> 
> I don't see any valleys here yet it is rejected.
> 
> Am I doing it wrong?

I believe there is a logic error not covered by the tests in the 
validation logic around here

https://gitlab.nic.cz/labs/bird/-/blob/master/nest/rt-table.c?ref_type=heads#L428

I did some pen-and-paper tracing of this algorithm:

First ASN: 3333
ap = 0, found = up = down = false;
set max_down = 1, min_up = 0;

So far so good, no ASPA so the min_down ramp ends here, the max_down 
goes further. If there is no ASPA everywhere, min_up can end here too.

Second ASN: 12859
ap = 1, found = true, up = down = false;
set min_up = max_up = 1;
set force_upstream = true;

There is ASPA but neither on the left or on the right is a provider. We 
don't touch the down ramp (it pointed here from the previous step) and 
we clamp the up ramp for this position.
However, we also force upstream validation from now on. I believe this 
is wrong because if this is the apex of the down ramp, the upstream 
validation should start from the next ASN.

Third ASN: 42695
ap = 2, found = true, up = down = false, force_upstream = true;
Bacause ap>0 and the ASN on the left is not provider, this ends up with 
ASPA_INVALID, because in previous iteration, the algorithm was switched 
to the upstream one.

Should we not switched to upstream validation at this point this would 
end up with min_up = max_up = 2.

I believe that this is expected result for the algorithm: both minimum 
and maximum up ramps end on AS with index 2, minimum down ramp is 0 
since the leftmost ASN does not have ASPA, but maximum down ramp is 1.

Thus having max_up = 2 and max_down = 1 says that the up and down ramps 
are meeting on adjacent peers. This should be allowed.

However the logic in the code requires max_up <= max_down for Unknown 
result. This means it requires up and down ramps to be touching or 
overlapping.

I don't think this is what the draft-ietf-sidrops-aspa-verification-24 
is prescribing. It operates with ramp lengths in place of positions so 
for this particular case:
max_up_ramp = 1, min_up_ramp =1, max_down_ramp = 2, min_down_ramp = 1, N 
= 3.

The draft says that:
>  the sum of max_up_ramp and max_down_ramp is less than N, the AS_PATH is Invalid.

Here 1 + 2 = 3 so this is not invalid.

> Else, if the sum of min_up_ramp and min_down_ramp is less than N, enough information is not available to perform full AS_PATH verification, and the outcome is set to Unknown.

Here 1 + 1 < 3 so this should be unknown.


Am I still doing it wrong? :)

--
Best regards,

Ondřej Caletka


More information about the Bird-users mailing list