Hello!
At one point it seems like there was a helper function already written
for this that has been lost in time. It used to be right next to
as_path_contains_confed() in the code.
Maybe its time to bring it back? :-)
Thanks!
int
as_path_contains_set(const struct adata *path)
{
const byte *pos = path->data;
const byte *end = pos + path->length;
while (pos < end)
{
uint type = pos[0];
uint slen = 2 + BS * pos[1];
if ((type == AS_PATH_SET) ||
(type == AS_PATH_CONFED_SET))
return 1;
pos += slen;
}
return 0;
}
On 12/27/2024 5:29 PM, Ralph Covelli via Bird-users wrote:
Okay!
I talked to Job. It looks like they have no interest in easing the
transition for stragglers who are still announcing AS_SETs in their
AS_PATHs.
All AS_SETs should result in ASPA_INVALID.
I also just learned the Dutch have a saying... "soft doctors make
wounds stink".
Haha! Thanks again for all your help.
Ralph Covelli
Network Engineer
Hurricane Electric / AS6939
On 12/27/2024 4:40 PM, Ralph Covelli via Bird-users wrote:
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.