Category Archives for "Das Blinken Lichten"

Multipath routing with VPNv4

When we talk about VPNv4 prefixes – Route Distinguishers (RDs) play an incredibly important role in ensuring multipath routing. We talked about this a little bit in our last post, but I want to hit it home in this post as well as cover a couple of other items in a little great detail.

To start with, we’re going to use our same physical lab topology, but changes things up slightly. Namely….

  • vMX7 will remain a BGP route reflector but will also now participate in the dataplane by having it’s interfaces enabled with LDP and MPLS
  • vMX1 and vMX3 will act as remote PEs for our provider that are hosting an anycast service. Both will be advertising into a “Provider” VPN which we will then import into our customer VPN.
  • vMX2 will now act like a Customer Edge (CE) router peering to vMX5 which will act as the provider edge (PE) router. It will peer with the provider in AS65000 from AS12345.

So our diagram will now look something like this…

Alright. So for the sake of thoroughness, I’ll start by including our base configurations again since they did change ever so slightly, and I Continue reading

Understanding RTs and RDs

One of the items that continues to come up in my conversations with folks learning about about MPLS VPNs is defining what a Route Target (RT) and Route Distinguisher (RD) are. More specifically, most seem to understand their purpose – but often times they don’t quite understand the application. I (and many others – just google “Understanding RDs and RTs”) have written about this in the past but Im hoping to put a finer point on the topic in this post.

If someone were to ask me to summarize what route targets and route distinguishers were – I’d probably define them like this…

Route Distinguishers – serve to make routes unique
Route Targets – metadata used to make route import decisions

Now – I’ll grant that those definitions are awfully terse, but I also feel like this is a topic that is often over complicated. So let’s spend some time talking about RTs and RDs separately and then bring it all together in a lab so you can see what’s really happening.

Route Distinguishers

As I said, a route distinguisher serve to make routes look unique. So why do we care about making routes look unique? I’d argue one of Continue reading

ExaBGP and etcd – processing routes

In my last post – we took a look at how we could leverage etcd from Python. In this post, I want to propose a use for leveraging etcd as a sort of message bus for ExaBGP. We saw some pretty compelling features with etcd that I think can work nicely in our ExaBGP model. So without further blabbering – let’s start coding.

Note: I assume you have a local instance of etcd installed and it is currently empty. If it’s not empty – you’ll want to clear it all out using a command like this ETCDCTL_API=3 etcdctl del "" --from-key=true

If you recall – in our last post on ExaBGP we were at a point where the ExaBGP process was using two Python programs we wrote. One for processing received routes ( and one for sending route updates ( My goal here it to remove a lot of the logic for static route processing from these two scripts and make them more about route processing. More specifically – I want to turn the two Python scripts that ExaBGP is running on our behalf into simple programs that read/write to to/from etcd. Once we Continue reading

Python Pieces – Working with etcd

Ah ha! Surprise – I’ve decided that in addition to the blog posts on MPLS and ExaBGP that I might as well start up a third series. Well – that’s not entirely true – but instead of trying to mix all sorts of details about Python into the blog posts, I thought I might split out some of the larger pieces. So Im starting a new series called “Python Pieces” where I’m going to pick one module, concept, or whatever else I decided warrants a post and talk about how to use it. Then – if/when I use that in one of my other posts – you’ve got a handy reference and starting point. I hope this makes the other posts less “all over the place” but we’ll see.

So – in my first edition of Python Pieces we’re going to talk about working with etcd from Python. For those of you that don’t know what etcd is – it’s a pretty popular key value store that’s used with lots of the more recent projects (Kubernetes comes to mind). What’s likely more important about etcd though is that it’s capable of being a distributed key value store which makes it Continue reading

ExaBGP – handling route withdrawal

In our last post we talked about how we can programmatically talk and listen to ExaBGP. By the end of the post, our Linux server was listening for BGP updates, processing them, and creating static routes based on the information it learned. We worked through some issues to get that far – but also recognized that we had a ways to go. In this post, we’ll start tackling some of the other issues that are lingering with this implementation. So let’s dive right in and start knocking these out!

The first issues I want to talk about isn’t actually an issue anymore – but it’s worth mentioning since we sort of solved it accidentally. At this point – we’ve only processed BGP update messages that have included a single router advertisement. Said more specifically – BGP update messages that included a single NLRI. A BGP update message can (and will) contain multiple NLRI’s so long as the path attributes are the same for all the prefixes. For folks not familiar with BGP – NLRI (Network layer reachability information) are basically the routes or prefixes that are being sent to us. If we go back and look at the BGP update Continue reading

Building static routes with ExaBGP

In our last post we covered the basic setup and configuration of ExaBGP. While we were able to make use of ExaBGP for dynamic route advertisement, it wasn’t able to help us when it came to actually programming the servers routing table. In this post, I want to show you how you can leverage ExaBGP from a more programatic perspective. We’ll start by handling route advertisement to our peer and then tackle reading and processing received route updates. We’ll also start using another Python module (pyroute2) to program the routing table of the bgp_server host so that it begins acting more like a normal router. Enough talk – let’s dive in!

Im going to assume you’re starting off at the end of the last post. So the first thing we need to do is clean up a couple of items. We’re not going to rely on the static route we provisioned so to clean that up we can simply reapply the netplan network configuration using the command sudo netplan apply

[email protected]_peer:~$ ip route
default via dev ens3 proto static dev ens7 proto kernel scope link src 
10. Continue reading

Working with ExaBGP 4

One of my goals this year was to spend more time doing Python development so I thought I’d take a break from the MPLS deep dives (no worries – there are still lots more coming) and insert some development type things along the way. One of the opensource projects I’ve used in the past was ExaBGP by the folks over at Exa-Networks. Since then – they’ve released a new version (4) and I’ve been keen to play around with it some more.

The last time I played with ExaBGP was strictly from a testing perspective. This time – I want to focus on some use cases that are closer to real life. Things you might actually do – or at the very least – try. So to start things off – we’re going to once again start with a basic lab that looks like this…

So here we have our 2 friendly end users connected at the head to a small simple network. left_user is attached to an Ubuntu 18 server called ‘bgp_peer’ which is then connected to two other routers (Juniper vMX) and finally our friendly right_user. To start with – we’re going to configure the routers vMX1 and Continue reading

Understanding CSPF and the TED

In our last post, we talked about one of the major differences between LDP and RSVP – the ability to define EROs or explicit route objects. We demonstrated how we could configure LSP paths through our network by providing a set of loose or strict next hops for the LSP to take. This was a rather huge paradigm shift because it meant we could define paths that didn’t align with what the IGP thought to be the best path through the network. What we didn’t talk about was how the ingress router determined if these paths were feasible. In this post, we’ll deep dive on the traffic engineering database (TED) and how it works in conjunction with the constrained shortest path first (CSPF) algorithm to build RSVP LSPs through a network.

It’s important to remember that the ingress label switching router (LSR) is really the thing doing most of the work in regards to setting up RSVP LSPs. Well – to be fair – the egress LSR is the one that actally sends the RESV message back toward the ingress LSR with the label information which is what’s required for the LSP to work. However – the ingress LSR Continue reading

Understanding RSVP EROs

In our last post we covered the basics of getting an RSVP LSP setup. This was a tedious process at least when compared to what we saw with LDP setting up LSPs. So I think it’s worthwhile to spend some time talking about RSVP and what it offers that merit it’s consideration as a label distribution protocol. First off – let’s talk about naming. When talking about MPLS – RSVP is typically just called RSVP – but without the MPLS context – it might be a little confusing. That’s because RSVP itself initially had nothing to do with MPLS. RSVP was initially a means to reserve resources for flows across a network. The protocol was then extended to support setting up MPLS LSPs. In this use case, it is often referred to as “RSVP-TE” or “MPLS RSVP-TE”. For the sake of my sanity – when I reference RSVP going forward I’ll be referring to RSVP that’s used to setup MPLS LSPs.

So now let’s talk about some differences between LDP and RSVP. The first thing that everyone points out is that LDP is tightly bound to the underlying IGP. While this is an accurate statement, it doesn’t mean that RSVP Continue reading

Getting start with RSVP

We’ve spent a great deal of time in the last few posts talking about MPLS both with LDP and with static LSP configurations. While these approaches certainly work, they aren’t the only options to use for label distribution and LSP creation. If we take static LSPs off the table (since they’re the equivalent of static routes and not scalable) we really have two main choices for label distribution – LDP and RSVP. LDP is typically considered to be the easiest of the two options but also offers a limited set of functionality. RSVP offers many more features but also requires more configuration. When you’re designing an MPLS network you’ll have to decide which protocol to use based on your requirements. In many cases a network may leverage both in different areas. In this post the aim is just to get RSVP up and running – we’ll dig into the specifics in a later post.

So let’s get right into a simple lab where we leverage RSVP instead of LDP. Like the previous post, we’ll leverage the same lab environment…

Let’s assume as before that the base configuration of the lab includes all the routers interfaces configured, OSPF enabled on all Continue reading

LDP Multipath/ECMP

In one of our last posts on MPLS – we showed how LDP can be used to dynamically exchange labels between MPLS enabled routers. This was a huge improvement from statically configured LSPs. We saw that LDP was tightly coupled to the underlying IGP but we didn’t spend a lot of time showing examples of that. In this post, I want to extend our lab a little bit to show you exactly how tightly this coupling is. To do so, we’ll use part of the extended lab that we created at the end of our last post on the JunOS routing table. For the sake of being thorough, we’ll provide the entire configuration of each device. The lab will look like what’s shown below…

For a base configuration – we’re going to start with mostly everything there with the exception of MPLS and LDP. We’ll then add that in stages so we can see how things look before and after we have multiple IGP paths to the same destination…

vMX1 Configuration…

system {
    host-name vmx1.lab;
interfaces {
    ge-0/0/0 {
        unit 0 {
            family inet {
    ge-0/0/1 {
        unit 0 {
             Continue reading

Understanding the JunOS routing table

I was just about to finish another blog post on MPLS when I got a question from a colleague about Junos routing tables. He was confused as to how to interpret the output of a basic Juniper routing table. I spent some time trying to find some resource to point him at – and was amazed at how hard it was to find anything that answered his questions specifically. Sure, there are lots of blogs and articles that explain RIB/FIB separation, but I couldn’t find any that backed it up with examples and the level of detail he was looking for. So while this is not meant to be exhaustive – I hope it might provide you some details about how to interpret the output of some of the more popular show commands. This might be especially relevant for those of you who might be coming from more of a Cisco background (like myself a number of years ago) as there are significant differences between the two vendors in this area.

Let’s start with a basic lab that looks a lot like the one I’ve been using in the previous MPLS posts…

For the sake of focusing on the real Continue reading


In our last post, we removed our last piece of static configuration and replaced static routes with BGP.  We’re going to pick up right where we left off and discuss another use case for MPLS – MPLS VPNs.  Really – we’re talking about two different things here.  The first is BGP VPNv4 address families used for route advertisement.  The second is using MPLS as a data plane to reach the prefixes being announced by VPNv4 address family.  If that doesn’t make sense yet – don’t worry – it will be pretty clear by the end of the post.  So as usual – let’s jump right into this and talk about our lab setup.

As I mentioned in the last post, setting up BGP was a prerequisite to this post – so since that’s the case – Im going to pick up right where I left off.  So I’ll post the lab topology picture here for the sake of posting a lab topology – but if you want to get your configuration prepped – take a look at the last post.  At the end of the last post we had our Continue reading

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 {
        unit 0 {
            family inet {
    ge-0/0/1 {
        unit 0 {
            family inet {
            family mpls;
    lo0 {
        unit 0 {
            family  Continue reading

MPLS 101 – Label Distribution Protocol (LDP)

In our last post, we saw a glimpse of what MPLS was capable of.  We demonstrated how routers could forward traffic to IP end points without looking at the IP header.  Rather, the routers performed label operations by adding (pushing), swapping, or removing (popping) the labels on and off the packet.  This worked well and meant that the core routers didn’t need to have IP reachability information for all destinations.  However – setting this up was time consuming.  We had to configure static paths and operations on each MPLS enabled router.  Even in our small example, that was time consuming and tedious.  So in this post we’ll look at leveraging the Label Distribution Protocol (LDP) to do some of the work for us.  For the sake of clarity, we’re going to once again start with a blank slate.  So back to our base lab that looked like this…

Note: I refer to the devices as routers 1-4 but you’ll notice in the CLI output that their names are vMX1-4.

Each device had the following base configuration…

interfaces {
    ge-0/0/0 {
        unit 0 {
            family inet {
                address 10.2. Continue reading

2017 in review and 2018 goals

Here we are – the first day of 2018 and Im anxious and excited to get 2018 off to a good start.  Looking back – it just occurred to me that I didn’t write one of these for last year.  Not sure what happened there, but Im glad to be getting back on track.  So let’s start with 2017…

2017 was a great year for me.  I started the year continuing my work at IBM with the Watson group.  About half way through the year (I think) I was offered the opportunity to transition to a role in the Cloud Networking group.  It was an opportunity I couldn’t pass up to work with folks whom I had an incredible amount of respect for.  So I began the transition and within 3 months had fully transitioned to the new team.  Since then, I’ve been heads down working (the reason for the lack of blog posts recently (sorry!)).  But being busy at work is a good thing for me.  For those of you that know me well you know that “bored Jon” is “not happy Jon” so Im in my own Continue reading

MPLS 101 – The Basics

In this series of posts, I want to spend some time reviewing MPLS fundamentals.  This has been covered in many places many times before – but I’ve noticed lately that often times the basics are missed or skipped when looking at MPLS.  How many “Introduction to MPLS” articles have you read where the first step is “Enable LDP and MPLS on the interface” and they dont actually explain whats happening?  I disagree with that being a valid starting point so in this post I’d like to start with the basics.  Subsequent posts will build from here as we get more and more advanced with the configuration.

Warning: In order to get up and running with even a basic configuration we’ll need to introduce ourselves to some MPLS terminology and concepts in a very brief fashion.  The descriptions of these terms and concepts is being kept brief intentionally in this post and will be covered in much great depth in a future post.

Enough rambling from me, let’s get right into it…

So what is MPLS?  MPLS stands for Multi-Protocol Label Switching and it provides a means to forward multiple different protocols across a network.  To see what it’s capable Continue reading

Getting Started with Python Development

Over the last several years I’ve made a couple of efforts to become better at Python. As it stands now – I’d consider myself comfortable with Python but more in terms of scripting rather than actual Python development. What does Python Development mean? To me – at this point – it’s means writing more than a single Python file that does one thing. So why have my previous efforts failed? I think there have been a few reasons I never progressed much past scripting…

  • I didn’t have a good understanding of Python tooling and the best way to build a project. This meant that I spent a large chunk of time messing around with Python versions, packages, and not actually writing any code.  I was missing the fundamentals in terms of how to work in Python.
  • I didn’t have a real goal in mind.  Trying to learn something through ‘Hello World’ type examples doesn’t work for me.  I need to see real world examples of something I’d actually use in order to understand how it works.  I think this is likely why some of the higher level concepts in Python didn’t fully take hold on the Continue reading

Interface basics on the Juniper MX

I’ve been spending more time on the MX recently and I thought it would be worthwhile to document some of the basics around interface configuration.  If you’re like me, and come from more of a Cisco background, some of configuration options when working with the MX weren’t as intuitive.  In this post, I want to walk through the bare bone basic of configuring interfaces on a MX router.

Basic L3 interface

ge-0/0/0 {
    unit 0 {
        family inet {

The most basic interface configuration possible is a simple routed interface. You’ll note that the interface address is configured under a unit. To understand what a unit is you need to understand some basic terminology that Juniper uses. Juniper describes a physical interface as an IFD (Interface Device). In our example above the IFD would be the physical interface ge-0/0/0. We can then layer one or more IFL (Interface Logical) on top of the IFD. In our example the IFL would be the unit configuration, in this case ge-0/0/0.0. Depending on the configuration of the IFD you may be able to provision additional units. These additional units (Logical interfaces (IFLs)) Continue reading

Getting started with Calico on Kubernetes

In the last 4 posts we’ve examined the fundamentals of Kubernetes networking…

Kubernetes networking 101 – Pods

Kubernetes networking 101 – Services

Kubernetes networking 101 – (Basic) External access into the cluster

Kubernetes Networking 101 – Ingress resources

My goal with these posts has been to focus on the primitives and to show how a Kubernetes cluster handles networking internally as well as how it interacts with the upstream or external network.  Now that we’ve seen that, I want to dig into a networking plugin for Kubernetes – Calico.  Calico is interesting to me as a network engineer because of wide variety of functionality that it offers.  To start with though, we’re going to focus on a basic installation.  To do that, I’ve updated my Ansible playbook for deploying Kubernetes to incorporate Calico.  The playbook can be found here.  If you’ve been following along up until this point, you have a couple of options.

  • Rebuild the cluster – I emphasized when we started all this that the cluster should be designed exclusively for testing.  Starting from scratch is always the best in my opinion if you’re looking to make sure you don’t have any lingering configuration.  To do that you Continue reading
1 2 3 5