SDN Series Part Two: Trema, a Framework for Developing OpenFlow Controllers in Ruby and C
Our first post explored SDN and SDN controllers. In this article we will discuss Trema, a framework for developing OpenFlow controllers in Ruby and C. It is the first in a series of articles on different open source SDN controllers.
With Trema, the term framework is used to highlight the fact that the user has the freedom to configure and build an OpenFlow controller. The framework, designed to provide extensibility, includes all the necessary libraries and functionalities that are necessary to interact with OpenFlow switches. With support for both C and Ruby languages, Trema gives the user the freedom to choose based on their comfort level and performance requirements.
Trema is more a software platform for OpenFlow developers/researchers/enthusiasts than a production controller. For example, if the user wants an OpenFlow controller to manage the network topology, she just has to build and run Trema with an existing topology-manager application. The architecture of the Trema framework is as shown in Figure 1.
Trema architecture includes core modules such as packet-in filter, switch and switch manager, OpenFlow application interface, necessary libraries, network DSL for configurations, an emulator for integrated development, and Tremashark to support debugging. Trema employs a multi-process model, in which many functional modules are loosely coupled via a messenger. The functional modules could be any of the user modules (applications) or the core modules. The modules interact via messenger using the following six important APIs — the first three are for receiving and last three are for sending messages:
add_message_received_callback [RECEIVE NOTIFICATION MESSAGE]
add_message_requested_callback [RECEIVE REQUEST MESSAGE]
add_message_replied_callback [RECEIVE REPLY MESSAGE]
send_message [SEND NOTIFICATION MESSAGE]
send_request_message [SEND REQUEST MESSAGE]
send_reply_message [SEND REPLY MESSAGE]
This messenger architecture can help with dynamic reconfigurations and protecting the controller for deploying unstable modules. In summary, the messenger acts as a glue for linking user modules (applications), core modules and monitoring systems.
Figure 2 below is the summarized functional diagram of Trema. It highlights the significance of the messenger, and the core modules and their interaction with the user applications. In the remainder of this article, we describe the important components of the Trema architecture.
The core modules of the Trema framework mostly include OpenFlow foundational modules and typically those that are useful for multiple applications.
Switch and Switch-Manager
These two core modules implement the necessary functionalities for interactions with the OpenFlow switches. They also maintain all the necessary information about the switches.
The switch manager is responsible for creating the instance (switch daemons) of a switch. Specifically, switch_manager listens for the incoming OpenFlow switch (OFS), and when the OFS comes in, it forks and creates a switch_daemon process and hands over the control of the OFS to the switch daemon. Hence, there will be one switch_daemon process for each OFS instance and only one instance of switch_manager. The service_name of a switch daemon starts initially with switch.(OFS IPaddr:port), since the daemon cannot know the datapath ID (dpid) at startup. Once the switch daemon initializes and receives a feature_reply, it renames its service_name to switch.(dpid) using rename_message_received_callback. You can find the code in switch_event_recv_featuresreply at switch_manager/switch.c.
The PacketIn message is a way for the OpenFlow switch to send a captured packet to the controller. Switch sends the packets to the controller only when it is asked to do so by the controller or when there is no appropriate entry in the switch’s flow table.
As the name indicates, the packet-in filter module is responsible for handing the packets that arrive at the controller from the OpenFlow switches. The switch module in Trema transfers the incoming packets to the packet-in filter, which would do the necessary changes before passing it to any of the registered applications.
Tremashark is the Wireshark plugin for keeping track of any interprocess communication events among the functional modules. The events could vary from messages to secure-channel status to the queue statuses.
The libraries in Trema can be categorized under multiple headings as listed below:
- Protocol: OpenFlow.
- Interfaces: OpenFlow application, switch, management.
- Commonly used data structures: Linked list, doubly-linked list, hash table, timers.
- Utilities: Log, stats, wrapper.
- Network Protocols: TCP, IP, UDP, ether and etherIP, ICMP and IGMP.
From the above classifications, we can see that the libraries module typically includes stand-alone and independent functionalities and generic programming utilities.
The Trema framework includes about 15 to 20 different applications, also termed as user modules. These applications typically implement high-level functionalities, and can be seen as examples of SDN applications. Any application developer can make use of these applications as reference points to understand the usage of the APIs and develop newer applications. At a very high level, we can summarize categories of APIs as below:
- Create OpenFlow messages.
- Send OpenFlow messages
- Receive OpenFlow messages.
- Receive secure channel or switch-specific events
As we will see in future articles, these APIs will be exposed by almost all the OpenFlow controllers. In the below table we summarize important OpenFlow APIs that are used by 10 different applications:
Event / Openflow
Running a Trema Application
Trema is an OpenFlow platform that supports the entire development cycle, including testing. It provides the seamless integration of the controller and the network environment (such as the emulator) for testing and validation.
There are two different options to run the Trema application. The first and straightforward way is to execute the application in the examples folder, with or without a configuration file. For example, to run the dumper application, one can just use the below command:
./trema run ./objects/examples/dumper/dumper –c
The command Trema allows the user to run and terminate applications that are developed on top of the core modules. Apart from the “run” option, the command can also be used to kill applications, send packets between hosts, dump the flow entries in the switches, and display the statistics.
All applications in Trema, typically, come with a configuration file, which defines how that particular application should behave (if needed) and what the integrated network configuration should be (if any). Defining the behavior of the application in the configuration file includes the following:
- Choice of applications or modules: The developer has to decide what all applications he would need for his controller. In some cases, if the feature the user is looking for is not present as an existing application in the framework, then the user may have to develop one. For example, if the user needs his controller to have MPLS support, he would develop a separate application for the same.
- Configuration of the modules: This mainly includes the configuration of the filters – defining which events should be handled by which component.
- Configuration of message routing: The message routing refers to the process of forwarding the incoming packets (from switch to the controller) to the appropriate modules.
The network configuration is typically defined in switches and hosts and their connectivity.