Skip to main content
  1. Network Articles/
  2. BGP Articles/

Removing Private AS Numbers in BGP (remove-private-AS)

Table of Contents

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.

SpaceRange
Two-octet64512 to 65534
Four-octet4200000000 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

ItemDetail
DirectionOutbound by default, applied as routes are advertised. IOS XR also has an inbound option that strips on receipt
ScopePer neighbor. Enable it only towards the upstream peer
SessionseBGP only
The local ASUnaffected. 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.

Example of a mixed 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.

Keeping private ASes away from the upstream peer
router bgp 100
 neighbor 10.3.4.4
  address-family ipv4 unicast
   remove-private-AS
ItemDetail
remove-private-ASStrips private AS numbers from AS_PATH when advertising to that neighbor
remove-private-AS entire-aspathStrips only when the whole AS_PATH is private. Despite the name it does not mean “strip throughout the path”
remove-private-AS inboundStrips from received UPDATEs
show bgp neighbors <peer> advertised-routesShows the AS_PATH actually being advertised

Verification on real devices

Verified on four routers running XRd 26.1.1.

Verification topology for remove-private-AS
  • 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 sees 192.168.1.0/24 originated by R1
  • A mixed AS_PATH is produced with a prepend as-path in R2’s outbound policy
RouterASTypeRole
R165001PrivateCustomer, originates 192.168.1.0/24
R264512PrivateThe customer’s upstream, also private
R3100PublicThe ISP. Removal happens here
R4200PublicUpstream. The AS_PATH is observed here

Overview of the STEPs

STEPOperationAS_PATH R3 receivesAS_PATH R4 sees
0No removal (initial state)64512 65001100 64512 65001 (leaking)
1remove-private-AS on R364512 65001100
2Mix public AS 300 in on R264512 300 65001100 300
3Switch R3 to entire-aspath64512 300 65001100 64512 300 65001
4Change the injected AS to the four-octet private 420000000164512 4200000001 65001100
5Change it to 4199999999 (one below the private range)64512 4199999999 65001100 4199999999
6Revert STEP 1 to 5 (final state)64512 65001100 64512 65001

STEP 0: private ASes are leaking

R4’s BGP table carries R1’s 65001 and R2’s 64512 as they are.

R4 show bgp (STEP 0)
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 paths

What R3 advertises to R4 shows the same thing.

R3 show bgp neighbors 10.3.4.4 advertised-routes (STEP 0)
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 paths

STEP 1: applying remove-private-AS

It is configured on R3’s neighbor statement for R4, under the address family.

R3
router bgp 100
 neighbor 10.3.4.4
  address-family ipv4 unicast
   remove-private-AS
R3 show running-config (STEP 1)
 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.

R3 show bgp neighbors 10.3.4.4 advertised-routes (STEP 1)
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 paths

R4’s table holds just 100 as well.

R4 show bgp (STEP 1)
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 paths

STEP 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.

R2
route-policy TO-R3
  prepend as-path 300 1
  pass
end-policy
R2 show rpl route-policy TO-R3 (STEP 2)
RP/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.

R3 show bgp (STEP 2)
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 paths

The AS_PATH R4 sees is 100 300. Even with a public AS in the middle, only the private ones were plucked out.

R4 show bgp (STEP 2)
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 paths

Note 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.

R3
router bgp 100
 neighbor 10.3.4.4
  address-family ipv4 unicast
   remove-private-AS entire-aspath
R3 show running-config (STEP 3)
 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 65001nothing was removed.

R4 show bgp (STEP 3)
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 paths

entire-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.

SettingTreatment of the mixed path 64512 300 65001
remove-private-ASPlucks out the private ones -> 300
remove-private-AS entire-aspathCondition 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.

R3 show bgp (STEP 4)
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 paths

The AS_PATH R4 sees is just 100. The four-octet private AS was removed as well.

R4 show bgp (STEP 4)
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 paths

STEP 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).

R3 show bgp (STEP 5)
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 paths

The AS_PATH R4 sees is 100 4199999999. Being outside the range, it stayed. The boundary in RFC 6996 is implemented as written.

R4 show bgp (STEP 5)
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 paths

STEP 6: reverting (final state)

Removing remove-private-AS from R3 and the prepend from R2 returns everything to the STEP 0 state.

R4 show bgp (final 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 paths

Summary of the verification

  • remove-private-AS strips private ASes from the advertised AS_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_PATH gets shorter (STEP 2)
  • entire-aspath removes only when the whole path is private, and does nothing for a mixed path (STEP 3)
  • Four-octet private ASes (4200000000 to 4294967294) are covered, and anything outside the range stays (STEP 4 and 5)
  • The command goes under the address-family, not directly under neighbor

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).

FileContents
..._show.txtshow 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.txtshow logging limited to that STEP
..._run.txtshow running-config at that STEP (that is, the verification config for the STEP)

STEP 0: no removal (initial state)

Routershow outputsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun
R4showlogrun

STEP 1: remove-private-AS on R3

Routershow outputsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun
R4showlogrun

STEP 2: mix public AS 300 in on R2

Routershow outputsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun
R4showlogrun

STEP 3: switch R3 to entire-aspath

Routershow outputsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun
R4showlogrun

STEP 4: change the injected AS to the four-octet private 4200000001

Routershow outputsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun
R4showlogrun

STEP 5: change it to 4199999999 (one below the private range)

Routershow outputsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun
R4showlogrun

STEP 6: revert STEP 1 to 5 (final state)

Routershow outputsyslogrunning-config
R1showlogrun
R2showlogrun
R3showlogrun
R4showlogrun

References

DocumentTitleSummary
RFC 6996Autonomous System (AS) Reservation for Private UseThe private AS number ranges: 64512-65534 for two octets, 4200000000-4294967294 for four
RFC 4271A Border Gateway Protocol 4 (BGP-4)The original specification of AS_PATH and loop detection

Related articles