Havox

Havox is a rule generator for Autonomous Systems supported by OpenFlow switches. Based on orchestration directives (or instructions) written in its own DSL, Havox generates a set of OpenFlow rules to be installed on the underlying switches.

As part of a bigger architecture, Havox is designed to run as a web API that receives requests containing the directives, the topology graph description and some parameters for rule formatting. Once the rules are generated, the API responds with a JSON message containing all the rules, each one indicating which OpenFlow switch it should be installed on.

The mentioned architecture is composed of Havox, RouteFlow and Merlin, and currently tested in a Mininet environment with support of MiniNext implementing Quagga routing engines. RouteFlow requests rules from Havox and therefore is a client, whereas Merlin is a dependency which effectively calculates the paths between the AS exits.

Development status

Havox is still experimental, born from a master's thesis, so it is being actively developed and improved. There is yet a lot of new functionalities to come.

How it works

Havox is implemented in Ruby and is strongly based on metaprogramming concepts. The orchestration directives that forms its DSL are methods executed by the Ruby interpreter, having both values and entire blocks of code as parameters. The following code shows some Havox directives:

topology 'example.dot'
associate :rfvmE, :s5

exit(:s4) { destination_port 80 }

exit(:s3) {
  source_ip '200.156.0.0/16'
  destination_ip '200.20.0.0/16'
}

The first one, topology <file_name> is a topology file definition directive. It takes a string and specifies the topology description file that should be considered, which usually goes together with the directives file in the same request.

The second, associate <router_name>, <switch_name> is the router-switch association directive. It takes a string or a symbol that specifies the RouteFlow container name that runs the target routing instance and its associated OpenFlow switch name. In this case, it associates the routing container rfvmE to the switch s5.

Next, there are two orchestration directives that instructs the matching flow to leave the network by the indicated switch. The exit directive, exit(<switch_name>) { <openflow_fields_and_values> }, takes the switch name as a string or symbol and a block containing the supported OpenFlow fields and their respective matching values, which can be strings or integers depending on the field.

For example, the first exit directive tells that any matching traffic with destination port 80 should leave the domain by the switch s4. The second exit directive tells that any packet that comes from the network 200.156/16 and heads to the network 200.20/16 must leave the domain by the switch s3.

The topology file is a graph description file written in DOT language and describes how the network topology is organized. This file is processed by both Havox and its dependency, Merlin. Each node has informations like its name, its internal IP address from one of its interfaces and how it is connected to the other nodes. It is important to know that this IP address is used by Havox to infer the associations between routing containers and switches using OSPF routes. Otherwise, it would be required to manually associate each pair using the association directive described above.

The exit directives from the request will be transcompiled to Merlin blocks of code, written in a Merlin policy file. This file is sent with the topology file to the Merlin process, where they will be evaluated for paths calculation. The generated raw rules are then post-processed, formatted and outputted by the API.

More details about the transcompilation, parsing and formatting processes can be found here (master's thesis in brazilian portuguese).

Installation

Install Havox by:

  1. Cloning the repository: $ git clone https://github.com/rodrigosoares/havox
  2. Accessing the directory: $ cd havox
  3. Installing gem dependencies: $ bin/setup

Besides, Havox requires Merlin and a modified version of RouteFlow that implements IP source and VLAN ID matching, subnet mask support and RFHavox module. The latter is an extra RouteFlow module designed to request rules from the remote Havox web API and enqueue them into the RouteFlow IPC system.

If the tests will be run in a experimental network, Mininet and MiniNext are also required. Gists containing example Quagga BGP configurations and Mininet topology files can be found here.

It is strongly recommended to install Merlin, RouteFlow and Mininet/MiniNext in isolated virtual machines, each. Make sure that all the VMs ping each other successfully. The recommendation is to use VirtualBox with host-only network adapters.

Setup all projects following their respective installation instructions. If using RouteFlow with Mininet, follow the instructions on setting Mininet up with RouteFlow remote controller.

Usage

HVX, MN and RF are the environments running Havox, Mininet and RouteFlow, respectively.

  1. (HVX) Setup Merlin and RouteFlow IPs and etcetera in config.rb.
  2. (HVX) Start Havox API web server: $ havox.
  3. (MN) Start Mininet, pointing its remote controller to the RouteFlow VM.
  4. (RF) Start RouteFlow: sudo ./rftest2.

If everything runs fine, RouteFlow will send a POST request to Havox, which in turn will log it and respond.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rspec --format d to run the tests and read a little documentation about what each component does. You can also run bin/console for an interactive prompt that will allow you to experiment.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/rodrigosoares/havox.

Be sure to follow Ruby best practices and to create a spec test case for each new method, module or component you create.

License

The gem is available as open source under the terms of the MIT License.