Trema is a OpenFlow controller framework that includes everything needed to create OpenFlow controllers in Ruby and C.
This distribution includes all the source code of Trema you need to develop your own OpenFlow controllers. The source tree includes basic libraries and functional modules that work as an interface to OpenFlow switches.
Several sample applications developed on top of Trema are also provided, so you can run them as a sample of OpenFlow controllers. Additionally, a simple but powerful framework that emulates an OpenFlow-based network and end-hosts is provided for testing your own controllers. For debugging, a wireshark plug-in to diagnose internal data-flows among functional modules is provided.
Trema supports GNU/Linux only. And it has been tested on the following environments:
- Ruby 1.8.7 (1.9.x is NOT supported yet)
- Ubuntu 12.10, 12.04, 11.10, 11.04, 10.10, and 10.04 (i386/amd64, Desktop Edition)
- Debian GNU/Linux 6.0 (i386/amd64)
It may also run on other GNU/Linux distributions but is not tested and NOT SUPPORTED at this moment.
1.Install the prerequisites at the command prompt:
(In Debian GNU/Linux or Ubuntu 12.04 and below)
$ sudo apt-get install gcc make ruby rubygems ruby-dev libpcap-dev libsqlite3-dev
(In Ubuntu 12.10)
$ sudo apt-get install gcc make ruby1.8 rubygems1.8 ruby1.8-dev libpcap-dev libsqlite3-dev
2.Install Trema at the command prompt:
$ sudo gem install trema
3.Follow the guidelines to start developing your OpenFlow controller. You may find the following resources handy:
- The Getting Started with Trema.
- The Trema in 10 Minutes Tutorial.
- The Trema Tutorial.
- The Programming Trema Article (in Japanese).
The following is an excerpt from the Trema Ruby API. The full documents are found here http://rubydoc.info/github/trema/trema/master/frames
Subclass Trema::Controller and override some of the following methods to implement your own controller.
class MyController < Controller
# handle Packet-In messages here.
def packet_in datapath_id, message
# ...
end
# handle Flow-Removed messages here.
def flow_removed datapath_id, message
# ...
end
# ...
end
- switch_ready(datapath_id)
- switch_disconnected(datapath_id)
- packet_in(datapath_id, message)
- flow_removed(datapath_id, message)
- port_status(datapath_id, message)
- openflow_error(datapath_id, message)
- features_reply(datapath_id, message)
- stats_reply(datapath_id, message)
- barrier_reply(datapath_id, message)
- get_config_reply(datapath_id, message)
- queue_get_config_reply(datapath_id, message)
- vendor(datapath_id, message)
For sending Flow-Mod and Packet-Out, there are some methods defined in Trema::Controller class.
class MyController < Controller
def packet_in datapath_id, message
# ...
send_flow_mod_add( datapath_id, ... )
send_packet_out( datapath_id, ... )
end
# ...
end
- send_flow_mod_add(datapath_id, options)
- send_flow_mod_delete(datapath_id, options)
- send_flow_mod_modify(datapath_id, options)
- send_packet_out(datapath_id, options)
The following OpenFlow messages can be sent with Trema::Controller#send_message
class MyController < Controller
def switch_ready datapath_id
# send a FeaturesRequest message
send_message datapath_id, FeaturesRequest.new
end
def features_reply datapath_id, message
# ...
end
# ...
end
- Trema::Hello
- Trema::EchoRequest
- Trema::EchoReply
- Trema::FeaturesRequest
- Trema::SetConfig
- Trema::GetConfigRequest
- Trema::QueueGetConfigRequest
- Trema::DescStatsRequest
- Trema::FlowStatsRequest
- Trema::AggregateStatsRequest
- Trema::TableStatsRequest
- Trema::PortStatsRequest
- Trema::QueueStatsRequest
- Trema::VendorStatsRequest
- Trema::BarrierRequest
- Trema::PortMod
- Trema::Vendor
The matching rule of each flow table entry can be created with Match.new(options) and passed as ":match =>" option when sending Flow-Mod or Packet-Out.
def packet_in datapath_id, message
# ...
send_flow_mod_add(
datapath_id,
:match => Match.new( :in_port => message.in_port, ...)
# ...
)
# ...
end
Also there is a utility method called ExactMatch.from(packetin) for getting an exact match corresponding to a packet.
def packet_in datapath_id, message
# ...
send_flow_mod_add(
datapath_id,
:match => ExactMatch.from( message )
# ...
)
# ...
end
The actions list of each flow table entry can be set with ":actions =>" when sending Flow-Mod or Packet-Out.
# Strip the VLAN tag of a packet then send it out to switch port #1
send_flow_mod_add(
datapath_id,
# ...
:actions => [ StripVlanHeader.new, SendOutPort.new( 1 ) ]
)
- Trema::SendOutPort
- Trema::SetEthSrcAddr
- Trema::SetEthDstAddr
- Trema::SetIpSrcAddr
- Trema::SetIpDstAddr
- Trema::SetIpTos
- Trema::SetTransportSrcPort
- Trema::SetTransportDstPort
- Trema::SetVlanVid
- Trema::SetVlanPriority
- Trema::StripVlanHeader
- Trema::VendorAction
- Web Page: http://trema.github.com/trema/
- Bugs: https://github.com/trema/trema/issues
- Mailing List: https://groups.google.com/group/trema-dev
- Twitter: http://twitter.com/trema_news
Special thanks to all contributors for submitting patches. A full list of contributors including their patches can be found at:
https://github.com/trema/trema/contributors
Trema is released under the GNU General Public License version 2.0: