Hi Maria!
Interesting stuff! I suppose you could consider the different AS's in
the SET as "lateral" from each other on "the mountain".
It looks like the newest (aspa-19) wording of the standard demands that
you throw them all out as invalid anyway.
https://datatracker.ietf.org/doc/draft-ietf-sidrops-aspa-verification/
7.2. Algorithm for Upstream Paths
3. If the AS_PATH has an AS_SET, then the procedure halts with the
outcome "Invalid".
7.3. Algorithm for Downstream Paths
3. If the AS_PATH has an AS_SET, then the procedure halts with the
outcome "Invalid".
I am going to see if I can convince the powers that be to change 7.3.3
to "Unknown".
Thanks again!
Ralph Covelli
Network Engineer
Hurricane Electric / AS6939
On 12/27/2024 12:31 PM, Maria Matejka via Bird-users wrote:
Hello Ralph,
Yes, “I have no providers” is a much more accurate description of
AS 0. It can be used by tier 1 networks as well as people trying
to depreciate their old ASN.
Well, yes, a deprecated ASN has also no providers, yet it can still be
(maliciously) placed into a valid AS path if it is on the top place.
OTOH, with that, the attack surface is limited only to your downstream
networks.
It looks like the source of my confusion was that I was under the
assumption that the transit ASPA entries could be used to
auto-detect upstream vs downstream as opposed to doing the check
in the filter script. Sorry about that!
No problem, everybody is confused by ASPA. It’s hard to get it right.
I noticed in aspa_check() you check for confeds but AS_PATH_SET is
never checked for.
Well, that looks like another oversight, thank you for reporting.
The specs say they should return ASPA_INVALID however I noticed
when I did that I lost about 64 routes which caused some customer
complaints. I had to end up slightly changing the code to return
ASPA_INVALID if upstream and ASPA_UNKNOWN if downstream.
Mhmmm. That’s definitely a problem. We can do various things with and
around that. First of all, the default behavior of |aspa_check()| must
conform to the RFC.
Brainstorming:
*
something like |if bgp_path.contains_sets|
*
allowing a more precise for-cycle over |bgp_path|, e.g.
|for bgppath_segment bs in bgp_path do { case bgppath_segment.type
{ AS_PATH_SEQUENCE: for int a in bs do { ... } AS_PATH_SET: for
int a in bs do { ... } AS_PATH_CONFED_SEQUENCE: ... } }|
*
adding an optional argument to |aspa_check()| to allow sets,
treting them as “any of the ASNs in the set”
*
adding an |aspa_is_customer(table, A, B)| function, returning
whether A can be a custormer of B according to the given table
Any other thoughts on that?
Thanks,
Maria
–
Maria Matejka (she/her) | BIRD Team Leader | CZ.NIC, z.s.p.o.