MPLS 101 – Dynamic routing with BGP

      2 Comments on MPLS 101 – Dynamic routing with BGP

In our last post we talked about how to make the MPLS control plane more dynamic by getting rid of static LSPs and adding in LDP to help advertise and distribute LSPs to all MPLS speaking routers.  However – even once got LDP up and running, we still had to tell the routers to use a given LSP.  In the last post, we accomplished this by adding recursive static routes in the inet.0 table to force the routers to recurse to the inet.3 table where the MPLS LSPs lived.  In this post, we’re going to tackle getting rid of the static routes and focus on replacing it with a dynamic routing protocol – BGP.

So to start off with, let’s get our lab back to a place where we can start.  To do that, we’re going to load the following configuration on each router show in the following lab topology…

interfaces {
    ge-0/0/0 {
        enable;
        unit 0 {
            family inet {
                address 10.2.2.0/31;
            }
        }
    }
    ge-0/0/1 {
        enable;
        unit 0 {
            family inet {
                address 10.1.1.0/31;
            }
            family mpls;
        }
    }
    lo0 {
        unit 0 {
            family inet {
                address 1.1.1.1/32;
            }
        }
    }
}
protocols {
    mpls {
        interface ge-0/0/1.0;
    }
    ospf {
        area 0.0.0.0 {
            interface lo0.0;
            interface ge-0/0/1.0;
        }
    }
    ldp {
        interface ge-0/0/1.0;
    }
}
interfaces {
    ge-0/0/0 {
        enable;
        unit 0 {
            family inet {
                address 10.1.1.1/31;
            }
            family mpls;
        }
    }
    ge-0/0/1 {
        enable;
        unit 0 {
            family inet {
                address 10.1.1.2/31;
            }
            family mpls;
        }
    }
    lo0 {
        unit 0 {
            family inet {
                address 2.2.2.2/32;
            }
        }
    }
}
protocols {
    mpls {
        interface ge-0/0/0.0;
        interface ge-0/0/1.0;
    }
    ospf {
        area 0.0.0.0 {
            interface lo0.0;
            interface ge-0/0/0.0;
            interface ge-0/0/1.0;
        }
    }
    ldp {
        interface ge-0/0/0.0;
        interface ge-0/0/1.0;
    }
}
interfaces {
     ge-0/0/0 {
        enable;
        unit 0 {
            family inet {
                address 10.1.1.3/31;
            }
            family mpls;
        }
    }
    ge-0/0/1 {
        enable;
        unit 0 {
            family inet {
                address 10.1.1.4/31;
            }
            family mpls;
        }
    }
    lo0 {
        unit 0 {
            family inet {
                address 3.3.3.3/32;
            }
        }
    }
}
protocols {
    mpls {
        interface ge-0/0/0.0;
        interface ge-0/0/1.0;
    }
    ospf {
        area 0.0.0.0 {
            interface ge-0/0/0.0;
            interface ge-0/0/1.0;
            interface lo0.0;
        }
    }
    ldp {
        interface ge-0/0/0.0;
        interface ge-0/0/1.0;
    }
}
interfaces {
    ge-0/0/0 {
        enable;
        unit 0 {
            family inet {
                address 10.1.1.5/31;
            }
            family mpls;
        }
    }
    ge-0/0/1 {
        enable;
        unit 0 {
            family inet {
                address 10.2.2.2/31;
            }
        }
    }
    lo0 {
        unit 0 {
            family inet {
                address 4.4.4.4/32;
            }
        }
    }
}
protocols {
    mpls {
        interface ge-0/0/0.0;
    }
    ospf {
        area 0.0.0.0 {
            interface ge-0/0/0.0;
            interface lo0.0;
        }
    }
    ldp {
        interface ge-0/0/0.0;
    }
}

You’ll notice that these base configurations include configuration for not only the interfaces, but also OSPF, LDP, and MPLS.  Basically we’ve configured everything we had in the last post with the exception of the static routes.  At this point, client 1 and client 2 will not be able to communicate to one another.  So let’s now look at how we configure BGP.

You might recall that I mentioned in a previous post that BGP was interesting in the regard that it could list a next hop for a destination prefix that was not directly connected to the router.  This is because BGP can leverage recursion which is exactly what we had been doing with the static routes in the previous two posts.  So let’s go ahead and setup a BGP peering to try and replace what we leveraged with static routes previously.  The first thing we need to do is define what our BGP peers will be and in what AS (autonomous system) they each reside in.  In our case, to keep things simple initially, we’re going to put all of our peers in the same AS (65000) for now.  As for the peers, we’re going to peer router 1 to router 4.  You might be wondering why we aren’t peering routers 2 and 3 with anything.  Recall that those are MPLS P routers and don’t require any knowledge of the actual prefixes they are passing traffic for.

protocols {
    bgp {
        group ibgp {
            type internal;
            family inet {
                unicast;
            }
            peer-as 65000;
            neighbor 4.4.4.4 {
                local-address 1.1.1.1;
            }
        }
    }
}
routing-options {
    router-id 1.1.1.1;
    autonomous-system 65000;
}
protocols {
    bgp {
        group ibgp {
            type internal;
            family inet {
                unicast;
            }
            peer-as 65000;
            neighbor 1.1.1.1 {
                local-address 4.4.4.4;
            }
        }
    }
}
routing-options {
    router-id 4.4.4.4;
    autonomous-system 65000;
}

If you’re familiar with BGP, then there shouldn’t be anything terribly new for you here.  Juniper configuration breaks the configuration into groups.  In my case, I have a single group called ibgp in which I define the type of peering that Im working with internal as well as my neighbor, the local address I want to talk to that neighbor on, and the peer autonomous system.  Juniper also breaks out the AS and router-id into the routing-options stanza which can take some getting used to if you’re used to working on other platforms.

Now that its configured, we should be able to check and see that we have a BGP peering between router 1 and router 4…

root@vmx1> show bgp summary 
Groups: 1 Peers: 1 Down peers: 0
Table          Tot Paths  Act Paths Suppressed    History Damp State    Pending
inet.0               
                       0          0          0          0          0          0
Peer                     AS      InPkt     OutPkt    OutQ   Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped...
4.4.4.4               65000          3          2       0       1          30 0/0/0/0              0/0/0/0

root@vmx1>

Looks like the peering is up as we can see in the Up/Dwn column that we list an up time and the state is not Active.  However – we dont appear to be getting any routes.  We can see that the number of received routes is still 0.  So why is that?  Well it’s because we haven’t told BGP about any of the routes.  To do that, we need to define a routing policy that we can then have BGP reference as an export policy.  Here are two basic policies that we’ll be using in this example…

policy-options {
    policy-statement mpls_bgp {
        term routes_for_mpls {
            from {
                protocol direct;
                route-filter 10.2.2.0/31 exact;
            }
            then accept;
        }
        then reject;
    }
}
protocols {
    bgp {
        group ibgp {
            export mpls_bgp;
        }
    }
}
policy-options {
    policy-statement mpls_bgp {
        term routes_for_mpls {
            from {
                protocol direct;
                route-filter 10.2.2.2/31 exact;
            }
            then accept;
        }
    then reject;
    }
}
protocols {
    bgp {
        group ibgp {
            export mpls_bgp;
        }
    }
}

If you’re not familiar with Juniper policies (terms, from, then, etc) I’d suggest you spend some time reading through the Juniper Day One: Configuring Junos Policy and Firewall Filters eBook.  It’s a great read and has lots of good examples.  While the logic may seem basic at first, I assure you that there are lots of places you can shoot yourself in the foot if you don’t understand the defaults and the means in which routers process policy.  So let’s walk through the above policy logic as applied on router 1 briefly…

  • We start with a policy-statement called mpls_bgp
    • This has a term defined in it called the routes_for_mplswhich defines two match criteria…
      • Routes that are from the protocol direct which are routes the router believes to be directly connected
      • Routes that match a route filter looking for the exact prefix 10.2.2.0/31
      • If the two above requirements are met, we proceed to the thenaction which is to accept or allow the advertisement.
    • If the above term is not matched, the policy has a default action to reject

Pretty straight forward right?  Then all we do is apply the routing-policy to the BGP process by tagging it as the export policy underneath the BGP protocol stanza.  If you’re following along and have applied the policy to both routers you should see that client 1 can now ping client 2 once again.  We can also do some validation on the routers to validate they have the appropriate prefixes…

root@vmx1> show route table inet.0 10.2.2.2/31 

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

10.2.2.2/31        *[BGP/170] 00:11:32, localpref 100, from 4.4.4.4
                      AS path: I, validation-state: unverified
                    > to 10.1.1.1 via ge-0/0/1.0, Push 299936

root@vmx1> 

root@vmx1> show route table inet.3 

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

2.2.2.2/32         *[LDP/9] 5d 18:14:18, metric 1
                    > to 10.1.1.1 via ge-0/0/1.0
3.3.3.3/32         *[LDP/9] 5d 18:14:18, metric 1
                    > to 10.1.1.1 via ge-0/0/1.0, Push 299920
4.4.4.4/32         *[LDP/9] 5d 18:14:18, metric 1
                    > to 10.1.1.1 via ge-0/0/1.0, Push 299936

root@vmx1>

First we look to ensure that we see the destination prefix that client 2 is a member of (10.2.2.2 /31) on router 1. We see that we do in fact have a routing entry for the 10.2.2.2/31 prefix and that it lists it coming from 4.4.4.4 (router 4).  We also see that recursion has occurred and router 1 has gleaned the MPLS information from the inet.3 table in order to know what MPLS label to push onto the traffic.  With that information, as well as the next-hop interface and IP to reach 4.4.4.4 from OSPF (10.1.1.1 and ge-0/0/1.0) we have all the information we need to send the traffic on its way towards client 2.  We can also validate that we’re advertising the 10.2.2.0/31 prefix to router 4 by using the advertising-protocol command syntax on router 1…

root@vmx1> show route advertising-protocol bgp 4.4.4.4 

inet.0: 15 destinations, 15 routes (15 active, 0 holddown, 0 hidden)
  Prefix		  Nexthop	       MED     Lclpref    AS path
* 10.2.2.0/31             Self                         100        I

root@vmx1>

As before – the advantage here is that routers 2 and 3 have no idea about the prefixes which routers 1 and 4 are advertising to each other…

root@vmx2> show route table inet.0 10.2.2.0/31 

root@vmx2> show route table inet.0 10.2.2.2/31    

root@vmx2>

So at this point, the only thing we’d need to do is add any additional prefixes to the routing-policy in order to have BGP dynamically advertise them to the other BGP peer.  This doesn’t buy us too much in over what we had with static routes, but it does setup us up to talk about the topic for our next post – VPNv4 with MPLS.  Stay tuned!

2 thoughts on “MPLS 101 – Dynamic routing with BGP

Leave a Reply

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