RFC 9234 BGP Only-to-Customer (OTC) on IOS XR
1. Introduction
1.1 Overview
Defined in RFC 9234, the BGP Only-to-Customer (OTC) attribute helps prevent and detect route leaks between Autonomous Systems (ASes), reducing the risk that an AS unintentionally provides transit between its Providers or Peers. OTC applies route-leak rules based on the BGP Role of each eBGP session. The operator configures the role from the perspective of the local AS. The neighbor configures its own role for the same session. For example, one side uses Provider and the other side uses Customer.
OTC is complementary to Autonomous System Provider Authorization (ASPA), which is featured in the next XRdocs BGP tutorial, but does not replace it. OTC does not replace route policy, prefix filtering, or Resource Public Key Infrastructure (RPKI) Route Origin Validation either, because these features have different purposes. Route Origin Validation checks whether a Route Origin Authorization (ROA) permits an AS to originate a prefix. OTC uses the configured BGP Roles to prevent or detect advertisements in a direction that is not allowed.
1.2 What is OTC?
Only-to-Customer (OTC) is an optional transitive BGP path attribute used for route-leak prevention and detection. It uses path attribute type code 35 and carries one four-octet AS number.
When an eBGP router advertises a prefix to a downstream Customer, it marks the prefix with OTC. If an eBGP neighbor receives the OTC-marked route from its downstream Customer, it identifies the route as a route leak.

Figure 1. OTC marks a Customer-facing route and prevents an advertisement to another Provider.
1.3 OTC local roles
OTC uses a local role for each eBGP session. The role defines the relationship of the local AS with the remote AS.
The BGP Role Capability carries the configured local role. It uses capability code 9. The eBGP neighbors exchange this capability in their BGP OPEN messages when the session starts. Each neighbor sends its own local role.
The following table shows all OTC local roles and their meanings:
| Local role | Meaning |
|---|---|
| Provider | The local AS provides transit to the remote AS. |
| Customer | The local AS receives transit from the remote AS. |
| Peer | The two ASes exchange selected routes without providing transit to each other. |
| Route Server (RS) | The local system is a Route Server. |
| Route Server Client (RS-Client) | The local AS is a client of a Route Server. |
The following local and remote role pairs are valid:
| Local role | Remote role |
|---|---|
| Provider | Customer |
| Customer | Provider |
| Peer | Peer |
| Route Server | Route Server Client |
| Route Server Client | Route Server |
Provider and Customer are a valid pair. For a Peer relationship, both routers use the Peer role. Provider and Peer are not a valid pair because the roles do not match.
If both neighbors send the capability, the two roles must form a valid pair. If only one neighbor sends it, the result depends on whether loose or strict mode is used. Section 1.4 explains both modes.
1.4 Loose and strict modes
OTC supports two modes for checking the roles exchanged between eBGP neighbors: loose mode and strict mode.
Loose mode does not require the remote neighbor to send the BGP Role Capability. If only one neighbor sends the capability, the eBGP session can still be established. The OTC-enabled neighbor uses its configured local role for OTC processing. The remote role is inferred from the local role. For example, local role Provider implies remote role Customer. An inferred role does not confirm the configuration on the remote neighbor.
Strict mode requires the remote neighbor to send the BGP Role Capability. In both modes, the two roles must form a valid pair when both neighbors send the capability. A missing capability in strict mode or an invalid role pair causes a Role Mismatch Notification (OPEN Message Error, code 2, subcode 11). In both cases, the eBGP session does not come up.

Figure 2. BGP Role Capability exchange between a Provider and a Customer in strict mode.
The routers exchange their roles only when the session starts. A change to the configured OTC role resets the eBGP session. The routers then send new OPEN messages with the new roles.
2. IOS XR implementation
The OTC feature described in this guide is supported starting with Cisco IOS XR Release 26.4.1. General BGP Route Server functionality is not supported in IOS XR, so the route-server local role is not configurable. The Route Server rows in the tables that follow describe the behavior defined by RFC 9234.
2.1 Configuring OTC roles
To enable OTC on an IOS XR eBGP session, configure otc-local-role under the BGP neighbor configuration. The value defines the local role toward that neighbor. Configure each end from its own point of view. For a Provider-to-Customer relationship, the Provider uses local role provider, and the Customer uses local role customer.
The configuration examples use AS numbers 65540, 65545, and 65550 from the RFC 5398 range reserved for documentation.
Configuration example:
router bgp 65540
neighbor X.X.X.X
remote-as 65545
otc-local-role { customer | provider | peer | route-server-client} [strict]

Figure 3. OTC local roles on a Provider-to-Customer eBGP session.
R1 is configured as Provider toward R2:
router bgp 65545
neighbor 10.10.10.2
otc-local-role provider
!
!
R2 is configured as Customer toward R1:
router bgp 65540
neighbor 10.10.10.1
otc-local-role customer
!
!
R3 is configured as Customer toward R5:
router bgp 65540
neighbor 11.11.11.4
otc-local-role customer
!
!
R5 is configured as Provider toward R3:
router bgp 65550
neighbor 11.11.11.3
otc-local-role provider
!
!
2.2 Basic role verification
Use the detailed neighbor command on both routers. The following R1 output verifies the Provider-to-Customer role pair:
RP/0/0/CPU0:R1# show bgp neighbor 10.10.10.2 detail
BGP neighbor is 10.10.10.2
Remote AS 65540, local AS 65545, external link
Remote router ID 192.168.0.2
BGP state = Established
OTC Local Mode: Loose
OTC Local Role: Provider
OTC Remote Role: Customer (received)
Neighbor capabilities: Adv Rcvd
4-byte AS: Yes Yes
Address family IPv4 Unicast: Yes Yes
OTC Role: Yes Yes
The local and remote roles must form a valid pair. received means that the neighbor sent its role. Yes/Yes means that both routers sent the BGP Role Capability.
2.3 Loose mode configuration and output
Loose mode is the default, so no additional keyword is required. In this example, R3 is configured as Customer toward R5, but no OTC role is configured on R5 toward R3.
router bgp 65540
neighbor 11.11.11.4
otc-local-role customer
!
!
If R5 does not send a BGP Role, R3 can keep the session up. R3 shows the remote role as inferred:
RP/0/0/CPU0:R3# show bgp neighbor 11.11.11.4 detail
BGP neighbor is 11.11.11.4
Remote AS 65550, local AS 65540, external link
Remote router ID 11.11.11.4
BGP state = Established
OTC Local Mode: Loose
OTC Local Role: Customer
OTC Remote Role: Provider (inferred)
Neighbor capabilities: Adv Rcvd
4-byte AS: Yes Yes
Address family IPv4 Unicast: Yes Yes
OTC Role: Yes No
Loose mode can apply OTC processing when only one router advertises the BGP Role Capability. A missing capability means that the neighbor has no local role configured, which is not necessarily the same as the neighbor not supporting BGP Roles. The configured local role controls OTC processing on R3.
2.4 Strict mode configuration and session reset
Strict mode is configured locally. It requires the remote eBGP neighbor to send the BGP Role Capability. The advertised roles must form a valid pair. In this example, strict mode is configured on both neighbors.
R1 configuration:
router bgp 65545
neighbor 10.10.10.2
otc-local-role provider strict
!
!
R2 configuration:
router bgp 65540
neighbor 10.10.10.1
otc-local-role customer strict
!
!
After the configuration is committed, IOS XR resets the eBGP session. The reset is required because the neighbors exchange their roles in the BGP OPEN message.
%ROUTING-BGP-5-ADJCHANGE: neighbor 10.10.10.2 Down - OTC local role changed (CEASE notification sent - configuration change)
%ROUTING-BGP-5-ADJCHANGE: neighbor 10.10.10.2 Up
After the session comes up, verify the mode and roles:
RP/0/0/CPU0:R1# show bgp neighbor 10.10.10.2 detail
BGP neighbor is 10.10.10.2
Remote AS 65540, local AS 65545, external link
Remote router ID 192.168.0.2
BGP state = Established
OTC Local Mode: Strict
OTC Local Role: Provider
OTC Remote Role: Customer (received)
Neighbor capabilities: Adv Rcvd
4-byte AS: Yes Yes
Address family IPv4 Unicast: Yes Yes
OTC Role: Yes Yes
In strict mode, the session does not come up if the remote capability is missing. In either mode, the session does not come up if the roles do not form a valid pair. For example, changing R2 to Provider while R1 is also Provider creates a mismatch:
router bgp 65540
neighbor 10.10.10.1
otc-local-role provider strict
!
!
R1 reports the resulting mismatch:
RP/0/0/CPU0:R1# show bgp neighbor 10.10.10.2 detail | include "Last reset"
Last reset 00:00:06, due to BGP Notification sent: OTC role mismatch
2.5 OTC rules
The OTC rules define how a router processes the OTC attribute based on the role of the eBGP neighbor. Three ingress rules apply when a route is received. Two egress rules apply when a route is advertised. The rules define when OTC is added, when a route becomes ineligible, and when a route must not be advertised.
| Rule | Direction | Condition | Required action |
|---|---|---|---|
| IR1 | Ingress | OTC is present on a route from a Customer or RS-Client. | The leaked path is not accepted for BGP route selection and is not advertised to other BGP neighbors. |
| IR2 | Ingress | OTC is present on a route from a Peer, and OTC is not equal to the remote AS number. | The leaked path is not accepted for BGP route selection and is not advertised to other BGP neighbors. |
| IR3 | Ingress | OTC is absent on a route from a Provider, Peer, or RS. | Add OTC with the remote AS number. |
| ER1 | Egress | OTC is absent on a route sent to a Customer, Peer, or RS-Client. | Add OTC with the local AS number. |
| ER2 | Egress | OTC is present on a route sent to a Provider, Peer, or RS. | Do not advertise the route. |
RFC 9234 applies these ingress and egress procedures only to the IPv4 and IPv6 unicast address families (AFI 1 and AFI 2 with SAFI 1). They are not applied to other address families by default. Once OTC has been set, its value is preserved unchanged.
2.5.1 Ingress Rule 1 (IR1)
When a prefix with OTC is received from a Customer or RS-Client, it is identified as a route leak. The leaked path is not accepted for BGP route selection and is not advertised to other BGP neighbors.
R4 and R3 are configured as Providers. R5 is configured as Customer only toward R3; no OTC role is configured on R5 toward R4:
! R5
router bgp 65550
neighbor 11.11.11.3
otc-local-role customer
!
!
! R4
router bgp 65540
neighbor 12.12.12.4
otc-local-role provider
address-family ipv4 unicast
soft-reconfiguration inbound always
!
!
!
! R3
router bgp 65540
neighbor 11.11.11.4
otc-local-role provider
!
!

Figure 4. R4 identifies an OTC-marked route received from Customer R5 as a route leak.
R5 sends an OTC-marked prefix to R4. R4 receives the prefix from its Customer and identifies it as a route leak. The path is not accepted or advertised to another BGP neighbor.
The lab deliberately allowed the same AS to be received again so the leak could be reproduced. allowas-in was enabled on R4 under the neighbor address family, and R5 disabled the outbound AS_PATH loop check:
! R4
router bgp 65540
neighbor 12.12.12.4
address-family ipv4 unicast
allowas-in
!
!
!
! R5
router bgp 65550
address-family ipv4 unicast
as-path-loopcheck out disable
!
!
Note: These loop-prevention exceptions are only for lab testing and should not be used in a production network.
The neighbor counters and BGP debug identify IR1 as the rejection reason:
RP/0/0/CPU0:R4# show bgp ipv4 unicast neighbors 12.12.12.4 detail | include "OTC ingress|denied"
Exact no. of prefixes denied: 56
Cumulative no. of prefixes denied: 112
By OTC ingress rule 1: 112, By OTC ingress rule 2: 0
RP/0/0/CPU0:R4# debug bgp update in
Prefix 18.18.18.0/24 received from 12.12.12.4 DENIED due to OTC ingress rule 1: route leak from Customer/RS-Client
The route can appear as received-only when inbound soft reconfiguration stores it. The route must not become eligible.
RP/0/0/CPU0:R4# show bgp 18.18.18.0/24 detail
Paths: (3 available, best #1)
Path #2: Received by speaker 0
Not advertised to any peer
65550 65540, (received-only)
12.12.12.4 from 12.12.12.4 (11.11.11.4)
Origin incomplete, localpref 100, valid, external
OTC-AS: 65540
2.5.2 Ingress Rule 2 (IR2)
When a prefix with OTC is received from a Peer, the OTC AS number must be equal to the remote Peer AS number. If the values are different, the prefix is identified as a route leak and becomes ineligible.
For this test, R4 uses the local Peer role in loose mode and R5 does not advertise a BGP Role toward R4. R4 therefore applies Peer ingress processing to the route received from R5:
! R4
router bgp 65540
neighbor 12.12.12.4
otc-local-role peer
!
!
! R5
router bgp 65550
neighbor 12.12.12.5
no otc-local-role customer
!
!

Figure 5. R4 rejects a Peer route because OTC does not equal remote AS 65550.
R5 advertises a path whose OTC value is 65540. Because R5 is in remote AS 65550, R4 rejects the path under IR2:
RP/0/0/CPU0:R4# show bgp ipv4 unicast neighbors 12.12.12.4 detail | include "OTC ingress|denied"
Exact no. of prefixes denied: 56
Cumulative no. of prefixes denied: 56
By OTC ingress rule 1: 0, By OTC ingress rule 2: 56
RP/0/0/CPU0:R4# debug bgp update in
Prefix 18.18.18.0/24 received from 12.12.12.4 DENIED due to OTC ingress rule 2: OTC AS mismatch from Peer
RP/0/0/CPU0:R4# show bgp 18.18.18.0/24 detail
Paths: (3 available, best #1)
Path #2: Received by speaker 0
Not advertised to any peer
65550 65540, (received-only)
12.12.12.4 from 12.12.12.4 (11.11.11.4)
Origin incomplete, localpref 100, valid, external
OTC-AS: 65540
If the OTC AS number is not equal to the remote AS number, 65550, the route becomes ineligible. A route with OTC-AS: 65550 passes the IR2 rule.
2.5.3 Ingress Rule 3 (IR3)
When a prefix without OTC is received from a Provider, Peer, or RS, the receiving router adds OTC. The OTC AS number is set to the remote AS number.
R2 is configured with the local Customer role toward R1. No OTC role is configured on R1. In loose mode, R2 therefore infers R1’s remote role as Provider. R1 sends the route without the OTC attribute:
router bgp 65540
neighbor 10.10.10.1
otc-local-role customer
!
!
! R1 has no configured OTC role toward R2.

Figure 6. R2 adds remote AS 65545 to an unmarked route received from Provider R1.
The R2 BGP table confirms that IR3 stored the AS number of the inferred Provider in OTC:
RP/0/0/CPU0:R2# show bgp 192.168.0.1/32 detail
Paths: (1 available, best #1)
65545
10.10.10.1 from 10.10.10.1 (10.10.10.1)
Origin incomplete, metric 0, localpref 100, valid, external, best, group-best
OTC-AS: 65545
The UPDATE arrived without OTC. The stored route contains the remote AS number 65545. This confirms that R2 applied the IR3 rule. If OTC is already present, the router does not change its value.
2.5.4 Egress Rule 1 (ER1)
When a prefix is advertised to a Customer, Peer, or RS-Client, add the OTC attribute if it is not present. Set the OTC AS number to the local AS number.
R3 is configured as Provider toward R5, and R5 is configured as Customer toward R3:
! R3
router bgp 65540
neighbor 11.11.11.4
otc-local-role provider
!
!
! R5
router bgp 65550
neighbor 11.11.11.3
otc-local-role customer
!
!

Figure 7. R3 adds its local AS number before it sends the route to Customer R5.
No OTC role is configured on the R1-R2 session for this test, so the prefix reaches AS 65540 without OTC and no ingress rule marks it. When R3 advertises the prefix to its Customer R5, ER1 adds OTC with the local AS number of R3. R5 receives the prefix with OTC-AS: 65540.
Note: If R2 kept the Customer role used in the IR3 example, R2 would add
OTC-AS: 65545on ingress. R3 would then preserve that value instead of adding its own, because ER1 only adds OTC when the attribute is absent.
The route output on R5 shows the complete AS path and OTC value:
RP/0/0/CPU0:R5# show bgp 192.168.0.1/32 detail
Paths: (2 available, best #1)
65540 65545
11.11.11.3 from 11.11.11.3 (192.168.0.3)
Origin incomplete, localpref 100, valid, external, best, group-best
OTC-AS: 65540
OTC is added to the route advertised from R3 to R5. The route stored on R3 does not have to contain OTC.
2.5.5 Egress Rule 2 (ER2)
When a prefix with OTC is advertised to a Provider, Peer, or RS, the advertisement is blocked. This prevents the local AS from becoming a transit AS by mistake.
R3 and R4 are configured as Providers toward R5. R5 is configured as Customer toward both routers:
R3 configuration:
router bgp 65540
neighbor 11.11.11.4
otc-local-role provider
!
!
R5 configuration:
router bgp 65550
neighbor 11.11.11.3
otc-local-role customer
!
neighbor 12.12.12.5
otc-local-role customer
!
!
R4 configuration:
router bgp 65540
neighbor 12.12.12.4
otc-local-role provider
!
!
R3 advertises the prefix to Customer R5 with OTC-AS: 65540. Egress Rule 2 prevents R5 from advertising the OTC-marked prefix to its other Provider, R4.

Figure 8. R5 does not advertise an OTC-marked route to its other Provider, R4.
Confirm that R5 has received the OTC-marked route from R3. R5 can still use the route, but ER2 prevents it from advertising the route to R4:
RP/0/0/CPU0:R5# show bgp 192.168.0.1/32 detail
Paths: (2 available, best #1)
Not advertised to any peer
Path #1: Received by speaker 0
Not advertised to any peer
65540 65545
11.11.11.3 from 11.11.11.3 (192.168.0.3)
Origin incomplete, localpref 100, valid, external, best, group-best
OTC-AS: 65540
Path #2: Received by speaker 0
Not advertised to any peer
65540 65545
12.12.12.5 from 12.12.12.5 (192.168.0.5)
Origin incomplete, localpref 100, valid, external
OTC-AS: 65540
Path #1 is the best path received from R3, so R5 can install and use it. Both paths carry OTC-AS: 65540, confirming that they are OTC-marked. Not advertised to any peer shows that R5 does not advertise the OTC-marked path to its other Provider, R4. This is the expected ER2 behavior.
2.6 OTC rules table
The following table covers all combinations, with and without OTC, when both roles are configured or one role is inferred in loose mode. The first column describes the route before egress processing. Configured means that the router has a local role and applies the OTC rules. Inferred means that the other router derives this missing role from its own configured role; the router with the inferred role does not apply role-based OTC processing.
| OTC present? | Sender role | Receiver role | Sender action | Receiver action |
|---|---|---|---|---|
| No | Provider (configured) | Customer (configured) | Add the local AS number as OTC (ER1). | Accept the route with OTC. |
| Yes | Provider (configured) | Customer (configured) | Advertise and preserve OTC. | Accept the route with OTC unchanged. |
| No | Provider (configured) | Customer (inferred) | Add the local AS number as OTC (ER1). | No role-based ingress action; receive the route with OTC. |
| Yes | Provider (configured) | Customer (inferred) | Advertise and preserve OTC. | No role-based ingress action; receive the route with OTC. |
| No | Provider (inferred) | Customer (configured) | No role-based egress action; advertise without OTC. | Add the remote Provider AS number as OTC (IR3). |
| Yes | Provider (inferred) | Customer (configured) | No role-based egress action; advertise with OTC unchanged. | Accept the route with OTC unchanged. |
| No | Customer (configured) | Provider (configured) | Advertise without adding OTC. | Accept the route without OTC. |
| Yes | Customer (configured) | Provider (configured) | Do not advertise the route (ER2). | If received contrary to ER2, make the route ineligible (IR1). |
| No | Customer (configured) | Provider (inferred) | Advertise without adding OTC. | No role-based ingress action; receive the route without OTC. |
| Yes | Customer (configured) | Provider (inferred) | Do not advertise the route (ER2). | No route is received. |
| No | Customer (inferred) | Provider (configured) | No role-based egress action; advertise without OTC. | Accept the route without OTC. |
| Yes | Customer (inferred) | Provider (configured) | No role-based egress action; advertise with OTC unchanged. | Make the route ineligible (IR1). |
| No | Peer (configured) | Peer (configured) | Add the local AS number as OTC (ER1). | Accept the route because OTC equals the remote AS. |
| Yes | Peer (configured) | Peer (configured) | Do not advertise the route (ER2). | If received contrary to ER2, accept only when OTC equals the remote Peer AS; otherwise, make it ineligible (IR2). |
| No | Peer (configured) | Peer (inferred) | Add the local AS number as OTC (ER1). | No role-based ingress action; receive the route with OTC. |
| Yes | Peer (configured) | Peer (inferred) | Do not advertise the route (ER2). | No route is received. |
| No | Peer (inferred) | Peer (configured) | No role-based egress action; advertise without OTC. | Add the remote Peer AS number as OTC (IR3). |
| Yes | Peer (inferred) | Peer (configured) | No role-based egress action; advertise with OTC unchanged. | Accept only when OTC equals the remote Peer AS; otherwise, make it ineligible (IR2). |
| No | RS (configured) | RS-Client (configured) | Add the local AS number as OTC (ER1). | Accept the route with OTC. |
| Yes | RS (configured) | RS-Client (configured) | Advertise and preserve OTC. | Accept the route with OTC unchanged. |
| No | RS (configured) | RS-Client (inferred) | Add the local AS number as OTC (ER1). | No role-based ingress action; receive the route with OTC. |
| Yes | RS (configured) | RS-Client (inferred) | Advertise and preserve OTC. | No role-based ingress action; receive the route with OTC. |
| No | RS (inferred) | RS-Client (configured) | No role-based egress action; advertise without OTC. | Add the remote RS AS number as OTC (IR3). |
| Yes | RS (inferred) | RS-Client (configured) | No role-based egress action; advertise with OTC unchanged. | Accept the route with OTC unchanged. |
| No | RS-Client (configured) | RS (configured) | Advertise without adding OTC. | Accept the route without OTC. |
| Yes | RS-Client (configured) | RS (configured) | Do not advertise the route (ER2). | If received contrary to ER2, make the route ineligible (IR1). |
| No | RS-Client (configured) | RS (inferred) | Advertise without adding OTC. | No role-based ingress action; receive the route without OTC. |
| Yes | RS-Client (configured) | RS (inferred) | Do not advertise the route (ER2). | No route is received. |
| No | RS-Client (inferred) | RS (configured) | No role-based egress action; advertise without OTC. | Accept the route without OTC. |
| Yes | RS-Client (inferred) | RS (configured) | No role-based egress action; advertise with OTC unchanged. | Make the route ineligible (IR1). |
The two roles cannot both be inferred on the same session. At least one router must have a configured local role before it can infer the remote role. Inferred is a local display convention: no Role Capability was received, and the unconfigured neighbor does not apply OTC processing of its own. An inferred role does not confirm the configuration or behavior of the remote neighbor.
3. RPL: OTC role per prefix
The otc-local-role configured under a neighbor is the default role for all prefixes on the eBGP session. Routing Policy Language (RPL) can override the default role for prefixes matched by a route policy. This allows different prefix groups on the same session to use different OTC processing. An inbound route policy selects the local role used by the ingress OTC rules for each matched prefix. An outbound route policy selects the local role used by the egress OTC rules.
The override applies to local OTC processing only. The BGP Role Capability is still negotiated once per session, so a per-prefix role is not verified with the neighbor. RFC 9234 Section 6 describes this trade-off: BGP Roles must not be configured on a session with a Complex peering relationship, and an operator who instead uses per-prefix policies has no in-band way to check that both ends agree.
3.1 Configuration
The RPL attach point is under the neighbor address-family configuration. A route policy can be attached inbound or outbound:
router bgp (local-as-number)
neighbor (neighbor-address)
address-family (ipv4-or-ipv6) unicast
route-policy (route-policy-name) (in-or-out)
!
!
!
The RPL action supports these local roles and is used inside a route policy:
route-policy otc_out
if...
set otc-local-role { customer | provider | peer | route-server-client}
else
...
endif
end-policy
An outbound set otc-local-role action selects the local role used for Egress Rule 1 and Egress Rule 2. For a matched prefix, the RPL role takes precedence over the otc-local-role configured under the neighbor.
The following example shows how RPL changes the neighbor role for one prefix. R5 has the local Customer role toward both R3 and R4. This is the default role for prefixes that do not match the policies. For 192.168.0.1/32, the inbound policy changes R5’s local role from Customer to Provider when R5 receives the route from R3. The outbound policy changes the role from Customer to Peer when R5 sends the route toward R4.

Figure 9. A route policy overrides the neighbor-level Customer role on R5 for one prefix.
Step 1: Check the default roles and behavior
R5 has the neighbor-level Customer role toward both routers:
RP/0/0/CPU0:R5# show running-config formal | include otc
router bgp 65550 neighbor 11.11.11.3 otc-local-role customer
router bgp 65550 neighbor 12.12.12.5 otc-local-role customer
Before the RPL policies are attached, the OTC-marked paths are not advertised because R5 uses its default Customer role:
RP/0/0/CPU0:R5# show bgp 192.168.0.1/32
Paths: (2 available, best #1)
Not advertised to any peer
Path #1: Received by speaker 0
Not advertised to any peer
65540 65545
11.11.11.3 from 11.11.11.3 (192.168.0.3)
Origin incomplete, localpref 100, valid, external, best, group-best
OTC-AS: 65540
Path #2: Received by speaker 0
Not advertised to any peer
65540 65545
12.12.12.5 from 12.12.12.5 (192.168.0.5)
Origin incomplete, localpref 100, valid, external
OTC-AS: 65540
Step 2: Remove the Provider role on R3
Remove R3’s neighbor-level Provider role:
router bgp 65540
neighbor 11.11.11.4
no otc-local-role provider
!
!
If this role is not removed, R3 adds OTC before it sends the route to R5. R5 then receives an already-marked route, and the test does not clearly show the inbound RPL action.
Step 3: Configure and attach the RPL policies
OTC_complex_pfx selects 192.168.0.1/32. The inbound policy makes R5 use local role Provider for that prefix when it is received from R3. The outbound policy makes R5 use local role Peer for the same prefix when it is advertised toward R4:
prefix-set OTC_complex_pfx
192.168.0.1/32
end-set
!
route-policy OTC_complex_in
if destination in OTC_complex_pfx then
set otc-local-role provider
else
pass
endif
end-policy
!
route-policy OTC_complex_out
if destination in OTC_complex_pfx then
set otc-local-role peer
else
pass
endif
end-policy
!
router bgp 65550
neighbor 11.11.11.3
address-family ipv4 unicast
route-policy OTC_complex_in in
!
!
neighbor 12.12.12.5
address-family ipv4 unicast
route-policy OTC_complex_out out
!
!
!
The policy applies these rules:
| Direction and neighbor | Match | Effective local role | Route treatment |
|---|---|---|---|
Inbound from R3 (11.11.11.3) |
192.168.0.1/32 |
Provider | R5 treats R3 as a Customer for this prefix. The unmarked route is accepted without adding OTC. |
Outbound to R4 (12.12.12.5) |
192.168.0.1/32 |
Peer | R5 treats R4 as a Peer, adds OTC-AS: 65550, and advertises the route. |
Inbound from R3 (11.11.11.3) |
Any other prefix | Customer (neighbor default) | R5 treats R3 as a Provider. If OTC is absent, R5 adds OTC-AS: 65540. |
Outbound to R4 (12.12.12.5) |
Any other prefix | Customer (neighbor default) | R5 treats R4 as a Provider. ER2 blocks the OTC-marked route. |
After the policies are attached, verify both a non-matching prefix and the matching prefix. The non-matching prefix 192.168.1.1/32 still uses the default Customer role and is not advertised. The matching prefix 192.168.0.1/32 uses the RPL roles and is advertised toward R4:
RP/0/0/CPU0:R5# show bgp 192.168.1.1/32 detail
Paths: (2 available, best #1)
Not advertised to any peer
RP/0/0/CPU0:R5# show bgp 192.168.0.1/32
Paths: (2 available, best #1)
Advertised IPv4 Unicast paths to peers (in unique update groups):
12.12.12.5
Path #1: Received by speaker 0
65540 65545
11.11.11.3 from 11.11.11.3 (192.168.0.3)
Origin incomplete, localpref 100, valid, external, best, group-best
Step 4: Verify the outbound attributes
Normal eBGP processing prepends the R5 AS number 65550 to the AS path. The Peer role selected by the outbound policy then causes ER1 to add OTC-AS: 65550:
RP/0/0/CPU0:R5# show bgp advertised neighbor 12.12.12.5
192.168.0.1/32 is advertised to 12.12.12.5
Path info:
neighbor: 11.11.11.3 neighbor router id: 192.168.0.3
valid external best
Attributes after inbound policy was applied:
next hop: 11.11.11.3
origin: incomplete neighbor as: 65540
aspath: 65540 65545
Attributes after outbound policy was applied:
next hop: 12.12.12.4
origin: incomplete neighbor as: 65540
aspath: 65550 65540 65545
OTC-AS: 65550
The output confirms that RPL overrides the neighbor-level OTC role only for the selected prefix. R4 still applies its own configured local role on ingress, so its role determines whether the received route is accepted.
4. Preserving OTC across networks
RFC 9234 requires that, once the OTC attribute has been set, it is preserved unchanged. The attribute tells each downstream eBGP neighbor that the route may be advertised only to Customers. If OTC is removed or changed, another eBGP neighbor may advertise the route to a Provider or Peer and create a route leak. Removing it also hides the information that other networks use to detect the leak. For this reason, filtering or modifying OTC weakens the protection provided by RFC 9234, as explained in Cloudflare’s article on the RFC 9234 BGP role model.