An AS set in a path is flattened into the path, giving a wrong origin AS and false peerings #75

Closed
opened 2026-10-14 14:50:34 +02:00 by clawbot · 2 comments
Collaborator

ASPath.UnmarshalJSON in internal/ristypes/ris.go turns a path that ends in an AS set, such as [64496, 64497, [64498, 64499]], into the plain sequence [64496, 64497, 64498, 64499]. The members of a set are not a sequence: any of them may be the origin, and they are not neighbours of each other.

  • PrefixHandler and ASHandler take the last element as the origin, so the route is stored and shown as originated by AS64499, a member picked by its position.
  • PeeringHandler records AS64497 with AS64498 and AS64498 with AS64499 as peerings, neither of which the path shows.

Failure scenario: an aggregated route with that path is listed on /as/64499, the IP lookup answers AS64499 for it, and /as/64498 lists AS64499 as a peer. AS sets are rare and deprecated, but still occur in the feed.

Reading taken (as RFC 6811 does for origin validation): a path ending in a set of several members has no known origin; a one-member set counts as that AS.

Severity: low

Definition of done

  • A test, failing before the fix: [64496, 64497, [64498, 64499]] stores its route with origin 0 (none) and gives no peering involving AS64498 or AS64499; [64496, 64497, [64498]] stores origin AS64498 and the peering AS64497 with AS64498.
  • ASPath keeps a trailing set apart from the sequence, and the prefix, AS and peering handlers use it as above.
  • make check passes.

Model: opus-5-5

`ASPath.UnmarshalJSON` in `internal/ristypes/ris.go` turns a path that ends in an AS set, such as `[64496, 64497, [64498, 64499]]`, into the plain sequence `[64496, 64497, 64498, 64499]`. The members of a set are not a sequence: any of them may be the origin, and they are not neighbours of each other. - `PrefixHandler` and `ASHandler` take the last element as the origin, so the route is stored and shown as originated by AS64499, a member picked by its position. - `PeeringHandler` records AS64497 with AS64498 and AS64498 with AS64499 as peerings, neither of which the path shows. Failure scenario: an aggregated route with that path is listed on `/as/64499`, the IP lookup answers AS64499 for it, and `/as/64498` lists AS64499 as a peer. AS sets are rare and deprecated, but still occur in the feed. Reading taken (as RFC 6811 does for origin validation): a path ending in a set of several members has no known origin; a one-member set counts as that AS. Severity: low ## Definition of done - A test, failing before the fix: `[64496, 64497, [64498, 64499]]` stores its route with origin 0 (none) and gives no peering involving AS64498 or AS64499; `[64496, 64497, [64498]]` stores origin AS64498 and the peering AS64497 with AS64498. - `ASPath` keeps a trailing set apart from the sequence, and the prefix, AS and peering handlers use it as above. - `make check` passes. Model: opus-5-5
clawbot self-assigned this 2026-10-14 14:50:34 +02:00
Author
Collaborator

Plan: ristypes.ASPath keeps the plain sequence and, apart from it, the members of a set that ends the path, and gives one method for the origin: the last AS of a path without a set, the member of a one-member set, and 0 (none) for a set of several. The prefix and AS handlers take the origin from that method; the peering handler records peerings only between neighbours in the sequence, plus the last AS of the sequence with a one-member set. A set anywhere but at the end is kept as now. The stored and shown AS path keeps the set's members after the sequence. It waits for the re-vendor in #85, so it is written to the new lint configuration.

Model: opus-5-5

Plan: `ristypes.ASPath` keeps the plain sequence and, apart from it, the members of a set that ends the path, and gives one method for the origin: the last AS of a path without a set, the member of a one-member set, and 0 (none) for a set of several. The prefix and AS handlers take the origin from that method; the peering handler records peerings only between neighbours in the sequence, plus the last AS of the sequence with a one-member set. A set anywhere but at the end is kept as now. The stored and shown AS path keeps the set's members after the sequence. It waits for the re-vendor in https://git.eeqj.de/sneak/routewatch/pulls/85, so it is written to the new lint configuration. Model: opus-5-5
Author
Collaborator

Built in #91. It follows the plan with one difference: a one-member set that ends the path is decoded into the sequence, so the origin and the peerings need no separate case for it.

Model: opus-5-5

Built in https://git.eeqj.de/sneak/routewatch/pulls/91. It follows the plan with one difference: a one-member set that ends the path is decoded into the sequence, so the origin and the peerings need no separate case for it. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/routewatch#75