Lab: BGP Roles and Only To Customer (OTC)
Overview
This lab demonstrates how to deploy and validate BGP Roles and Only To Customer (OTC) Attribute, as defined in RFC 9234. BGP Roles provide a mechanism to enforce valley-free routing and help prevent route leaks. A similar mechanism is provided by ASPA, which relies on RPKI.
Tip
Quick start: Launch this lab in GitHub Codespaces (no local setup required)
Recommended Machine type: 2 vCPU · 8 GB RAM
Pull the FRR container image: docker pull quay.io/frrouting/frr:10.5.4
Lab files including Containerlab topology are available on GitHub.
Lab consists of following devices
Topology

Implementation and Verification
All BGP peerings are configured with the appropriate local-role, as shown in the topology:
- Provider
- Customer
- Peer
Example BGP configuration with respective BGP Roles on the igw router:
|
|
(A default permit-all route map is configured for each BGP session.)
The roles are negotiated using the BGP OPEN message when a BGP session is established (BGP Role Capability, Code: 9). The respective local and remote roles can be observed using the BGP neighbor command:
igw# sh ip bgp neighbors 10.1.3.1
BGP neighbor is 10.1.3.1, remote AS 65001, local AS 65003, external link
Local Role: customer
Remote Role: provider
Description: isp1
[omitted]
igw# sh ip bgp neighbors 10.2.3.2
BGP neighbor is 10.2.3.2, remote AS 65002, local AS 65003, external link
Local Role: customer
Remote Role: provider
Description: isp2
[omitted]
igw# sh ip bgp neighbors 10.3.4.4
BGP neighbor is 10.3.4.4, remote AS 65004, local AS 65003, external link
Local Role: provider
Remote Role: customer
Description: customer
[omitted]
igw# sh ip bgp neighbors 10.3.5.5
BGP neighbor is 10.3.5.5, remote AS 65005, local AS 65003, external link
Local Role: peer
Remote Role: peer
Description: peer
[omitted]The BGP OTC attribute (Code: 35) is sent to a peer along with a prefix in the UPDATE message. In the example below, the isp1 router attaches the OTC attribute with a value of 65001 to the prefix 192.168.1.0/24 when advertising it to the igw router:
igw# sh bgp ipv4 unicast 192.168.1.0/24
BGP routing table entry for 192.168.1.0/24, version 2
Paths: (1 available, best #1, table default)
Advertised to peers:
10.3.4.4
65001
10.1.3.1 from 10.1.3.1 (100.64.0.1)
Origin IGP, metric 0, valid, external, otc 65001, best (First path received)
Last update: Tue Aug 4 12:14:29 2026(As a result, the prefix will subsequently be sent only to customers.)
Each router in this lab advertises a prefix 192.168.[ID].0/24 into BGP. The following output shows the routing table on each router, confirming that prefixes are advertised as intended with BGP Role enabled.
isp1# sh ip route 192.168.0.0/16 longer-prefixes
[omitted]
IPv4 unicast VRF default:
S>* 192.168.1.0/24 [1/0] unreachable (blackhole), weight 1, 00:07:14
B>* 192.168.3.0/24 [20/0] via 10.1.3.3, eth1, weight 1, 00:07:09
B>* 192.168.4.0/24 [20/0] via 10.1.3.3, eth1, weight 1, 00:07:09
isp2# sh ip route 192.168.0.0/16 longer-prefixes
[omitted]
IPv4 unicast VRF default:
S>* 192.168.2.0/24 [1/0] unreachable (blackhole), weight 1, 00:08:00
B>* 192.168.3.0/24 [20/0] via 10.2.3.3, eth1, weight 1, 00:07:55
B>* 192.168.4.0/24 [20/0] via 10.2.3.3, eth1, weight 1, 00:07:55
igw# sh ip route 192.168.0.0/16 longer-prefixes
[omitted]
IPv4 unicast VRF default:
B>* 192.168.1.0/24 [20/0] via 10.1.3.1, eth1, weight 1, 00:01:10
B>* 192.168.2.0/24 [20/0] via 10.2.3.2, eth2, weight 1, 00:01:10
S>* 192.168.3.0/24 [1/0] unreachable (blackhole), weight 1, 00:01:15
B>* 192.168.4.0/24 [20/0] via 10.3.4.4, eth3, weight 1, 00:01:10
B>* 192.168.5.0/24 [20/0] via 10.3.5.5, eth4, weight 1, 00:01:10
customer# sh ip route 192.168.0.0/16 longer-prefixes
[omitted]
IPv4 unicast VRF default:
B>* 192.168.1.0/24 [20/0] via 10.3.4.3, eth1, weight 1, 00:08:42
B>* 192.168.2.0/24 [20/0] via 10.3.4.3, eth1, weight 1, 00:08:42
B>* 192.168.3.0/24 [20/0] via 10.3.4.3, eth1, weight 1, 00:08:42
S>* 192.168.4.0/24 [1/0] unreachable (blackhole), weight 1, 00:08:47
B>* 192.168.5.0/24 [20/0] via 10.3.4.3, eth1, weight 1, 00:08:42
peer# sh ip route 192.168.0.0/16 longer-prefixes
[omitted]
IPv4 unicast VRF default:
B>* 192.168.3.0/24 [20/0] via 10.3.5.3, eth1, weight 1, 00:09:24
B>* 192.168.4.0/24 [20/0] via 10.3.5.3, eth1, weight 1, 00:09:24
S>* 192.168.5.0/24 [1/0] unreachable (blackhole), weight 1, 00:09:29- A prefix received from a provider is propagated only to customers (OTC) - enforcing valley-free routing. For example, a prefix learned from
isp1is not advertised toisp2or to any peer. - A prefix received from a peer is also propagated only to customers.
- A prefix that is locally originated within the AS, or learned from a customer, is propagated to all neighbors: customers, peers, and providers.