Tutorial for creating first external SDN application for HP SDN VAN controller – Part 3/3: “Node Cutter” SDN application in perl with web interface

In this tutorial series, I will show you by example, how to build your first external REST API based SDN application for HP SDN VAN controller, with web interface for the user control. Target will be to learn how to use REST API, curl and perl scripting to generate some basic and useful code to view and also manipulate network traffic.

This article is part of “Tutorial for creating first external SDN application for HP SDN VAN controller” series consisting these articles:

In this Part 3/3, I will show you my first example SDN application that I have written just to demonstrate the combination of REST API interface with perl and the ability to have a web based interface for the user to this interface. Please note that this application is purely demonstrative on the REST API interface and basic principles, it is by no means a template for larger project because of complete lack of application based design as it was created in a “quick&dirty” way.

Prerequisites: Have the LAB from previous parts still running, we are going to use the same Mininet topology and the HP SDN VAN Controller 2.4.6

Step 1)
Install/activate Apache2 and mod_perl on it (perl CGI “Hello World”)

Both the SDNHub.org and Mininet.org VM images that I pointed you to do not by default have apache2 installed, but lucky both are ubuntu based so installing apache2 should not be a problem by simply running:

After you have this, lets modify the default webpage apache config to enable perl files execution, open /etc/apache/sites-available/000-default.conf and add the following lines:

And restart apache with

Now you should be able to run perl scripts that generate a web interface using the CGI interface of apache and mod_perl. So lets test this with a simple test file.

Create a new file inside your /var/www/html directory called “hello.cgi” and add this content to the file:

Step 2) Download and first run of NodeCutter

First point, this NodeCutter is provided as educational application with the following license:

Which means that I have no other requirements than that you keep my name as the author on any derivatives and hopefully I will get a beer from random stranger in the future. However, also there is no Warranty or Liability if you use this in production environment, this is purely for LAB/study purposes.

DOWNLOAD NODE CUTTER HERE

INSTALLATION:
Inside the ZIP file, you will see that it starts with index.html and directory with several perl scripts. Simply copy all this to you apache rood directory (if you used our defaults, it should be /var/www/html ) so that the index.html is directly in the document root. E.g like this /var/www/html/index.html

FIRST RUN:
If you think you have everything now, simply open your browser of choice and go to your apache server root, if you are following my lab, it should be http://192.168.125.10/ and you should see something like this:

Node Cutter - v0.1 Entry and SDN Controller login page

Node Cutter – v0.1 Entry and SDN Controller login page

Step 2) Logging to the SDN Controller and understanding index.cgi

You might have noticed, there are some default parameters already in the login page, that is only because this program is used here as part of my LAB, if you lab is different, simply change the IP/username/password to reflect your environment.

After you have the data, click the “Submit” button. The index.cgi is a smaller of the two program perl scripts and the only role of index.cgi is to to a simple REST API call with GET to /auth and submit via JSON structure the username/password (domain is the default “sdn” hidden in the code).

If everything works, you will see a notification and also the X-Auth-Token received from the controller like this:

Node Cutter - v0.1 Entry with successful token retrieval and option to continue to main menu

Node Cutter – v0.1 Entry with successful token retrieval and option to continue to main menu

If you click on the “Continue to main menu …” button, you will be redirected will all the data (including token) to the main.cgi, but before we go there, let’s have a deeper look on index.cgi. This is the high level pseudo-code summary of how index.cgi works.

Node Cutter 0.1 - index.cgi pseudo structure

Node Cutter 0.1 – index.cgi pseudo structure

As you can notice, the blue parts are those that you see at the begininning when you are entering username/password/IP and send them via POST method back to index.cgi. The red parts are executed only if any POST data are recieved.

The red parts check the POST arguments in standard perl-cgi processing that creates a hash %FORM from them. If this form contains all the required fields, a second IF will initiate REST API call to the controller and attempts to recover the X-Auth-Token.

For completeness of this article, this is the whole index.cgi code, I enabled line numbering to help me point to interesting parts that you should look at like:

  • Lines #35-66 is the fucntion that is generating REST API and contacts the controller for token, this is the main portion you should look at here!

NOTE to help you read the code: Do NOT forget you have the option to open the code in a separate window using the “Open Code In New Window” button in the code toolbar menu. Alternatively just read the pseudo-codes I will be showing and consider this a user-guide to the application GUI only if you are not interested in the code that much.

Step 3) Main menu and main.cgi structure

OK, if you are not yet fed-up by the index.cgi code, let me show you the main menu. When you arrived, this is what you should see.

Node Cutter - v0.1 Main menu initial page with readme and license

Node Cutter – v0.1 Main menu initial page with readme and license

There are only a few buttons in the menu, this is what they do:

  • Nodes to Cut – this is the main function this application is doing, when you enter here, you will get a list of Nodes that are currently known to the controller and the option to block their traffic (this is the main point of this app here).
  • Switches & Interfaces – this is a read-only function to demonstrate how to extract information from multiple parts of REST API and combine it. This one gets /net/devices for switches, net/devices/{dpdi}/ports for interfaces and also /of/stats for interface statistics and presents it as a combined overview!
  • README & License – this is a return button back this introduction page
  • Sage-refresh button – this is a BIG button to help you refresh the pages during experiments in a safe way, because sometimes if you use only F5, you can re-submit the POST command to block some node repeatedly and we wan to avoid this. So please use this one:
    NODE_Cutter_4_main_Menu_refresh_button

If you are code hungry, this is a quick representation of the main.cgi code. Technically all the buttons are POST methods and this way I am keeping the token and other usefull state data like which page to display and what action to take in a loop (yes, in real application this should be a cookie!, but POST is much more easy to understand reading the code, so after I started early with this I didn’t bothered to repair this architecture flaw as this is purely educational app!).

Node Cutter 0.1 - main.cgi pseudo-code structure to understand the code organization

Node Cutter 0.1 – main.cgi pseudo-code structure to understand the code organization

First, there are three parameters that you can configure if you want directly as a static variables at the beginning of the code.

  • $bDebug (Default value “0”) controls my dprint function that is a filtering mechanism for debug text control. If you change this value to 1, you will see much more troubleshooting and debug text appearing everywhere, but maybe inspire yourself using this dprint function instead of pure print if you are going to experiment with the code.
  • $COOKIE (Default value “0x2031987”) is an artificial value that Node Cutter is entering to all the flows it creates and it helps later identify all these rules to know if the found blocking rule was created by Node Cutter or by someone else. FYI right now this number is my birth date 😉
  • $PRIORITY (Default value “30000”), to override the controller SPF algorithm that creates rules with priority 29999, we are setting our rules at least to increment +1. NOTE: There is some problem here in going to values 30001+ for some reason, so if  you are going to experiment and mange to insert value larger than 30000, let me know.

Again, the logic of the file structure is also that blue parts are executed always, but the red parts are those that are executed depending on what arrives to them via POST method (always track the %FORM hash in the code). We only have two main chooses to do in terms of view and that is selected based on %FORM{‘view’} and only two actions of “block” and “unblock” that is selected via the %FORM{‘action’}.

Also note that for error handling, I choose to use a very simple, but ugly if this program would to become large way of using “goto” pointers. If any REST API function fails, it will print error messages and then jump at the end and stop the execution with only finishing the HTML body parts.

For main.cgi I will not show code in one view (if you want that please download the zip and open main.cgi that way) as it has ~800lines of perl and would definitely kill most of readers here. So lets have a quick view first how the Node Cutter works and then I will show the most important code snippets.

Step 4) Switches and Interfaces view

This is a read-only function, that if you click here with active network and controller you should get a fairly large table with all known SDN switches registered to the controller, and each switch that is marked as “Online” you will also get list of all its interfaces and Rx/Tx statistics for each port. This is how it looks like:

Node Cutter - v0.1 Switches & Interfaces view with several Off-line and Online switches, interfaces and statistics visible for Online switch

Node Cutter – v0.1 Switches & Interfaces view with several Off-line and Online switches, interfaces and statistics visible for Online switch

Node cutter achieves this by combining /net/devices with /net/devices/{dpid}/ports and /of/stats calls with various identifiers pushed back. The function to explore here is subrouting print_switches_and_their_interfaces, here is the code. Just have a look how it uses three REST API calls, while iterating via online switches and interfaces with some more REST API calls. In total, for large amount of switches this I expect can be quite a lot of sessions with performance impact possible in very large networks, but for campus it should be OK.

NOTE to help you read the code: Do NOT forget you have the option to open the code in a separate window using the “Open Code In New Window” button in the code toolbar menu.

 Step 5) Nodes to Cut – first look

Ok, finally we are here, lets do the following. Open you mininet and ping from H1 (10.10.2.1) to G1 (10.10.2.254) so that there are at least these two hosts active during our next experiment.

Leave the ping running as that will be our experiment for blocking/unblocking.

Now go to the “Nodes to Cut” view in the Node Cutter application and you should see something similar to this:

Node Cutter - v0.1 Nodes to Cut view, showing two detected nodes H1 and G1.

Node Cutter – v0.1 Nodes to Cut view, showing two detected nodes H1 and G1.

If you have your two nodes there, it is great! Now, make sure that the ping is still running, for me I just had a quick view:

Node Cutter - v0.1 Nodes to Cut view, ping running between H1 and G1

Node Cutter – v0.1 Nodes to Cut view, ping running between H1 and G1

 Step 6) Block node “H1” communication

Ok, you probably noticed the big “BLOCK” button in the table, but there are also two Timeout parameters you can play with. This is the explanation:

  • Hard.Timeout – is a timeout that invalidates the blocking flow (ergo auto-unblock) after the number of seconds. Independent on activity.
  • Idle.Timeout – is also going to invalidate the blocking flow, however this timer is reset with every new packet, so if the node will “try” to communicate continuously, the flow will never be removed, on the other side, if the node will be quit for the amount of time specified, it will help him invalidate the flow.

By default there is a combination of 300seconds on both, which means that the Hard.Timeout is going to win and definitely invalidate the flow after 5minutes. Feel free to experiment.

Let’s leave the default times and click “BLOCK”, something like this should happen:

Node Cutter - v0.1 Nodes to Cut view, recieved blocking request and successfully moved node to blocking state

Node Cutter – v0.1 Nodes to Cut view, recieved blocking request and successfully moved node to blocking state

Verification: Check your running PING between H1 and G1, it should now be blocked. Also feel free to run “pingall” in mininet and you will see that H1 cannot send traffic to any of the other hosts as well.

Node Cutter - v0.1 Nodes to Cut view, blocked seconds counter

Node Cutter – v0.1 Nodes to Cut view, blocked seconds counter

NOTE: If you start using the safe-refresh button now, you can notice that Node Cutter is also tracking the flow lifetime value in seconds, this might help you determine how long until it is subject to Timeout.

Regarding main.cgi code, the whole functionality is hidden inside the “block” subroutine. This is it and if you have a quick view on it, you can notice that it is only a single JSON construction of flow definition and a single REST API call with HTTP method “POST”.

NOTE: The “flow” definition in JSON was already explained in Part2/3 of this series, so I will not repeat that here.

Step 7) Unblocking node H1 communication

Because if you experimented with the Timers you can also enter “0” (zero) to make the blocking indefinite, you need a we to remove this block. You can do this after the program detects (by searching for it’s cookie value in the flow table) that a node is blocked, it gives you the “UNBLOCK” button.

Let’s try this now, but first, do you still run the ping between H1 and G1? If yes then by unblocking this communication, you will see the jump in ICMP sequence numbers that were dropped during our experiment. So let’s unblock! Click the “UNBLOCK” button.

Node Cutter - v0.1 Nodes to Cut view, unblocking node H1 success message and ping recovery after several sequence numbers blocked

Node Cutter – v0.1 Nodes to Cut view, unblocking node H1 success message and ping recovery after several sequence numbers blocked

If we look on the unblocking function “sub unblock {}” in main.cgi, you can notice that it is the same as the the block function, the only change is that the HTTP method was changed from POST to DELETE, everything else is identical with the block. Code part here:

END of Part 2/3 – “Node Cutter ” perl application with web interface

So in summary, I really hope you liked this one, it took me quite some time to actually program this app for you (well, initial creation was not long, maybe 4 hours, but making it nicer anc code clean was another point!). So I hope there will be at least someone who appreciates it, if nothing else it was a great experience for me that has not motivated me to check the internal application development because the REST API despite being powerful and can help you do a lot, doesn’t give you that many functions to play with. And what was not mentioned here is that there are some “magic limits” in some places. For example natural evolution of “Node Cutter” that I wanted was to enable DSCP field editing for nodes to manipulate their QoS, but the REST API is only permitting certain DSCP values (e.g. it accepted value “12” but refused to accept value “46” and other WTF?! moments I had).

In conclusion to the whole series

This series has given you a COMPLETE introduction to SDN external application creation, even though it assumed you know already something about OpenFlow and perl, it should have been easy to follow on the REST API aspect that we explored for both direct cURL commands and then with a full example application in perl with a nice web interface. ANd the application I share with the world only under the BEER-WARE license as I only want the references and be kept mentioned as author on derivatives (and hopefully get a beer sometime …. ).

In summary, I appreciate your time (especially if someone went through all three parts). Please leave a comment if you liked it! Thanks!

Index:

If you enjoyed this blog, please share.

About Peter Havrila

Author's Profile