This entry is part 6 of 6 in the series Influence Routing Decisions with python and ExaBGP

Now that you know how to advertise prefixes to BGP peers with ExaBGP and are familiar with how to use this to influence traffic in your network, let’s change gears and look at processing BGP messages between ExaBGP and its peers. Since ExaBGP uses JSON for message data, I figured it would be a good opportunity to use MongoDB so the message information can easily be stored into a database for data collection and analysis.

ExaBGP & MongoDB

In the ExaBGP configuration file you can specify the types of messages you want to receive on STDOUT and also the encoding of the messages (text or JSON). Here’s an example of configuring ExaBGP to send all BGP messages to the script running in the process section:

This should look real similar to previous ExaBGP config files, but note the new receive section and encoder directive under process syslog. This tells ExaBGP to output neighbor changes, updates, and all other parsed BGP messages in JSON format to STDOUT. There is also an option to output messages that ExaBGP sends to peers which you can read about here, but is outside the scope of this post.

Now that ExaBGP is outputting these messages we’ll look at how to use the python script specified in the process syslog section to parse the data. Here’s an example of the messages in JSON format we receive when ExaBGP peers with a router, receives a prefix, and then the peering is shutdown:

As you can see, there’s plenty of useful information provided in these messages in a very easy to consume JSON format. Here’s a summary of the values in messages:

  • Details about ExaBGP are contained in each message (Version, localhost, process ID)
  • BGP Message type: State (related to OPEN), Notification, Update, and Keepalive
  • ABGP neighbor section to show peer  associated with the message and the message content
    • This section will contain the route announcement/withdraw/EoR info

Just to show the process of storing these messages in our MongoDB database, let’s pretend we’re working on an app that will monitor the status of ExaBGP peers and send alerts if a peer connection is shutdown or keepalives haven’t been received in a certain amount of time. For this app, we will only need to hold onto the state and keepalive messages. Go ahead and check out this example syslog script in the ExaBGP repo that reads from STDIN, as I will be using it as a base for this next example.

Instead of storing the entire JSON message in MongoDB, I will create a summarized version with just the info needed for the app (type, peer, time, and state info). This example also converts the timestamp to a python datetime object so it’s a little easier to work with in our app. Here’s the python example to do this using the syslog-1.py script mentioned earlier as a base (I’ve preserved the original comments to help):

* This example assumes you have MongoDB and pymongo installed and are running it on the same host as ExaBGP with the default port.

So now if we were to connect to this database from the frontend app that will monitor BGP peer status, we can use the pymongo library to check for keepalives in the last 5 minutes from peer 172.16.2.10 like this:

This was just an introduction to working with the JSON messages from ExaBGP and storing them in a MongoDB for querying purposes. There’s plenty of potential with access to the UPDATE messages from neighbors and I’m sure a future post will cover that in more depth. Thanks for reading!

Series Navigation<< Control BGP Advertisements to eBGP peers with ExaBGP

This article has 6 comments

  1. Peng Xiao

    hi 

    I love  your website, could you tell me how to build a personal blog like yours? what kinds of tools or framework do you use?

    I used Hexo for my personal blog, but i love yours better.

    1. Andrew Gallo

      Are the errors you are getting complaining about datetime not being defined?  

      Try this:

      import datetime, 

      #line 17 looks something like this
      timestamp = datetime.datetime.fromtimestamp(temp_message[‘time’])

Leave a Reply

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