Andy Pearce discusses the process of implementing and testing the application in the fourth post of the SampleTap blog series.
This is the concluding post in our four-part blog series exploring the implementation of ONF SampleTap, our network tapping application using the OpenDaylight framework. For more information, please read our earlier posts on the project: “The App. Developed.,” “Designing SampleTap,” and “Application Building.”
Implementing SampleTap Using OpenDaylight
Once we decided to use OpenDaylight as our platform, I set up an Ubuntu Linux instance on my MacBook and downloaded the OpenDaylight codebase from GitHub. With our product specifications as a reference – which included the key technology components we needed to build – I began to translate the user requirements into a domain object model.
I documented these specifications with a UML static-structure diagram that described major objects in the system and their relationship with one another. I used the UML diagram to communicate the current state of the design with the web developer and other stakeholders, and we updated this diagram to reflect any changes that were made.
After we agreed upon APIs with the web developer, we worked independently on our components, integrating our progress every few days. We were able to build the mid-tier persistence and UI-facing APIs within three weeks. The UI appeared to be functional, as user configuration could be stored and retrieved from the database. We also added an event receiver API to notify the tapping app whenever a user made a change to the system configuration.
At this point, the backend app was integrated with the web UI, which meant I could switch gears to integration with OpenDaylight. We decided to build the app as a native OSGi bundle running inside the OpenDaylight framework. The OSGi is an “Activator” in the OpenDaylight model that operates as a dynamic app loader and launcher whenever OpenDaylight is started. The Activator also registers the app with the list of OpenDaylight services it can use.
The process of creating the OSGi bundle was very time consuming because I wasn’t familiar with the build tools I needed to use. Resolving all of the external class dependencies proved to be quite difficult for someone with only rudimentary Maven experience, so I reached out to a few OpenDaylight developers for some pointers. With their help, I was able to resolve the class dependency problems we were having so that SampleTap started whenever OpenDaylight was launched.
Lastly, we implemented the appropriate Java Interface (SwitchManager.IInventoryListener), so when a significant change occurred – such as a switch connecting or disconnecting – the app received that information. We kept it as a thin layer between OpenDaylight and the rest of the app logic, allowing all events received to be delegated as the application’s objects, where they could be processed and implemented.
Time to Test
I tested the app with OpenVSwitch (OVS) because I thought it would be easier to use than a physical switch. I downloaded and installed OVS, and I configured the OpenFlow® parameters with the command line tools to ensure it was connected to the OpenDaylight controller.
Getting to the point where connecting or disconnecting of a switch was processed by the app was pretty easy. I then implemented the logic necessary to traverse the set of configuration objects stored in the database, generate the set of flow rules needed to tap the network traffic, and send it to the capture devices specified by the user.
We started to run some simple end-to-end tests using a traffic generator and analyzer. After a few bug fixes and minor changes, we were able to use the web UI to configure the app and select the different types of traffic that we wanted to capture.
The main problem we encountered was that any traffic that didn’t match what we wanted to capture was being sent to the OpenDaylight controller as a series of PACKET_IN messages, causing major performance problems. I realized I had forgotten to apply a DISCARD rule. Once I added a default flow rule at the lowest priority with the action of DROP, the switch stopped overrunning the system and the app worked as intended.
I rounded out the implementation by adding the logic in the backend to send log messages from the database and statistics from the controller to the UI. The list of statistics for each port was obtained from the StatisticsManager service in OpenDaylight.
With the app working as expected with OVS, we started to use a real switch. NEC kindly loaned us two NEC model PF5240 switches, one of which we configured to connect to the controller as an OpenFlow® client. As soon as the NEC switch connected, we were able to reconfigure the app to start sending captured traffic to the capture device. Success!
Advantages of OpenDaylight
The OpenDaylight controller is a fairly full-featured solution that provides access to the underlying OpenFlow® functionality. It offers an app framework based on an event-driven architecture that I prefer where app performance and responsiveness is important. The design of OpenDaylight APIs makes them straightforward to use, so it was easy to implement rules for traffic filtering and packet capture. The objects are generally clean, well-structured, and work as expected. Having been through the process of building SampleTap, I was able to do pretty much everything I wanted to using OpenDaylight.
Challenges of OpenDaylight
The biggest challenge I encountered was figuring out how to navigate the OSGi bundle generation process. Pulling in third-party libraries was especially irksome, since I needed a slightly different approach for every library I wanted to use. The reason is that the CLASSPATH environment contains a list of individual jar files, but not a directory. This breaks a lot of functions in third-party libraries.
Another issue was that the OpenDaylight documentation is voluminous and hard to navigate. Sometimes definitions are not clear. For example, it took me a while to understand that “node” meant switch and “node connector” meant switch port. A glossary and tutorials would be helpful.
I do think there is some missing functionality within OpenDaylight. For example, getting the IP address of a switch that just connected required a patch from an OpenDaylight developer. (A big thank you to Madhu Venugopal and Brent Salisbury for their willingness to point me in the right direction!) In addition, the functions available for the node and node connector identifiers are quite limited. They need to be passed to other services before you can get useful information, which adds complexity to the app code.
Future Enhancements to SampleTap’s Code
In my previous post, I discussed possible code improvements that would make SampleTap better. Future enhancements should:
- Support high-availability and improved scalability.
- Simplify the UI to make it easier to define the set of flows to tap and capture.
- Improve security mechanisms, restricting users who can browse the app’s web server and obtain access.
- Add user authentication, supported by role-based access control mechanisms that are tied to user profiles stored in the database.
- Support newer SAL APIs that support OpenFlow® protocol version 1.3.
Please let us know if you have feedback or suggestions about ONF SampleTap. We welcome the community’s thoughts.
– Andy Pearce, System Architect, Wiretap Labs
Andy Pearce has spent his last 20 years as a software developer and system architect. Most of his career has been spent building high-performance, real-time and embedded systems using communications and networking technology. Andy’s development work has been primarily focused on using C and C++ with a heavy emphasis on STL.
Andy is currently the lead developer and architect for Wiretap Labs, which provides custom development and system architecture services for enterprise customers, specializing in SDN, NFV, cloud-based solutions and network security. Andy spends his days working with clients to help architect cloud and SDN-based solutions.