16 mins read

BGP – 6PE

1. Intro

We have a small service provider which is providing IPv4 internet services. It has a really simple design with a flat OSPF network, and internal iBGP session via a Route Reflector. No MPLS at this stage.

BGP 6PE

2. Dual-Stack IPv6

Now, we are being asked to add IPv6 to our network. One way to do it is with dual-stack deployment, where IPv4 and IPv6 run simultaneously.

3. 6PE

Our service provider want’s to take advantage of MPLS, this means that we will use 6PE instead of our dual-stack deployment.

Rollback config to IPv4 only, and add 6PE instead:

### Rollback and delete the 'dual-stack' config: 

delete protocols bgp group iBGPv6
delete protocols ospf3 
delete interfaces lo0 unit 0 family inet6 
delete interfaces ge-0/0/4 unit 0 family inet6
delete interfaces ge-0/0/5 unit 0 family inet6 

### We also need to activate mpls and LDP on all routers core interfaces: 

set interfaces ge-0/0/4 unit 0 family mpls
set interfaces ge-0/0/5 unit 0 family mpls
set protocols ldp track-igp-metric
set protocols ldp transport-address router-id
set protocols ldp interface ge-0/0/4.0
set protocols ldp interface ge-0/0/5.0
set protocols ldp interface lo0.0
set protocols mpls interface lo0.0
set protocols mpls interface ge-0/0/4.0
set protocols mpls interface ge-0/0/5.0

At this stage, of course there is no more IPv6 forwarding, but how about IPv4?

### IPv4 ping works: 

root@R1# run ping 192.70.1.1 source 192.10.1.1            
PING 192.70.1.1 (192.70.1.1): 56 data bytes
64 bytes from 192.70.1.1: icmp_seq=0 ttl=60 time=6.284 ms
64 bytes from 192.70.1.1: icmp_seq=1 ttl=60 time=7.182 ms
64 bytes from 192.70.1.1: icmp_seq=2 ttl=60 time=6.174 ms
^C
--- 192.70.1.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 6.174/6.547/7.182/0.451 ms

### But, since we activated MPLS/LDP, with tcmdump we can see label forwarding: 

14:51:42.057389 MPLS (label 299776, exp 0, [S], ttl 62) IP 192.10.1.1 > 192.70.1.1: ICMP echo request, id 13322, seq 6, length 64
14:51:42.060298 MPLS (label 301008, exp 0, [S], ttl 62) IP 192.70.1.1 > 192.10.1.1: ICMP echo reply, id 13322, seq 6, length 64

### This means we can now have a BGP free core
### We can deactivate BGP on the P routers: 

root@R4# delete protocols bgp 
root@R4# commit 
root@R5# delete protocols bgp 
root@R5# commit 
root@R9# delete protocols bgp 
root@R9# commit 

### IPv4 still works:

root@R1# run ping 192.70.1.1 source 192.10.1.1    
PING 192.70.1.1 (192.70.1.1): 56 data bytes
64 bytes from 192.70.1.1: icmp_seq=0 ttl=60 time=6.333 ms
64 bytes from 192.70.1.1: icmp_seq=1 ttl=60 time=5.428 ms
64 bytes from 192.70.1.1: icmp_seq=2 ttl=60 time=42.430 ms
^C
--- 192.70.1.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 5.428/18.064/42.430/17.234 ms

Before we activate 6PE, let’s check some BGP prefixes:

### On the PE router (R3), we are receiving the IPv6 prefix from Cust-A: 

root@R3# run show route protocol bgp 

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

192.10.1.0/24      *[BGP/170] 22:59:05, localpref 100
                      AS path: 100 I, validation-state: unverified
                    >  to 17.8.1.1 via ge-0/0/1.0
192.70.1.0/24      *[BGP/170] 00:21:52, localpref 100, from 17.0.0.2
                      AS path: 700 I, validation-state: unverified
                    >  to 17.8.11.2 via ge-0/0/4.0, Push 300992

inet.3: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden)

mpls.0: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden)

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

2001:db8:10::/48   *[BGP/170] 01:00:49, localpref 100, from 17.8.1.1
                      AS path: 100 I, validation-state: unverified
                    >  to ::ffff:17.8.1.1 via ge-0/0/1.0 

### But the prefix is not crossing to the other side of the network, to the remote PE:

root@R6# run show route protocol bgp 

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

192.10.1.0/24      *[BGP/170] 00:24:55, localpref 100, from 17.0.0.2
                      AS path: 100 I, validation-state: unverified
                    >  to 17.8.13.1 via ge-0/0/2.0, Push 300400
192.70.1.0/24      *[BGP/170] 03:28:27, localpref 100
                      AS path: 700 I, validation-state: unverified
                    >  to 17.8.14.2 via ge-0/0/3.0

inet.3: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden)

mpls.0: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden)

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

2001:db8:70::/48   *[BGP/170] 03:27:54, localpref 100
                      AS path: 700 I, validation-state: unverified
                    >  to 2001:db88:8:e::2 via ge-0/0/3.0

### Let's check the RR: 

root@R2# run show route hidden 

inet.0: 35 destinations, 35 routes (35 active, 0 holddown, 0 hidden)

iso.0: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden)

mpls.0: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden)

inet6.0: 14 destinations, 14 routes (12 active, 0 holddown, 2 hidden)
+ = Active Route, - = Last Active, * = Both

2001:db8:10::/48    [BGP/170] 00:18:06, localpref 100, from 17.0.0.3
                      AS path: 100 I, validation-state: unverified
                       Unusable
2001:db8:70::/48    [BGP/170] 00:21:37, localpref 100, from 17.0.0.6
                      AS path: 700 I, validation-state: unverified
                       Unusable

### The IPv6 next hop is unusable by the route reflector: 

root@R2# run show route 2001:db8:10::/48 extensive hidden 

inet6.0: 14 destinations, 14 routes (12 active, 0 holddown, 2 hidden)
2001:db8:10::/48 (1 entry, 0 announced)
         BGP    Preference: 170/-101
                Next hop type: Unusable, Next hop index: 0
                Address: 0x7bbd5b4
                Next-hop reference count: 2, key opaque handle: 0x0, non-key opaque handle: 0x0
                Kernel Table Id: 0
                Source: 17.0.0.3
                State: <Hidden Int Ext Changed>
                Local AS: 34569 Peer AS: 34569
                Age: 27:19 
                Validation State: unverified 
                Task: BGP_34569.17.0.0.3
                AS path: 100 I 
                Accepted
                Route Label: 2
                Localpref: 100
                Router ID: 17.0.0.3
                Thread: junos-main 
                Indirect next hops: 1
                        Protocol next hop: ::ffff:17.0.0.3 ResolvState: PnhUnresolv
                        Label operation: Push 2
                        Label TTL action: prop-ttl
                        Load balance label: Label 2: None; 
                        Indirect next hop: 0x0 - INH Session ID: 0

### Resolution should happen on the inet6.3 table, but it is empty: 

root@R2# run show route table inet6.3 

[edit]
root@R2# 

root@R3# run show route table inet6.3 

[edit]
root@R3# 

We can finally implement 6PE:

### As per JunOS documentation, inet6 labeled-unicast was already added to BGP, on PE and RR: 

set protocols bgp group iBGP family inet6 labeled-unicast explicit-null

### Next, we need to activate 'ipv6-tunneling'.
### This command will basically copy IPv4 next-hops from inet.3 to inet6.3:

root@R3# set protocols mpls ipv6-tunneling 

[edit]
root@R3# commit 
commit complete

root@R3# run show route table inet6.3 

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

::ffff:17.0.0.4/128*[LDP/9] 00:00:06, metric 1000
                    >  to 17.8.11.2 via ge-0/0/4.0
::ffff:17.0.0.5/128*[LDP/9] 00:00:06, metric 2000
                    >  to 17.8.11.2 via ge-0/0/4.0, Push 300976
::ffff:17.0.0.6/128*[LDP/9] 00:00:06, metric 3000
                    >  to 17.8.11.2 via ge-0/0/4.0, Push 300992

### After doing the same on the RR and the remote PE, now we can check the RR: 

root@R2# run show route table inet6.3 

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

::ffff:17.0.0.3/128*[LDP/9] 00:00:02, metric 2000
                    >  to 17.8.9.2 via ge-0/0/3.0, Push 301008
::ffff:17.0.0.4/128*[LDP/9] 00:00:02, metric 1000
                    >  to 17.8.9.2 via ge-0/0/3.0
::ffff:17.0.0.5/128*[LDP/9] 00:00:02, metric 2000
                    >  to 17.8.9.2 via ge-0/0/3.0, Push 300976
::ffff:17.0.0.6/128*[LDP/9] 00:00:02, metric 3000
                    >  to 17.8.9.2 via ge-0/0/3.0, Push 300992

### Prefises are no longer hidden:  

root@R2# run show route protocol bgp 

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

192.10.1.0/24      *[BGP/170] 00:39:21, localpref 100, from 17.0.0.3
                      AS path: 100 I, validation-state: unverified
                    >  to 17.8.9.2 via ge-0/0/3.0, Push 301008
192.70.1.0/24      *[BGP/170] 00:42:52, localpref 100, from 17.0.0.6
                      AS path: 700 I, validation-state: unverified
                    >  to 17.8.9.2 via ge-0/0/3.0, Push 300992

inet.3: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden)

mpls.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden)

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

2001:db8:10::/48   *[BGP/170] 00:00:14, localpref 100, from 17.0.0.3
                      AS path: 100 I, validation-state: unverified
                    >  to 17.8.9.2 via ge-0/0/3.0, Push 2, Push 301008(top)
2001:db8:70::/48   *[BGP/170] 00:00:14, localpref 100, from 17.0.0.6
                      AS path: 700 I, validation-state: unverified
                    >  to 17.8.9.2 via ge-0/0/3.0, Push 2, Push 300992(top)

inet6.3: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden)

### Next-Hop resolution is now OK: 

root@R2# run show route 2001:db8:10::/48 extensive 

inet6.0: 14 destinations, 14 routes (14 active, 0 holddown, 0 hidden)
2001:db8:10::/48 (1 entry, 1 announced)
TSI:
KRT in-kernel 2001:db8:10::/48 -> {indirect(1048577)}
Page 0 idx 0, (group iBGP type Internal) Type 1 val 0x9f27480 (adv_entry)
   Advertised metrics:
     Nexthop: ::ffff:17.0.0.3
     Localpref: 100
     AS path: [34569] 100 I
     Communities:
     Cluster ID: 17.0.0.2
     Originator ID: 17.0.0.3
     Label: 2
    Advertise: 00000008
Path 2001:db8:10::
from 17.0.0.3
Vector len 4.  Val: 0
        *BGP    Preference: 170/-101
                Next hop type: Indirect, Next hop index: 0
                Address: 0x7bbece4
                Next-hop reference count: 2, key opaque handle: 0x0, non-key opaque handle: 0x0
                Kernel Table Id: 0
                Source: 17.0.0.3
                Next hop type: Router, Next hop index: 634
                Next hop: 17.8.9.2 via ge-0/0/3.0, selected
                Label operation: Push 2, Push 301008(top)
                Label TTL action: prop-ttl, prop-ttl(top)
                Load balance label: Label 2: None; Label 301008: None; 
                Label element ptr: 0x9f49e78
                Label parent element ptr: 0x9eecab0
                Label element references: 1
                Label element child references: 0
                Label element lsp id: 0
                Session Id: 14d
                Protocol next hop: ::ffff:17.0.0.3
                Label operation: Push 2
                Label TTL action: prop-ttl
                Load balance label: Label 2: None; 
                Indirect next hop: 0x8498c88 1048577 INH Session ID: 351
                State: <Active Int Ext>
                Local AS: 34569 Peer AS: 34569
                Age: 24         Metric2: 2000 
                Validation State: unverified 
                Task: BGP_34569.17.0.0.3
                Announcement bits (3): 0-KRT 2-BGP_RT_Background 3-Resolve tree 5 
                AS path: 100 I 
                Accepted
                Route Label: 2
                Localpref: 100
                Router ID: 17.0.0.3
                Thread: junos-main 
                Indirect next hops: 1
                        Protocol next hop: ::ffff:17.0.0.3 Metric: 2000 ResolvState: Resolved
                        Label operation: Push 2
                        Label TTL action: prop-ttl
                        Load balance label: Label 2: None; 
                        Indirect next hop: 0x8498c88 1048577 INH Session ID: 351
                        Indirect path forwarding next hops: 1
                                Next hop type: Router
                                Next hop: 17.8.9.2 via ge-0/0/3.0
                                Session Id: 14d
                                ::ffff:17.0.0.3/128 Originating RIB: inet6.3
                                  Metric: 2000 Node path count: 1
                                  Forwarding nexthops: 1
                                        Next hop type: Router
                                        Next hop: 17.8.9.2 via ge-0/0/3.0
                                        Session Id: 14d

### Control plane now looks ok, let's test with a ping: 

root@R1# run ping 2001:db8:70::1 source 2001:db8:10::1    
PING6(56=40+8+8 bytes) 2001:db8:10::1 --> 2001:db8:70::1
^C
--- 2001:db8:70::1 ping6 statistics ---
25 packets transmitted, 0 packets received, 100% packet loss

### We need to do one more thing. We must activate IPv6 forwarding on our core interfaces.
### We don't need a complicated addressing plan, we just need to activate link local addressing: 

root@R3# show | compare 
[edit interfaces ge-0/0/4 unit 0]
+      family inet6;
[edit interfaces ge-0/0/5 unit 0]
+      family inet6;

[edit]
root@R3# commit 
commit complete

### The same was done on all routers, all core interfaces.
### Now ping works: 

root@R1# run ping 2001:db8:70::1 source 2001:db8:10::1    
PING6(56=40+8+8 bytes) 2001:db8:10::1 --> 2001:db8:70::1
16 bytes from 2001:db8:70::1, icmp_seq=0 hlim=60 time=6.322 ms
16 bytes from 2001:db8:70::1, icmp_seq=1 hlim=60 time=5.623 ms
16 bytes from 2001:db8:70::1, icmp_seq=2 hlim=60 time=6.191 ms
^C
--- 2001:db8:70::1 ping6 statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/std-dev = 5.623/6.045/6.322/0.303 ms

### TCP Dump shows the labels being used, including the explicit null label (2): 

15:33:10.677484 MPLS (label 299776, exp 0, ttl 62) (label 2, exp 0, [S], ttl 63) IP6 2001:db8:10::1 > 2001:db8:70::1: ICMP6, echo request, id 5503, seq 4, length 16
15:33:10.679685 MPLS (label 301008, exp 0, ttl 62) (label 2, exp 0, [S], ttl 63) IP6 2001:db8:70::1 > 2001:db8:10::1: ICMP6, echo reply, id 5503, seq 4, length 16

Conclusion

There is a good chance that you will already have in place the prerequisites: BGP (inet unicast), IGP protocol (OSPF, ISIS), MPLS (LDP, RSVP or SR).

If that is the case, then you only need to add:

  • BGP -> family inet6 labeled-unicast explicit-null
  • MPLS -> mpls ipv6-tunneling
  • Interface link local -> interfaces ge-0/0/x unit 0 family inet6

External Resources:

Leave a Reply