RFC 9234 observed in the wild

By on 16 May 2023

Category: Tech matters

Tags: , , , ,

Blog home

Route leaks occur when Border Gateway Protocol (BGP) prefixes are propagated in a way that goes against the expected topology relationships of BGP. For example, this can happen when a route learned from one transit provider is announced to another transit provider or a lateral peer (peer-peer-peer), or when a route learned from one lateral peer is announced to another lateral peer or a transit provider (see RFC 7908). These leaks often result from misconfiguration or the absence of BGP route filtering, or from inadequate coordination between Autonomous Systems (ASes).

I have worked closely on detecting route leaks and we shipped a route-leak detection system under the Cloudflare Radar platform for free public consumption. In short, the system detects potential route leaks by first inferring the inter-AS relationships on a per-prefix-basis, and examines each AS path being announced to detect valley-free violations. However, the detection of route leaks can only help operators so much, where prevention should be the ultimate solution.

RFC 9234

RFC 9234 documents an active route-leak prevention approach where it defines new BGP capacities (BGP Roles) exchanged during the eBGP session open time and allows the BGP routers to understand AS relationships between local and remote ASes, and thus prevent the propagation of route leaks. RFC 9234 also defines a new BGP attribute type, only-to-customer, which tells the receiving BGP routers whether some routes should never be announced to another provider.

When a pair of eBGP routers both implement RFC 9234, they will first confirm the BGP role of each other.

Local AS RoleRemote AS Role
ProviderCustomer
CustomerProvider
RSRS-Client
RS-ClientRS
PeerPeer
Table 1 — Allowed pairs of role capabilities. Source.

With roles defined, it handles the only-to-customer (OTC) attributes as follows.

Screenshot of RFC 9234's Only to Customer (OTC) attribute.
Figure 1 — RFC 9234’s OTC attribute. Source.

In essence, RFC 9234 uses BGP roles and OTC attributes to make sure routes received from a provider or a peer can only be propagated to customers.

Only-to-customer attribute in the wild

RFC 9234 graduated as an official RFC in May 2022, almost one year ago. There have not been many discussions about the deployment of RFC 9234, nor actual measurements of how widely it is deployed on the Internet.

To observe the deployment of RFC 9234, I added the support for RFC 9234 to the BGPKIT parser a while back and wrote a quick example code to demonstrate how to parse a RIB file and look for messages that contain only-to-customer attributes.

Here is what I see from parsing one single RIB dump file from the route-views2 RIB dump (file link).

OTC found: 15562 for path 23673:6939:15562
A|1678932008|203.189.128.233|23673|67.221.245.0/24|23673 6939 15562|IGP|203.189.128.233|0|0||NAG||

OTC found: 15562 for path 293:6939:15562
A|1678932008|198.129.33.85|293|67.221.245.0/24|293 6939 15562|IGP|198.129.33.85|0|710||NAG||

OTC found: 15562 for path 11686:6939:15562
A|1678932008|96.4.0.55|11686|67.221.245.0/24|11686 6939 15562|IGP|96.4.0.55|0|0|11686:195|NAG||

OTC found: 15562 for path 18106:6939:15562
A|1678932008|202.73.40.45|18106|67.221.245.0/24|18106 6939 15562|IGP|202.73.40.45|0|0|6939:2000|NAG||

OTC found: 15562 for path 34224:6939:15562
A|1678932008|94.156.252.18|34224|67.221.245.0/24|34224 6939 15562|IGP|94.156.252.18|0|0|34224:333|NAG||

OTC found: 15562 for path 20130:6939:15562
A|1678932008|140.192.8.16|20130|67.221.245.0/24|20130 6939 15562|IGP|140.192.8.16|0|0||NAG||

OTC found: 15562 for path 6939:15562
A|1678932008|64.71.137.241|6939|67.221.245.0/24|6939 15562|IGP|64.71.137.241|0|0||NAG||

OTC found: 212068 for path 11686:6939:212068
A|1678932020|96.4.0.55|11686|139.28.205.0/24|11686 6939 212068|IGP|96.4.0.55|0|0|11686:195|NAG||

OTC found: 212068 for path 23673:6939:212068
A|1678932020|203.189.128.233|23673|139.28.205.0/24|23673 6939 212068|IGP|203.189.128.233|0|0||NAG||

OTC found: 212068 for path 6939:212068
A|1678932020|64.71.137.241|6939|139.28.205.0/24|6939 212068|IGP|64.71.137.241|0|0||NAG||

OTC found: 212068 for path 20130:6939:212068
A|1678932020|140.192.8.16|20130|139.28.205.0/24|20130 6939 212068|IGP|140.192.8.16|0|0||NAG||

OTC found: 20555 for path 6939:20555
A|1678932039|64.71.137.241|6939|213.135.44.0/22|6939 20555|IGP|64.71.137.241|0|0||NAG||

OTC found: 20555 for path 11686:6939:20555
A|1678932039|96.4.0.55|11686|213.135.44.0/22|11686 6939 20555|IGP|96.4.0.55|0|0|11686:195|NAG||

OTC found: 20555 for path 23673:6939:20555
A|1678932039|203.189.128.233|23673|213.135.44.0/22|23673 6939 20555|IGP|203.189.128.233|0|0||NAG||

OTC found: 20555 for path 20130:6939:20555
A|1678932039|140.192.8.16|20130|213.135.44.0/22|20130 6939 20555|IGP|140.192.8.16|0|0||NAG||

OTC found: 20555 for path 6939:20555
A|1678932039|64.71.137.241|6939|213.135.48.0/23|6939 20555|IGP|64.71.137.241|0|0||NAG||

OTC found: 20555 for path 11686:6939:20555
A|1678932039|96.4.0.55|11686|213.135.48.0/23|11686 6939 20555|IGP|96.4.0.55|0|0|11686:195|NAG||

OTC found: 20555 for path 23673:6939:20555
A|1678932039|203.189.128.233|23673|213.135.48.0/23|23673 6939 20555|IGP|203.189.128.233|0|0||NAG||

OTC found: 20555 for path 20130:6939:20555
A|1678932039|140.192.8.16|20130|213.135.48.0/23|20130 6939 20555|IGP|140.192.8.16|0|0||NAG||

From this output, we can see that at least four ASes (AS6939, AS15562, AS20555, and AS212068) implement RFC 9234 and the messages containing OTC attributes propagated to the route collector and got preserved into MRT files.

The code that generates this result is also very simple. It’s pretty much just a loop of messages and checking if the only_to_customer attribute is present in the message.

use bgpkit_parser::BgpkitParser;

fn main() {
    for elem in BgpkitParser::new(
        "http://archive.routeviews.org/bgpdata/2023.03/RIBS/rib.20230316.0200.bz2",
    )
    .unwrap()
    {
        if let Some(otc) = elem.only_to_customer {
            println!(
                "OTC found: {} for path {}\n{}\n",
                &otc,
                &elem.as_path.as_ref().unwrap(),
                &elem
            );
        }
    }
}

If you would like to try out this example yourself, you can run the following command (assuming you have Rust toolchain installed):

git clone https://github.com/bgpkit/bgpkit-parser
cd bgpkit-parser
cargo run --release --example only-to-customer

Job Snijders shed some more light on the source of OTC attributes. I did not know YYCIX before — it’s a pretty cool exchange point!

Mingwei Zhang (Twitter, Mastodon) PhD is a senior systems engineer at Cloudflare, building complex high-throughput data pipelines and conducting data analysis on significant Internet routing events. He is the founder of open source BGP data analysis toolkit BGPKIT.

Adapted from the original post at Request for Commits.

Rate this article

The views expressed by the authors of this blog are their own and do not necessarily reflect the views of APNIC. Please note a Code of Conduct applies to this blog.

Leave a Reply

Your email address will not be published. Required fields are marked *

Top