Juniper: 6VPE Centralized Internet Access

I recently worked on a pilot project which aim is to provide IPv6-only global connectivity to a open wireless network. The network is mostly made of IEEE 802.11n base stations routing traffic from various mobile devices (e,g. laptops, smartphones) to outside services on the Internet. I had to address three challenges; the first being the lack of proper IPv6 support on some platforms, in particular on 'old' Android 4.x devices. The second challenge was to forward and transport the native IPv6 traffic from the clients, through the base stations and up to the nearest service provider's exit point. To address the latter I decided to leverage 6VPE on the MPLS backbone; the latter being composed of multi-vendors equipments from Cisco Systems and Juniper Networks. The label distribution protocol chosen is LDP for it's simplicity of operation and troubleshooting. Finally, and this is the topic of this article, I had to provide Internet Services to the wireless VPN instances so mobile clients can browse the web in a transparent and efficient manner, despite their physical locations and the base station they're associated with.

Figure 1 - Wireless IPv6-only Pilot Network
Wireless IPv6-only Pilot Network

The service provider's outbound PE that connects the NAT64/NAT66 translator (PLAT) is powered by a Juniper vMX router. The setup of the 6VPE configuration has been a very straightforward process, however configuring service chaining on the tail-end PE has been more challenging because of the lack of proper documentation from Juniper. In fact, I decided to use among other things RIB-Groups in order to import routes between the wireless client's VRF and a Virtual Router (VR). The virtual router FWFI-EXT (pictured on the above diagram) is the internet facing side of the NAT translators or the service chain. As PE2, which is also an edge router here, implements the internet connectivity from a dedicated virtual router, namely internet, I have to exchanges routes bidirectionally between the two instances. To do so I used:

  • RIB-Groups on the FWFI-EXT VR. RIB-Groups allow to import or export routes between a source table and one or more destination table. As a rule of thumb, you should always apply the rib-group statement on the source instance (where origin routes resides), here FWFI-EXT.
  • The next-table route statement's option. The next-table option defines which table to perform the next-hop resolution on. This is an handy feature, because in my case, it allowed me to perform the NH resolution of the default route of the FWFI-EXT table directly on the internet.inet6.0 instance's table where my transit provider's connectivity is terminated.

A Junos configuration is worth thousands words.

[edit routing-instances]
eprom@PE2# show 
FWFI {
    instance-type vrf;
    interface ge-0/0/2.200;
    route-distinguisher 10.16.255.1:1024;
    vrf-export [ VPNV6-FWFI-VRF-EXPORT VPNV4-FWFI-VRF-EXPORT ];
    vrf-target target:65515:1024;
    vrf-table-label;
    routing-options {
        rib FWFI.inet6.0 {
            static {
                route ::/0 next-hop fdd4:cb46:b68f:2::2;
            }
        }
    }
}
FWFI-EXT {
    instance-type virtual-router;
    interface ge-0/0/2.201;
    interface gr-0/0/10.10;
    routing-options {
        interface-routes {
            rib-group inet6 FWFI-EXT-TO-INTERNET-INET6;
        }
        rib FWFI-EXT.inet6.0 {
            static {
                rib-group FWFI-EXT-TO-INTERNET-INET6;
                route ::/0 next-table internet.inet6.0;
                route 2001:470:7804:b68e::/96 next-hop 2001:470:7804:b68f::2;
            }
        }                               
    }
}
internet {
    instance-type virtual-router;
    interface ge-0/0/2.101;
    interface ip-0/0/10.0;
    routing-options {
        rib internet.inet6.0 {
            static {
                route ::/0 next-hop 2001:470:1f14:84b::1;
                route 2001:470:7804:101::/64 next-hop 2001:470:7804::2;
                route 2001:470:7804:103::/64 next-hop 2001:470:7804::2;
                route 2001:470:7804::/48 discard;
            }
        } 
    }
}

[edit routing-options]
eprom@PE2# show 
rib-groups {
    FWFI-EXT-TO-INTERNET-INET6 {
        import-rib [ FWFI-EXT.inet6.0 internet.inet6.0 ];
        import-policy FWFI-EXT-TO-INTERNET-IMPORT-POLICY;
    }
}

[edit policy-options]
eprom@PE2# show 
policy-statement FWFI-EXT-TO-INTERNET-IMPORT-POLICY {
    term IMPORT-DIRECT {
        from protocol direct;
        then accept;
    }
    term IMPORT-STATIC-B68E {
        from {
            protocol static;
            route-filter 2001:470:7804:b68e::/96 exact;
        }
        then accept;
    }
}
policy-statement VPNV6-FWFI-VRF-EXPORT {
    term EXPORT-DIRECT {                
        from {
            protocol direct;
            route-filter fdd4:cb46:b68f:2::/64 exact;
        }
        then {
            community add FWFI-RT;
            accept;
        }
    }
    term EXPORT-DEFAULT {
        from {
            protocol static;
            route-filter ::/0 exact;
        }
        then {
            community add FWFI-RT;
            accept;
        }
    }
}
community FWFI-RT members target:65515:1024;

Please note the rib-group statement is applied twice. Once to import interfaces routes (protocol direct), and a second time to import the static routes from the VRF instance to the VR. The order you specify the tables and where you apply the rib-group statement is significant, You can easily make the mistake to apply the rib-group the other way around; again use the rule of thumb: Apply the rib-group on the source instance, configure the source table first, then the destination(s) table(s) inside the rib-group's arguments brackets (or arguments list).

The next-table option is relatively self-explanatory, so need to explain it further.

A look at the routing tables, show the results of the utilization of both rib-group and the next-table options. Now traffic from the mobile clients can be forward from the base stations, inside the MPLS backbone, out the provider edge (PE) router, through the NAT66/NAT64 translator and finally back a second time to the PE for egress routing toward the transit provider.

eprom@PE2> show route table FWFI.inet6.0        

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

::/0               *[Static/5] 5d 22:15:44 <---- Default route toward the NAT66 translator.
                    > to fdd4:cb46:b68f:2::2 via ge-0/0/2.200
fdd4:cb46:b68f::/64*[BGP/170] 1d 23:54:20, MED 0, localpref 100, from 10.2.255.1
                      AS path: I, validation-state: unverified
                    > via gr-0/0/10.1, Push 62
fdd4:cb46:b68f:1::/64
                   *[BGP/170] 1d 23:54:20, MED 0, localpref 100, from 10.2.255.1
                      AS path: I, validation-state: unverified
                    > via gr-0/0/10.1, Push 63
fdd4:cb46:b68f:2::/64
                   *[Direct/0] 6d 00:30:12
                    > via ge-0/0/2.200
fdd4:cb46:b68f:2::1/128
                   *[Local/0] 6d 00:30:23
                      Local via ge-0/0/2.200
fe80::206:a00:c80e:fff2/128
                   *[Local/0] 6d 00:30:23
                      Local via ge-0/0/2.200

eprom@PE2> show route table FWFI-EXT.inet6.0     

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

::/0               *[Static/5] 1d 03:07:19
                      to table internet.inet6.0 <---- NH resolution on next-table internet.inet6.0.
2001:470:7804:b68e::/96
                   *[Static/5] 1d 03:07:19
                    > to 2001:470:7804:b68f::2 via ge-0/0/2.201
2001:470:7804:b68f::/64
                   *[Direct/0] 6d 00:30:07
                    > via ge-0/0/2.201
2001:470:7804:b68f::1/128
                   *[Local/0] 6d 00:30:18
                      Local via ge-0/0/2.201
fe80::206:a00:c90e:fff2/128
                   *[Local/0] 6d 00:30:18
                      Local via ge-0/0/2.201

eprom@PE2> show route table internet.inet6.0 

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

::/0               *[Static/5] 1w1d 08:51:02
                    > to 2001:470:1f14:84b::1 via ip-0/0/10.0
                    [Static/5] 1d 03:07:29
                      to table internet.inet6.0
2001:470:1f14:84b::/64
                   *[Direct/0] 1w1d 08:51:02
                    > via ip-0/0/10.0
2001:470:1f14:84b::2/128
                   *[Local/0] 1w1d 08:51:33
                      Local via ip-0/0/10.0
2001:470:7804::/48 *[Static/5] 1d 04:41:40
                      Discard
2001:470:7804::/64 *[Direct/0] 1w1d 08:50:51
                    > via ge-0/0/2.101
2001:470:7804::1/128
                   *[Local/0] 1w1d 08:51:02
                      Local via ge-0/0/2.101
2001:470:7804:101::/64
                   *[Static/5] 1w1d 08:50:51
                    > to 2001:470:7804::2 via ge-0/0/2.101
2001:470:7804:103::/64
                   *[Static/5] 1w1d 08:50:51
                    > to 2001:470:7804::2 via ge-0/0/2.101
2001:470:7804:b68e::/96 <---- Imported static route from FWFI-EXT.inet6.0 table.
                   *[Static/5] 1d 03:07:29
                    > to 2001:470:7804:b68f::2 via ge-0/0/2.201
2001:470:7804:b68f::/64 <---- Imported direct route from FWFI-EXT.inet6.0 table.
                   *[Direct/0] 5d 22:20:59
                    > via ge-0/0/2.201
2001:470:7804:b68f::1/128
                   *[Local/0] 5d 22:20:59
                      Local via ge-0/0/2.201
[ cut for brevity ]

Careful readers may have noticed the use of IPv6 Unique Local Addresses (ULAs). I deliberately chose to address the whole private side of the network out of a randomly-generated ULA prefix so the infrastructure and clients addressing stay independent of the transit provider's assigned address block. I can now easily traffic engineer the traffic to use another exit point or several stateless translators for load-balancing or scalability purpose.

About the author Nicolas Chabbey

Nicolas Chabbey is a Network Engineer certified with Cisco Systems and Juniper Networks. He has begun his career in 2003, and has designed, implemented and maintained networks for enterprises and service providers. When he is not behind a computer, he is riding his mountain bike across the Swiss alps.

Previous Home

Comments

blog comments powered by Disqus