Why private AS numbers are removed
Part of the AS number space is set aside as private AS numbers, free for use inside an organisation.
| Space | Range |
|---|---|
| Two-octet | 64512 to 65534 |
| Four-octet | 4200000000 to 4294967294 |
The ranges come from RFC 6996 (BCP).
IANA has reserved, for Private Use, a contiguous block of 1023 Autonomous System numbers from the “16-bit Autonomous System Numbers” registry, namely 64512 - 65534 inclusive.
Private AS numbers are not guaranteed to be unique. Anyone may use the same number, so they must not appear in routing information on the Internet. If they end up in an AS_PATH, two unrelated organisations can claim the same number and loop detection can misfire.
At the same time, it is common for a customer connecting to an ISP to use a private AS number: not large enough to justify a public AS number, but still wanting to speak BGP.
The ISP therefore strips the private AS numbers out of AS_PATH before advertising upstream. That is remove-private-AS.
Where it applies
| Item | Detail |
|---|---|
| Direction | Outbound by default, applied as routes are advertised. IOS XR also has an inbound option that strips on receipt |
| Scope | Per neighbor. Enable it only towards the upstream peer |
| Sessions | eBGP only |
| The local AS | Unaffected. The router’s own AS number is prepended as usual after the removal |
Used outbound, the AS_PATH the customer sees is unchanged. Only what the upstream receives changes.
Not standardized
RFC 6996 defines the ranges and nothing else; no RFC specifies the act of removing them. It is a per-implementation feature, so the details differ between vendors and versions.
The behaviour that differs most is what happens when a public AS number is mixed into the AS_PATH.
64512 65001 all private -> everything can simply be removed
64512 300 65001 public AS 300 in the middle -> how much is removed?When every AS is private, removing them all is harmless. With a public AS in the middle, removing the private ones around it reorders what is left and changes the path length. Some implementations do nothing in that case; others pluck out just the private ones.
This article checks which of the two IOS XR actually does.
Configuration on IOS XR
remove-private-AS goes under the neighbor’s address-family. It is not accepted directly under neighbor.
router bgp 100
neighbor 10.3.4.4
address-family ipv4 unicast
remove-private-AS| Item | Detail |
|---|---|
remove-private-AS | Strips private AS numbers from AS_PATH when advertising to that neighbor |
remove-private-AS entire-aspath | Strips only when the whole AS_PATH is private. Despite the name it does not mean “strip throughout the path” |
remove-private-AS inbound | Strips from received UPDATEs |
show bgp neighbors <peer> advertised-routes | Shows the AS_PATH actually being advertised |
Verification on real devices
Verified on four routers running XRd 26.1.1.
- R1 (
65001) and R2 (64512) hold private AS numbers; R3 (100) and R4 (200) hold public ones - R3 plays the ISP that hides its customers’ private ASes, with the removal applied on the session towards R4
- Each router advertises its Lo1 (
192.168.<n>.0/24). The subject is how R4 sees192.168.1.0/24originated by R1 - A mixed
AS_PATHis produced with aprepend as-pathin R2’s outbound policy
| Router | AS | Type | Role |
|---|---|---|---|
| R1 | 65001 | Private | Customer, originates 192.168.1.0/24 |
| R2 | 64512 | Private | The customer’s upstream, also private |
| R3 | 100 | Public | The ISP. Removal happens here |
| R4 | 200 | Public | Upstream. The AS_PATH is observed here |
Overview of the STEPs
| STEP | Operation | AS_PATH R3 receives | AS_PATH R4 sees |
|---|---|---|---|
| 0 | No removal (initial state) | 64512 65001 | 100 64512 65001 (leaking) |
| 1 | remove-private-AS on R3 | 64512 65001 | 100 |
| 2 | Mix public AS 300 in on R2 | 64512 300 65001 | 100 300 |
| 3 | Switch R3 to entire-aspath | 64512 300 65001 | 100 64512 300 65001 |
| 4 | Change the injected AS to the four-octet private 4200000001 | 64512 4200000001 65001 | 100 |
| 5 | Change it to 4199999999 (one below the private range) | 64512 4199999999 65001 | 100 4199999999 |
| 6 | Revert STEP 1 to 5 (final state) | 64512 65001 | 100 64512 65001 |
STEP 0: private ASes are leaking
R4’s BGP table carries R1’s 65001 and R2’s 64512 as they are.
RP/0/RP0/CPU0:R4#show bgp
Fri Sep 11 07:46:12.036 UTC
<snip>
Status codes: s suppressed, d damped, h history, * valid, > best
i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 192.168.1.0/24 10.3.4.3 0 100 64512 65001 i
*> 192.168.2.0/24 10.3.4.3 0 100 64512 i
*> 192.168.3.0/24 10.3.4.3 0 0 100 i
*> 192.168.4.0/24 0.0.0.0 0 32768 i
Processed 4 prefixes, 4 pathsWhat R3 advertises to R4 shows the same thing.
RP/0/RP0/CPU0:R3#show bgp neighbors 10.3.4.4 advertised-routes
Fri Sep 11 07:45:14.866 UTC
Network Next Hop From AS Path
192.168.1.0/24 10.3.4.3 10.2.3.2 100 64512 65001i
192.168.2.0/24 10.3.4.3 10.2.3.2 100 64512i
192.168.3.0/24 10.3.4.3 Local 100i
Processed 3 prefixes, 3 pathsSTEP 1: applying remove-private-AS
It is configured on R3’s neighbor statement for R4, under the address family.
router bgp 100
neighbor 10.3.4.4
address-family ipv4 unicast
remove-private-AS neighbor 10.3.4.4
remote-as 200
description eBGP to R4 (AS 200)
address-family ipv4 unicast
send-community-ebgp
route-policy FROM-R4 in
route-policy TO-R4 out
remove-private-AS
soft-reconfiguration inbound always
!
!64512 and 65001 are gone from the advertised AS_PATH, leaving only R3’s own 100.
RP/0/RP0/CPU0:R3#show bgp neighbors 10.3.4.4 advertised-routes
Fri Sep 11 07:50:38.328 UTC
Network Next Hop From AS Path
192.168.1.0/24 10.3.4.3 10.2.3.2 100i
192.168.2.0/24 10.3.4.3 10.2.3.2 100i
192.168.3.0/24 10.3.4.3 Local 100i
Processed 3 prefixes, 3 pathsR4’s table holds just 100 as well.
RP/0/RP0/CPU0:R4#show bgp
Fri Sep 11 07:51:35.337 UTC
<snip>
Status codes: s suppressed, d damped, h history, * valid, > best
i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 192.168.1.0/24 10.3.4.3 0 100 i
*> 192.168.2.0/24 10.3.4.3 0 100 i
*> 192.168.3.0/24 10.3.4.3 0 0 100 i
*> 192.168.4.0/24 0.0.0.0 0 32768 i
Processed 4 prefixes, 4 pathsSTEP 2: what happens when a public AS is mixed in
A public AS is inserted into the middle of the AS_PATH to create the mixed case, by prepending 300 in R2’s outbound policy.
route-policy TO-R3
prepend as-path 300 1
pass
end-policyRP/0/RP0/CPU0:R2#show rpl route-policy TO-R3
Fri Sep 11 07:54:29.823 UTC
route-policy TO-R3
prepend as-path 300 1
pass
end-policy
!The AS_PATH R3 receives is 64512 300 65001 — a public AS sandwiched between two private ones.
RP/0/RP0/CPU0:R3#show bgp
Fri Sep 11 07:55:25.880 UTC
<snip>
Status codes: s suppressed, d damped, h history, * valid, > best
i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 192.168.1.0/24 10.2.3.2 0 64512 300 65001 i
*> 192.168.2.0/24 10.2.3.2 0 0 64512 300 i
*> 192.168.3.0/24 0.0.0.0 0 32768 i
*> 192.168.4.0/24 10.3.4.4 0 0 200 i
Processed 4 prefixes, 4 pathsThe AS_PATH R4 sees is 100 300.
Even with a public AS in the middle, only the private ones were plucked out.
RP/0/RP0/CPU0:R4#show bgp
Fri Sep 11 07:56:25.699 UTC
<snip>
Status codes: s suppressed, d damped, h history, * valid, > best
i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 192.168.1.0/24 10.3.4.3 0 100 300 i
*> 192.168.2.0/24 10.3.4.3 0 100 300 i
*> 192.168.3.0/24 10.3.4.3 0 0 100 i
*> 192.168.4.0/24 0.0.0.0 0 32768 i
Processed 4 prefixes, 4 pathsNote also that the AS_PATH length shrank from 3 to 1. Removal changes the path length, which can change the outcome of best path selection.
STEP 3: entire-aspath does not do what its name suggests
With the same mixed path in place, R3’s option is changed to entire-aspath.
router bgp 100
neighbor 10.3.4.4
address-family ipv4 unicast
remove-private-AS entire-aspath neighbor 10.3.4.4
remote-as 200
description eBGP to R4 (AS 200)
address-family ipv4 unicast
send-community-ebgp
route-policy FROM-R4 in
route-policy TO-R4 out
remove-private-AS entire-aspath
soft-reconfiguration inbound always
!
!The AS_PATH R4 sees is 100 64512 300 65001 — nothing was removed.
RP/0/RP0/CPU0:R4#show bgp
Fri Sep 11 08:01:13.204 UTC
<snip>
Status codes: s suppressed, d damped, h history, * valid, > best
i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 192.168.1.0/24 10.3.4.3 0 100 64512 300 65001 i
*> 192.168.2.0/24 10.3.4.3 0 100 64512 300 i
*> 192.168.3.0/24 10.3.4.3 0 0 100 i
*> 192.168.4.0/24 0.0.0.0 0 32768 i
Processed 4 prefixes, 4 pathsentire-aspath does not mean “remove throughout the AS_PATH”; it means
remove only when the entire AS_PATH is private.
The help text on XR says exactly that: remove only if all ASes in the path are private.
This mixed path does not meet the condition, so no removal happens at all.
| Setting | Treatment of the mixed path 64512 300 65001 |
|---|---|
remove-private-AS | Plucks out the private ones -> 300 |
remove-private-AS entire-aspath | Condition not met, so nothing happens -> 64512 300 65001 |
STEP 4: four-octet private ASes count too
R3 is put back to plain remove-private-AS, and the injected AS is changed to the four-octet private 4200000001.
RP/0/RP0/CPU0:R3#show bgp
Fri Sep 11 08:05:13.578 UTC
<snip>
Status codes: s suppressed, d damped, h history, * valid, > best
i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 192.168.1.0/24 10.2.3.2 0 64512 4200000001 65001 i
*> 192.168.2.0/24 10.2.3.2 0 0 64512 4200000001 i
*> 192.168.3.0/24 0.0.0.0 0 32768 i
*> 192.168.4.0/24 10.3.4.4 0 0 200 i
Processed 4 prefixes, 4 pathsThe AS_PATH R4 sees is just 100. The four-octet private AS was removed as well.
RP/0/RP0/CPU0:R4#show bgp
Fri Sep 11 08:06:13.562 UTC
<snip>
Status codes: s suppressed, d damped, h history, * valid, > best
i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 192.168.1.0/24 10.3.4.3 0 100 i
*> 192.168.2.0/24 10.3.4.3 0 100 i
*> 192.168.3.0/24 10.3.4.3 0 0 100 i
*> 192.168.4.0/24 0.0.0.0 0 32768 i
Processed 4 prefixes, 4 pathsSTEP 5: the edge of the private range
4200000001 disappearing on its own does not distinguish “recognised as a four-octet private AS” from “the whole AS_PATH happened to be private”. So the injected AS is changed to 4199999999, one below the start of the private range (4200000000).
RP/0/RP0/CPU0:R3#show bgp
Fri Sep 11 08:10:04.296 UTC
<snip>
Status codes: s suppressed, d damped, h history, * valid, > best
i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 192.168.1.0/24 10.2.3.2 0 64512 4199999999 65001 i
*> 192.168.2.0/24 10.2.3.2 0 0 64512 4199999999 i
*> 192.168.3.0/24 0.0.0.0 0 32768 i
*> 192.168.4.0/24 10.3.4.4 0 0 200 i
Processed 4 prefixes, 4 pathsThe AS_PATH R4 sees is 100 4199999999. Being outside the range, it stayed.
The boundary in RFC 6996 is implemented as written.
RP/0/RP0/CPU0:R4#show bgp
Fri Sep 11 08:11:04.606 UTC
<snip>
Status codes: s suppressed, d damped, h history, * valid, > best
i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 192.168.1.0/24 10.3.4.3 0 100 4199999999 i
*> 192.168.2.0/24 10.3.4.3 0 100 4199999999 i
*> 192.168.3.0/24 10.3.4.3 0 0 100 i
*> 192.168.4.0/24 0.0.0.0 0 32768 i
Processed 4 prefixes, 4 pathsSTEP 6: reverting (final state)
Removing remove-private-AS from R3 and the prepend from R2 returns everything to the STEP 0 state.
RP/0/RP0/CPU0:R4#show bgp
Fri Sep 11 08:15:50.763 UTC
<snip>
Status codes: s suppressed, d damped, h history, * valid, > best
i - internal, r RIB-failure, S stale, N Nexthop-discard
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 192.168.1.0/24 10.3.4.3 0 100 64512 65001 i
*> 192.168.2.0/24 10.3.4.3 0 100 64512 i
*> 192.168.3.0/24 10.3.4.3 0 0 100 i
*> 192.168.4.0/24 0.0.0.0 0 32768 i
Processed 4 prefixes, 4 pathsSummary of the verification
remove-private-ASstrips private ASes from the advertisedAS_PATH; the router’s own AS is prepended afterwards (STEP 1)- Private ASes are plucked out even with a public AS mixed in, and the
AS_PATHgets shorter (STEP 2) entire-aspathremoves only when the whole path is private, and does nothing for a mixed path (STEP 3)- Four-octet private ASes (
4200000000to4294967294) are covered, and anything outside the range stays (STEP 4 and 5) - The command goes under the
address-family, not directly underneighbor
Verification configs and show output
At every STEP the following three kinds of output were collected from all four routers, kept in separate files per router. The verification config is the ..._run.txt file (the final state is the STEP 6 one).
| File | Contents |
|---|---|
..._show.txt | show version / show interface description / show route / show route bgp / show bgp summary / show bgp / show bgp <prefix> (four prefixes) / show bgp neighbors / show bgp update-group / advertised-routes, routes and received routes per peer / show rpl route-policy |
..._log.txt | show logging limited to that STEP |
..._run.txt | show running-config at that STEP (that is, the verification config for the STEP) |
STEP 0: no removal (initial state)
| Router | show output | syslog | running-config |
|---|---|---|---|
| R1 | show | log | run |
| R2 | show | log | run |
| R3 | show | log | run |
| R4 | show | log | run |
STEP 1: remove-private-AS on R3
| Router | show output | syslog | running-config |
|---|---|---|---|
| R1 | show | log | run |
| R2 | show | log | run |
| R3 | show | log | run |
| R4 | show | log | run |
STEP 2: mix public AS 300 in on R2
| Router | show output | syslog | running-config |
|---|---|---|---|
| R1 | show | log | run |
| R2 | show | log | run |
| R3 | show | log | run |
| R4 | show | log | run |
STEP 3: switch R3 to entire-aspath
| Router | show output | syslog | running-config |
|---|---|---|---|
| R1 | show | log | run |
| R2 | show | log | run |
| R3 | show | log | run |
| R4 | show | log | run |
STEP 4: change the injected AS to the four-octet private 4200000001
| Router | show output | syslog | running-config |
|---|---|---|---|
| R1 | show | log | run |
| R2 | show | log | run |
| R3 | show | log | run |
| R4 | show | log | run |
STEP 5: change it to 4199999999 (one below the private range)
| Router | show output | syslog | running-config |
|---|---|---|---|
| R1 | show | log | run |
| R2 | show | log | run |
| R3 | show | log | run |
| R4 | show | log | run |
STEP 6: revert STEP 1 to 5 (final state)
| Router | show output | syslog | running-config |
|---|---|---|---|
| R1 | show | log | run |
| R2 | show | log | run |
| R3 | show | log | run |
| R4 | show | log | run |
References
| Document | Title | Summary |
|---|---|---|
| RFC 6996 | Autonomous System (AS) Reservation for Private Use | The private AS number ranges: 64512-65534 for two octets, 4200000000-4294967294 for four |
| RFC 4271 | A Border Gateway Protocol 4 (BGP-4) | The original specification of AS_PATH and loop detection |
Related articles
- BGP (Border Gateway Protocol)
- BGP Messages
- BGP Neighbor States
- iBGP and eBGP
- BGP next-hop-self
- BGP Route Reflector
- BGP Path Attributes and Best Path Selection
- BGP ORIGIN Attribute
- BGP AS_PATH Attribute
- BGP NEXT_HOP Attribute
- BGP LOCAL_PREF Attribute
- BGP MED Attribute
- BGP WEIGHT Attribute
- BGP COMMUNITY Attribute
- BGP Route Aggregation (aggregate-address)
- MP-BGP (Multiprotocol Extensions)
- BGP Extended Community
- BGP Multipath (maximum-paths)
- BGP Four-Octet AS Numbers (RFC 6793)
- Removing Private AS Numbers in BGP (remove-private-AS)