Skip navigation

In my previous post, we saw the theory behind hub-and-spoke VPN. We saw how H/S involves multiple VRFs with cross-importation between them, and we traced the basic flow of a route advertised from one spoke to another.
Next, we are going to look at two options for configuring H/S VPNs. In this post, I will cover using BGP as the PE-CE routing protocol without independent route reflectors. In my next post, I will cover OSPF. Finally, I will return to BGP and examine the issues that come up when we use independent route reflectors with hub and spoke VPN.

Review

To review, let’s examine our setup. R5 is the hub PE, which has two separate links to the Hub CE, R2. These can be physically separate or different logical units on the same physical interface. In my lab, they are two physical interfaces. We have two spokes in this lab, although there is no reason you can’t use more. Each spoke has a PE and a CE router.
hs-bgp
Note: This is part of a larger lab, but I have extracted only the relevant part. This is why the router numbering does not start at 1. Also note that in my labs, the last octet of the router’s IP address equals the router number. This should help in decoding the outputs.

For my initial configuration, I have MPLS enabled with RSVP, and LSPs are established between R5 and the spoke PEs. Since H/S VPN does not allow spoke-to-spoke traffic, I don’t bother with a spoke-to-spoke LSP. R5 is acting as a route-reflector for the spokes, but notice that it is in the path of the traffic flow. We’ll see that there are some more issues when the RR is not in the path. Although not strictly necessary, we are going to look at the worst case, with the hub CE and both spokes all being in the very same AS.

Configuring the spokes

To begin, I configure my Spoke 1 CE to peer with its PE via BGP, exporting its loopback, which will be our test prefix:

[edit]
root@r9# set routing-options autonomous-system 65100 
root@r9# set protocols bgp group external neighbor 172.20.109.10 
root@r9# set protocols bgp group external export to-bgp             
root@r9# set protocols bgp group external peer-as 100               

Note: You do not need to set type “internal” or “external” explicitly. Junos will determine that based on the local and remote AS numbers.

Next, we define a VRF on the Spoke 1 PE router, and peer via BGP to the CE:

root@r10# edit routing-instances vrf1 
root@r10# set instance-type vrf 
root@r10# set interface ge-0/0/1.0 
root@r10# set protocols bgp group spoke1 peer-as 65100 
root@r10# set protocols bgp group spoke1 neighbor 172.20.109.9 

Now this configuration should be familiar if you have worked with MPLS VPNs. If you haven’t, you need to review them before reading this article. Assuming that’s not the case, you will know that this config will not commit because we need to define a few more things:

[edit routing-instances vrf1]
root@r10# set route-distinguisher 10:1 
root@r10# set vrf-import vrf1-in 
root@r10# set vrf-export vrf1-out

I’m configuring things a bit out of order so you can see that the VRF configuration is pretty basic. For an ordinary VRF, you could use a vrf-target instead of an import/export statement, but I recommend you always use import/export for layer 3 VPN on the JNCIE lab exam, since you will probably need to do some customization and tweaking of your policies. Regardless, for H/S VPN you must use import/export policies. The really interesting part of the H/S config is in the policy-options stanza:

root@r10# show policy-options | display set 
set policy-options policy-statement vrf1-in term 1 from community hub
set policy-options policy-statement vrf1-in term 1 then accept
set policy-options policy-statement vrf1-out term 1 from protocol bgp
set policy-options policy-statement vrf1-out term 1 then community add spoke
set policy-options policy-statement vrf1-out term 1 then accept
set policy-options community hub members target:100:2
set policy-options community spoke members target:100:1

Here we can see the cross-importation that was described in the previous article. This VRF imports routes carrying a different community than it uses to export. We import “hub” routes but export “spoke” routes. You will, of course, want to be sure the community values are the same across all hub and spoke routers. All spoke routers will be tagged using the same spoke community, i.e., there is not a different community for each spoke.
Note: Note well that while there is only one VRF target-type community for both spokes, if we do Site-of-Origin filtering we will need to have additional origin-type communities, which will be unique to the particular spoke.
As you can imagine, the configuration for Spoke 2 is identical, other than the IP addresses. Remember, we are using AS 65100 at all sites, hub or spoke. (The “provider” network is using AS 100.)

Configuring the hub

Recall that the hub has not one, but two VRFs. We’ll begin the hub configuration with the policy-options, which I’ll show in “set” format here:

root@r5# show policy-options | display set 
set policy-options policy-statement hub-out term 1 from protocol bgp
set policy-options policy-statement hub-out term 1 then community add hub
set policy-options policy-statement hub-out term 1 then accept
set policy-options policy-statement null then reject
set policy-options policy-statement spoke-in term 1 from community spoke
set policy-options policy-statement spoke-in term 1 then accept
set policy-options community hub members target:100:2
set policy-options community spoke members target:100:1

A few things to notice:

1. We created a policy-statement called “null” that just rejects everything. It will be used in both VRFs.
2. The spoke-in policy is for the spoke VRF. Notice at the hub that we import routes with the spoke community. Do you remember what community we used on the spokes to export? Spoke. So the routes exported by the spokes will be imported into this VRF.
3. The hub-out policy is for the hub VRF. As we will see, and as we saw in the last article, the hub VRF learns routes from the Hub CE via PE-CE BGP. It does not import any routes from MBGP. The routes it learns are advertised back to the spokes. What do the spokes import? Routes with the “hub” community, of course!

Now we will define our VRFs. Let’s start with the spoke VRF:

[edit]
root@r5# edit routing-instances spoke 
[edit routing-instances spoke]
root@r5# set route-distinguisher 5:1 
root@r5# set instance-type vrf 
root@r5# set vrf-import spoke-in 
root@r5# set vrf-export null        
root@r5# set interface ge-0/0/2.0 
root@r5# commit check 
configuration check succeeds

Note that the configuration check succeeds because we have already defined our policies. This is a basic VRF configuration with a catch: While we import spoke-tagged routes, we export nothing. Next we need to define a BGP peering in this VRF:

[edit routing-instances spoke]
root@r5# set protocols bgp group spoke peer-as 65100 
root@r5# set protocols bgp group spoke neighbor 10.1.25.2

This is the PE-CE peering to the Hub CE. Remember that the Hub CE has two interfaces connecting it to the Hub PE; one of them learns routes from the PE, the other sends routes to the PE. Now, on to the hub VRF.

[edit routing-instances spoke]
root@r5# up    

[edit routing-instances]
root@r5# edit hub 

[edit routing-instances hub]
root@r5# set instance-type vrf 
root@r5# set interface ge-0/0/7.0 
root@r5# set route-distinguisher 5:2 
root@r5# set vrf-import null 
root@r5# set vrf-export hub-out 
root@r5# set protocols bgp group hub peer-as 65100 
root@r5# set protocols bgp group hub neighbor 10.1.52.2 
root@r5# commit 
commit complete

This is another basic VRF, but now the import is null and the export is hub-out. Notice that I defined a second BGP peering. This is a peering to the exact same CE router, just on a different interface and in a different VRF! I repeat myself often so that you’ll learn.

On the Hub CE, we’ll configure a single BGP group with two peerings, yes, to the same PE router:

[edit]
root@r2# set routing-options autonomous-system 65100 
root@r2# set protocols bgp group external peer-as 100 
root@r2# set protocols bgp group external neighbor 10.1.52.5    
root@r2# set protocols bgp group external neighbor 10.1.25.5    

Looking at the results

We’ve now done the basic config, but as we’ll see, it won’t work yet. We’ll start at spoke 1 and trace our sample route, 172.255.255.9/32 through the network. Remember, this route should be advertised as follows:

Spoke 1 CE->Spoke 1 PE->Hub PE->Hub CE->Hub PE->Spoke 2 PE->Spoke 2 CE

Our Spoke 1 PE sees the route from its CE:

root@r10> show route table vrf1.inet.0 | find 255.9 
172.255.255.9/32   *[BGP/170] 1d 01:26:21, localpref 100
                      AS path: 65100 I, validation-state: unverified
                    > to 172.20.109.9 via ge-0/0/1.0

Next, we can see that our Hub PE receives it and is pointing out the correct LSP:

root@r5> show route table spoke.inet.0 | find 255.9 
172.255.255.9/32   *[BGP/170] 00:13:29, localpref 100, from 10.255.255.10
                      AS path: 65100 I, validation-state: unverified
                    > to 10.1.105.10 via ge-0/0/4.0, label-switched-path r5-to-r10

So far so good. Next, we expect to see it on the Hub CE:

root@r2> show route protocol bgp 
inet.0: 12 destinations, 12 routes (12 active, 0 holddown, 0 hidden)
root@r2>

Not so good. What happened? Recall that in this example, we are using the same ASN for all three sites. Why are we doing this? Well, it might be that way on a test. BGP is smart enough not to advertise the route back to the Hub CE since it is in the same AS (65100) that originated the route. The easiest solution is simply to have the PE rewrite the ASN with its own:

[edit routing-instances spoke]
root@r5# set protocols bgp group spoke as-override

And now we see it on r2, the hub CE:

root@r2> show route protocol bgp    
172.255.255.9/32   *[BGP/170] 00:01:43, localpref 100
                      AS path: 100 100 I, validation-state: unverified
                    > to 10.1.25.5 via ge-0/0/2.0

Now, we expect the route will be advertised from the hub CE to the hub PE, but something’s amiss:

root@r2> show route advertising-protocol bgp 10.1.52.5           
root@r2>

What’s going on here? Well, once again we are running into AS looping problems. Our hub CE knows full well that its neighbor is in AS 100 and would drop any route that arrives via BGP with the same ASN. So, r2 does the kindly thing and doesn’t bother to advertise it. We can change this behavior with the advertise-peer-as option:

root@r2> configure
root@r2# set protocols bgp group external advertise-peer-as 
root@r2# commit and-quit 
commit complete
Exiting configuration mode
root@r2> show route advertising-protocol bgp 10.1.52.5    
inet.0: 13 destinations, 13 routes (13 active, 0 holddown, 0 hidden)
  Prefix                  Nexthop              MED     Lclpref    AS path
* 172.255.255.9/32        Self                                    100 100 I

So, the route is now being advertised from our CE back to the hub PE. We should see it there, right?

root@r5> show route table hub.inet.0 protocol bgp 
hub.inet.0: 2 destinations, 2 routes (2 active, 0 holddown, 0 hidden)
root@r5>

No, repeat after me: nothing comes easy with hub and spoke VPN. Look at the previous example, where the route is visible on R2. AS 100 is in the path twice, which means it looks like a loop. BGP will not use this route. In order to make this work, we need to tell Junos it’s ok to have loops:

root@r5# set routing-options autonomous-system 100 loops 5   
root@r5# run clear bgp neighbor
root@r5# run show route table hub.inet.0 protocol bgp    
172.255.255.9/32   *[BGP/170] 00:00:38, localpref 100
                      AS path: 65100 100 100 I, validation-state: unverified
                    > to 10.1.52.2 via ge-0/0/7.0

Note that we had to reset our BGP neighbor for this to work. I could have reset it individually, but I was lazy and did all of them. I need to apply this configuration on all of the service provider routers; otherwise, the spokes will reject the route.

We have one last thing to do before our route makes it to the Spoke 2 CE—we have to enable as-override on the Spoke 2 PE. Remember, we are using the same ASN at all sites, and this route has 65100 in the AS path. After enabling it, we can see our route has made it all the way through:

root@r8> show route protocol bgp 
inet.0: 9 destinations, 9 routes (9 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
172.255.255.9/32   *[BGP/170] 00:00:03, localpref 100
                      AS path: 100 100 100 100 I, validation-state: unverified
                    > to 172.21.68.6 via ge-0/0/1.0
root@r8>

Now in order to have bidirectional traffic, of course, R8 needs to advertise its route(s) back in exactly the same way, so we have to make sure we replicate what we did going the other way. (E.g., Spoke 1 PE needs as-override.)

On the Hub CE, using the monitor traffic interface command, with the “b” option, we can see the traffic flowing in one interface and out the other:

Cleaning it up

Most descriptions of H/S VPN recommend a step which I haven’t implemented here. To prevent routing loops, they say you should use the Site-of-Origin community to filter routes from a spoke that were originated there. My setup works fine without SoO, but there is in fact an oddity without it:

root@r10> show route 172.255.255.9 
172.255.255.9/32   *[BGP/170] 1d 03:34:05, localpref 100
                      AS path: 65100 I, validation-state: unverified
                    > to 172.20.109.9 via ge-0/0/1.0
                    [BGP/170] 00:00:06, localpref 100, from 10.255.255.5
                      AS path: 65100 100 100 I, validation-state: unverified
                    > to 10.1.105.5 via ge-0/0/4.0, label-switched-path r10-to-r5

Here we can see that R10, the Spoke 1 PE, has two routes to the network that is being advertised by its own CE. This is because the route has been re-advertised at the hub into the hub VRF, which is the VRF that our spokes are importing from. The router doesn’t select it because its AS path is too long, but it potentially could be a problem. We can modify the spoke policy to block this and save ourselves trouble. Here is our complete policy options stanza with this done.

root@r10# show policy-options 
policy-statement vrf1-in {
    term 0 {
        from community spoke1;
        then reject;
    }
    term 1 {
        from community hub;
        then accept;
    }
}
policy-statement vrf1-out {
    term 1 {
        from protocol bgp;
        then {
            community add spoke;
            community add spoke1;
            accept;
        }
    }
}
community hub members target:100:2;
community spoke members target:100:1;
community spoke1 members origin:65100:1;

We need, of course, to do the same thing on spoke 2.

Interface routes

In my case I only advertised a single loopback address from each spoke. In the JNCIE lab, you will need to advertise a lot more. Be sure to read their instructions carefully, and pay special attention to the interface routes. Even if they don’t specifically tell you to advertise them, you would always do well to include them when constructing your routing policies.

Summary

Hub and spoke VPN is complex, and we’ve covered a lot in this article. If it seems confusing, I recommend you review the first, high-level article and then come back to this one. The actual hub and spoke scenario you might face in the lab will assuredly be more complex than this, but if you practice this scenario several times, it should be easy to extrapolate to a more complex scenario. My next article will cover hub and spoke with OSPF as the routing protocol.

To wrap-up:
• We configured basic BGP as our PE-CE protocol on the hub and spokes, and defined basic VRFs on the PEs.
• On the spoke PE’s, we defined special import/export policies such that the hubs import routes tagged with the hub community but export with the spoke policy.
• We configured two VRFs on the hub PE router, one of which imported spoke-tagged routes, while the other exported hub-tagged routes.
• We configured as-override, advertise-peer-as, and AS loops to overcome the difficulty of using the same AS in three different places.
• We configured SoO to prevent the routes from looping.

14 Comments

  1. Thanks a lot for your post. it helps me a lot to understand.

    I do have another question regarding Hub-Spoke.
    between the spoke vrf on Hub PE and Hub CE there is ebgp peer, spoke vrf will advertise all bgp prefixes(only bgp) to Hub CE by default, won´t it ? my question is, should I configure policy on Hub PE to make spoke vrf advertise all routes which are listed in spoke vrf routing table to Hub CE ? because there might be other kind of routes which are necessarily to be advertised to Hub CE and then from Hub CE to hub vrf ?

    Best Regards

    • Yes, I would agree. My example is fairly basic in order to illustrate the fundamental concepts. It is important for the exam to ensure full reachability to all the VRF prefixes. It is especially important to ensure that interface routes are reachable. Often a /30 or /31 is assigned to the interface and doesn’t make it into BGP. When these routes are missed, you can lose points on an entire section of the exam.

      • sorry, still have question:
        ” It is especially important to ensure that interface routes are reachable. Often a /30 or /31 is assigned to the interface and doesn’t make it into BGP. When these routes are missed, you can lose points on an entire section of the exam.”

        I have seen these kind of requirements a lot, for example: “please make sure that PE-CE links subnets in customer VPN are advertised to the customer reomote VPN sites”.
        i am really confused with this kind of questions, because as my understanding, the PE-CE links will not be advertised only when there is no any prefixes learned from CE, then the PE-CE links can not be advertised. but this question is placed also when there is ospf or bgp between PE-CE. and in this case, even vrf-table-label is not configured, PE-CE links are still advertised. but anyway, the answer is “to configure vrf-table-label” .

        I have left my email address there, if you do not mind, could you please send me your email address, I send you email about my questions ? I hope I am not too rude. thank you very much

        • Hmmm, I don’t think vrf-table-label has anything to do with that. You might be confused about its function, which wouldn’t be unusual, since just about everybody is confused about vrf-table-label. I’ve been meaning to do an article on it. Meantime, just think of it this way. If the requirement says PE-CE links must be advertised, check the VRF routing table and see if they’re there. If not, export them into BGP (or OSPF or whatever.) It doesn’t need to be any more complicated than that.
          Unfortunately I don’t have time for JNCIE 1:1 coaching but you can always try the Jnet forums or techexams.net, where I am sure you can get answers to your questions.

            • Linda
            • Posted June 5, 2015 at 6:36 am
            • Permalink

            Thanks a lot for your reply. I will check the question and answer again.
            Have a nice weekend!

  2. Thanks a lot for your reply. I do have several other questions, may I contact you ? it is regarding RTBH.

  3. Hi All,

    how to block spoke to spoke communication attached on the same PE,

    both spoke CEs on shared LAN connected to the PE via single interface.

    Thanks

    • it is a good question ,can any one help ?

  4. Really many thanks

  5. Nice post.

    What is the issue you refer to with route reflectors? I just tested BGP H&S with off-path route reflector and it worked OK providing loops 5 was also configured on the RR. Anything else we need to watch for?

    Thanks

    • Thanks for the kind word. Seeing as this article is a couple years old and I’m back at Cisco, I can’t really answer that. I haven’t configured H/S VPN for a long time, or even a Junos device. I had planned a follow-up article that never happened. If it’s working for you then great!

    • oscar deniz jensen
    • Posted September 20, 2019 at 2:06 pm
    • Permalink
    • Reply

    Hej

    I have a problem with Hub and Spoke when using a Route Reflector in my network.

    I can see that Hub is indeed advertising all prefixes from other sites to Route reflector, so no problems with as-loops etc. However, route reflector also receives these routes from those specific Sites as well, so it does not install other site routes coming from the Hub. And as a result Site A doesn’t have the Route of Site B or C because of vrf-import not matching.

    I would appreciate any advise on how to solve this problem. I tried _family route-target_ but failed miserably

    Regards

    • Thanks for the comment. Unfortunately, I passed the JNCIE in 2014, wrote the article in 2015, left for Cisco in 2015, and haven’t touched a Juniper device since. I remember H/S got tricky with route reflectors but I don’t remember the details and I wouldn’t know the Juniper CLI anyways. Best of luck to you.

    • If RR is not recognizing the routes as unique then check the route distinguisher. Each VRF on each PE should have a unique RD that gets prepended to the IP prefix, thus making the route unique.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.