8 mins read

BGP – Inter-AS Option C

1. Intro

BGP Option C is the most scalable Inter-AS MPLS L3VPN model. Unlike Options A and B, the PE routers exchange VPN routes directly, while the ASBRs only provide MPLS transport between the autonomous systems.

Find next our test topology for this post:

Inter-AS Option C

Our aim is to have end to end connectivity for Cust-A VRF, e.g. ping from 192.45.6.1 prefix all the way to R7 192.45.6.7.

2. RR MP-BGP to the other ISP

Between the IPS Route Reflectors (RR2 to RR8) we we will have an eBGP MP-BGP session:

  • only the inet-vpn address family (this is all we need with the other ISP RR).
  • this is an external session
  • the peer is multiple hops away, so we need ‘multihop
  • the philosophy is to keep the original next hops, so we also need ‘no-nexthop-change’
### BGP MP-BGP to the other ISP: 

set protocols bgp group Option-C type external
set protocols bgp group Option-C multihop no-nexthop-change
set protocols bgp group Option-C local-address 17.0.0.2
set protocols bgp group Option-C family inet-vpn unicast
set protocols bgp group Option-C peer-as 200
set protocols bgp group Option-C neighbor 17.0.0.8

2. BGP LU

We need to activate BGP-LU an PE, RR, ASBR:

It is the common practice and recommended to add the BGP-LU to the inet.3 table.

Theoretically, we can make the Option C working if we add the BGP-LU prefixes to the default inet.0 table. But it can because confusing to have both unicast and labeled-unicast prefixes in the same inet.0 table. In fact, JunOS will not even let you to activate both inet and labeled unicast to the same BGP neighbor:

So, the config is as follows:

3. Configure the ASBR with BGP-LU

We must be sure to capture the Loopbacks (/32 prefixes from subnet 17.0.0.0/24) and advertise them to the peer ISP:

As we can see, we are exchanging PE loopbacks (17.0.0.1 and 17.0.0.7) and RRs loopbacks (17.0.0.2 and 17.0.0.8).

4. Back to RR

If we get back to the RR, we notice that the BGP sessions is still down:

### The BGP sessions between RRs is down: 

root@R2# run show bgp summary    
[...]
Peer                     AS      InPkt     OutPkt    OutQ   Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped...
17.0.0.1                100         60         80       0       1       24:51 Establ
  bgp.l3vpn.0: 1/1/1/0
  inet.0: 0/0/0/0
  inet.3: 0/0/0/0
17.0.0.4                100          2          3       0       2           0 Establ
  inet.0: 0/0/0/0
  inet.3: 0/0/0/0
17.0.0.8                200          0          0       0       2        2:33 Active

### But we are receiving the RR8 loopback: 

root@R2# run show route 17.0.0.8 

inet.3: 7 destinations, 7 routes (7 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

17.0.0.8/32        *[BGP/170] 00:02:53, MED 2000, localpref 100, from 17.0.0.4
                      AS path: 200 I, validation-state: unverified
                    >  to 17.8.8.2 via ge-0/0/2.0, Push 300736, Push 299792(top)

This is a problem, RR8 loopback only appears in inet.3. For the TCP session to establish on the BGP port 179 we need the prefix also in inet.0.

### Configure a RIB Group to copy prefixes from inet.3 to inet.0: 

set routing-options rib-groups RIB-GLOBAL import-rib inet.3
set routing-options rib-groups RIB-GLOBAL import-rib inet.0
set routing-options rib-groups RIB-GLOBAL import-policy PS-LU-GLOBAL
set policy-options policy-statement PS-LU-GLOBAL term 1 from route-filter 17.0.0.0/24 prefix-length-range /32-/32
set policy-options policy-statement PS-LU-GLOBAL term 1 then accept
set policy-options policy-statement PS-LU-GLOBAL term DENY then reject
set protocols bgp group iBGP family inet labeled-unicast rib-group RIB-GLOBAL

### After we commit we can see the prefix also in inet.0: 

root@R2# run show route 17.0.0.8 

inet.0: 30 destinations, 30 routes (30 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

17.0.0.8/32        *[BGP/170] 00:00:05, MED 2000, localpref 100, from 17.0.0.4
                      AS path: 200 I, validation-state: unverified
                    >  to 17.8.8.2 via ge-0/0/2.0, Push 300736, Push 299792(top)

inet.3: 7 destinations, 7 routes (7 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

17.0.0.8/32        *[BGP/170] 00:06:47, MED 2000, localpref 100, from 17.0.0.4
                      AS path: 200 I, validation-state: unverified
                    >  to 17.8.8.2 via ge-0/0/2.0, Push 300736, Push 299792(top)

### And the BGP session is now UP: 

root@R2# run show bgp summary 
[...]
Peer                     AS      InPkt     OutPkt    OutQ   Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped...
17.0.0.1                100         76        103       0       1       31:59 Establ
  bgp.l3vpn.0: 1/1/1/0
  inet.0: 0/0/0/0
  inet.3: 0/0/0/0
17.0.0.4                100         22         18       0       2        7:08 Establ
  inet.0: 4/4/4/0
  inet.3: 4/4/4/0
17.0.0.8                200          5          3       0       2          19 Establ
  bgp.l3vpn.0: 1/1/1/0

### At this point we are exchanging VPN prefixes: 

root@R2# run show route receive-protocol bgp 17.0.0.8 
[...]
bgp.l3vpn.0: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden)
  Prefix                  Nexthop              MED     Lclpref    AS path
  64512:1:192.45.6.7/32                    
*                         17.0.0.7                                200 I

root@R2# run show route advertising-protocol bgp 17.0.0.8 

bgp.l3vpn.0: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden)
  Prefix                  Nexthop              MED     Lclpref    AS path
  64512:1:192.45.6.1/32                    
*                         17.0.0.1                                I

5. Final checks

Now the everything is in place and working:

root@R1# run show route table Cust-A.inet 192/8 

Cust-A.inet.0: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

192.45.6.1/32      *[Direct/0] 2d 04:38:03
                    >  via lo0.456
192.45.6.7/32      *[BGP/170] 00:04:06, localpref 100, from 17.0.0.2
                      AS path: 200 I, validation-state: unverified
                    >  to 17.8.1.2 via ge-0/0/2.0, Push 16, Push 300720, Push 299792(top)

### We can see the prefix next hop: 

root@R1# run show route table Cust-A.inet 192.45.6.7/32 detail 

Cust-A.inet.0: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden)
192.45.6.7/32 (1 entry, 1 announced)
        *BGP    Preference: 170/-101
                Route Distinguisher: 64512:1
                Next hop type: Indirect, Next hop index: 0
                Address: 0x7bbf0d4
                Next-hop reference count: 3, key opaque handle: 0x0, non-key opaque handle: 0x0
                Kernel Table Id: 0
                Source: 17.0.0.2
                Next hop type: Router, Next hop index: 676
                Next hop: 17.8.1.2 via ge-0/0/2.0, selected
                Label operation: Push 16, Push 300720, Push 299792(top)
                Label TTL action: prop-ttl, prop-ttl, prop-ttl(top)
                Load balance label: Label 16: None; Label 300720: None; Label 299792: None; 
                Label element ptr: 0x9f48f78
                Label parent element ptr: 0x9f4a3c8
                Label element references: 1
                Label element child references: 0
                Label element lsp id: 0
                Session Id: 140
                Protocol next hop: 17.0.0.7
                Label operation: Push 16
                Label TTL action: prop-ttl
                Load balance label: Label 16: None; 
                Indirect next hop: 0x791e080 1048575 INH Session ID: 334
                State: <Secondary Active Int Ext ProtectionCand>
                Local AS:   100 Peer AS:   100
                Age: 5:03       Metric2: 2000 
                Validation State: unverified 
                Task: BGP_100.17.0.0.2
                Announcement bits (1): 0-KRT 
                AS path: 200 I 
                Communities: target:64512:456
                Import Accepted
                VPN Label: 16
                Localpref: 100
                Router ID: 17.0.0.2
                Primary Routing Table: bgp.l3vpn.0
                Thread: junos-main 

### Ping now works: 

root@R1# run ping routing-instance Cust-A 192.45.6.7 
PING 192.45.6.7 (192.45.6.7): 56 data bytes
64 bytes from 192.45.6.7: icmp_seq=0 ttl=60 time=8.315 ms
64 bytes from 192.45.6.7: icmp_seq=1 ttl=60 time=15.488 ms
64 bytes from 192.45.6.7: icmp_seq=2 ttl=60 time=6.191 ms
^C
--- 192.45.6.7 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 6.191/9.998/15.488/3.978 ms

Note: In this post we are assuming both ISP agreed to use the same Route Targes for the Cust-A VPN, hence there is no need to tweak this on the RR.


External Resources:

Leave a Reply