How to implement Quality Of Service using Floodlight

This has not been ported to Floodlight v1.0 at this time.

This open-source project is in affiliation with Marist College in New York.

Ryan Wallner

ryan.wallner1@marist.edu

openflow.marist.edu

A video tutorial on some the features:

http://www.youtube.com/watch?v=M03p8_hJxdc

The code is available here: (rough around the edges but good enough to play with)

https://github.com/wallnerryan/floodlight-qos-beta.git

$git clone https://github.com/wallnerryan/floodlight-qos-beta.git

$cd floodlight-qos-beta

$ant; ./floodlight.sh

(open your bowser and visit localhost:8080/ui/index.html and click Tools

[Update Jan 2013]

Both python apps will be re-factored to use a more flexible arg parsing lib

The module itself is also being prepared to be only the QoS module, no UI or other code. This is 

so it can eventually integrate into the master. Modifying existing QoS policies will also be added.

[update 4-22-13] I will be updating this tutorial in the coming days.

Implementing QoS using Floodlight

  • Quality of Service is at its infancy when it comes to OpenFlow. The OpenFlow 1.0 spec included ways in which you can set the network

type of service on a flow, as well as enqueue the packets matching the flow to a specific queue on a specific port. What this module tries to do

is give a user a way to simply push QoS state to switches that support these features. This modules will aim to tackle the "enqueue" and "set-nw-tos" 

actions. The static flow pusher API calls this "set-tos-bits". As future specs such as 1.3 become adopted I plan to implement features that take advantage

of 1.3's "set-queue" and and meter tables. Setting of the DSCP or ToS bits will continue to be supported, but there are plans to create a more in-depth

QoS framework in the future specs. OFConfig can play a major role in Quality of Service as well, the implementation of such a protocol could prove

very useful in the set-up and tear-down of qos-based queues. 

  • The example below shows how to push rate-limiting QoS state into OVswitches that utilize queues attached to ports. Other switches can take advantage of the network ToS bits,(which is very vendor specific) and you can ultimately push a "network wide" policy that abides by what ever the ToS bits are set to do in your network.

Some additional references:

  • OpenFlow (1.0) supports setting the network type of service bits and enqueuing packets. This does not however mean that every switch will support these actions.
  • Queuing Methods:
    Some Openflow implementation do NOT support queuing structures to attach to a specific ports, in turn then "enqueue:port:queue" action in Openflow 1.0 is optional. Therefore resulting in failure on some switches

QoS Application.

Module: Allows the QoS service and policies to be managed on the controller and applied to the network

   

REST API

GET

POST

Description of use

/wm/qos/tool/<op>/json

Yes

N/A

Use "status", "enable" or "disable"
status - Gives the status of the module, true if enabled, false if not.
enable - Enables the Quality of Service Module
disable - Disables the Quality of Service Module

/wm/qos/service/json

Yes

Yes

Accepts a service that can be added to the controller. This service can
be used in policies to enforce certain classification of service within a network.
(The switch must support this action)

Returns a list of services that are known to the controller.

/wm/qos/policy/json

Yes

Yes

Accepts a policy to enforce. Policies can be applied to a single switch, a list of
switches or all switches. You can specify "none" to have the controller retain it
but not push it to any switch. This technique may be used in using the QoSPath
application.

Returns a list of policies that are known to the controller

Service

Field

Description

id

unique identifier (not needed in POST)

name

unique, gives a human readable description for the policy. I.e. "Best Effort"

tos

Represents the type of service or DSCP (Differentiated Services Code Point) bits

Policy

Field

Description

id

unique identifier (not needed in POST)

name

 Unique. human readable name for the policy i.e "Enqueue 1:1 on switch 1"

sw

this can have several values.

  1. ensure no policy to any switches, controller stores it, used in QoSPath "none",
  2. all switches, used mainly for type of service QoS "all"
  3. policy is pushed to a single switch dpid "<Switch-ID>"
  4. or a list of switch dpids "<Switch-ID>,<Switch-ID>,..."

service

reference a ToS classification service from a list of known services by the controller. Will set the policy to action _set-nw-tos. _Default is "Best Effort" with a tos=0x00.
 Only service or enqueue must be set on a policy. Cannot use both, controller will ask to use only one.

queue

queue used in the enqueue method. queue cannot be set without enqueue

enqueue-port

This will set the action to enqueue and set the action to enqueue to this port. This will need queue to be set as well.
Only service or enqueue must be set on a policy. Cannot use both, controller will ask to use only one.

priority

The priority of the policy (flow) 

  • default is 32767 
  • maximum value is 32767



Policy Match Fields

same from the staticflowpusher

protocol

Can be hexadecimal (with leading 0x) or decimal

eth-type

Can be hexadecimal (with leading 0x) or decimal

ingress-port

switch port on which the packet is received 
Can be hexadecimal (with leading 0x) or decimal

ip-src

xx.xx.xx.xx

ip-dst

xx.xx.xx.xx

tos

Can be hexadecimal (with leading 0x) or decimal

vlan-id

Can be hexadecimal (with leading 0x) or decimal

eth-src

Can be hexadecimal (with leading 0x) or decimal

eth-dst

Can be hexadecimal (with leading 0x) or decimal

src-port

Can be hexadecimal (with leading 0x) or decimal

dst-port

Can be hexadecimal (with leading 0x) or decimal

*"wildcards" and "active" keys are unsupported right now.


Rest Applications

QoSPusher.py Python application used to manage QoS from the command line

(Example coming soon)

QoSPath.py QoSPath is a python application that utilizes cirtcuitpusher.py to push QoS state along a specific circuit in a network.

Example

*sorry for the typos in the screen shots

Network

Mininet Topo Used
#sudo mn --topo linear,4 --switch ovsk --controller=remote,ip= --ipbase=10.0.0.0/8

Enable QoS on the controller:

1. Visit the tools seciton and click on "Quality of Service"

2. Verify that the module is enabled.


  • From the topology above, say we want to Rate-Limit traffic from Host 10.0.0.1  to Host 10.0.0.2 to only 2Mbps.
  • The links suggest we need to place 2 flows, one in switch 00:00:00:00:00:00:01
  • and another in 00:00:00:00:00:00:02 that enqueue the packets that match Host 1 to the rate-limited queue.
  • Knowing queue 2 on these switches rate limit the flows, we can use the QoSPusher application to push 2 policies that do just that.
#./qospusher.py add policy ' {"name": "Enqueue 2:2 s1?, "protocol":"6?,"eth-type": "0×0800?, "ingress-port": "1?,"ip-src":"10.0.0.1?, "sw":&nbsp;"00:00:00:00:00:00:00:01?,"queue":"2?,"enqueue-port":"2?}' 127.0.0.1
QoSHTTPHelper
Trying to connect to 127.0.0.1...
Trying server...
Connected to: 127.0.0.1:8080
Connection Succesful
Trying to add policy {"name": "Enqueue 2:2 s1?, "protocol":"6?,"eth-type": "0×0800?, "ingress-port": "1?,"ip-src":"10.0.0.1?, "sw": "00:00:00:00:00:00:00:01?,"queue":"2?,"enqueue-port":"2?}
[CONTROLLER]: {"status" : "Trying to Policy: Enqueue 2:2 s1?}
Writing policy to qos.state.json
{
"services": [],
"policies": [
" {\"name\": \"Enqueue 2:2 s1\", \"protocol\":\"6\",\"eth-type\": \"0x0800\", \"ingress-port\": \"1\",\"ip-src\":\"10.0.0.1\", \"sw\": \"00:00:00:00:00:00:00:01\",\"queue\":\"2\",\"enqueue-port\":\"2\"}"
]}
Closed connection successfully

#./qospusher.py add policy ' {"name": "Enqueue 1:2 s2?, "protocol":"6?,"eth-type": "0×0800?, "ingress-port": "1?,"ip-src":"10.0.0.1?, "sw": "00:00:00:00:00:00:00:02?,"queue":"2?,"enqueue-port":"1?}' 127.0.0.1
QoSHTTPHelper
Trying to connect to 127.0.0.1...
Trying server...
Connected to: 127.0.0.1:8080
Connection Succesful
Trying to add policy {"name": "Enqueue 1:2 s2?, "protocol":"6?,"eth-type": "0×0800?, "ingress-port": "1?,"ip-src":"10.0.0.1?, "sw": "00:00:00:00:00:00:00:02?,"queue":"2?,"enqueue-port":"1?}
[CONTROLLER]: {"status" : "Trying to Policy: Enqueue 1:2 s2?}
Writing policy to qos.state.json
{
"services": [],
"policies": [
" {\"name\": \"Enqueue 2:2 s1\", \"protocol\":\"6\",\"eth-type\": \"0x0800\", \"ingress-port\": \"1\",\"ip-src\":\"10.0.0.1\", \"sw\": \"00:00:00:00:00:00:00:01\",\"queue\":\"2\",\"enqueue-port\":\"2\"}",
" {\"name\": \"Enqueue 1:2 s2\", \"protocol\":\"6\",\"eth-type\": \"0x0800\", \"ingress-port\": \"1\",\"ip-src\":\"10.0.0.1\", \"sw\": \"00:00:00:00:00:00:00:02\",\"queue\":\"2\",\"enqueue-port\":\"1\"}"
]}
Closed connection successfully

Take a look in the Browser to make sure it was taken

Verify the flows work, using iperf, from h1 --> h2

Iperf shows that the bandwith is limited to ~2Mbps. See below for counter iperf test to verify h2 --> 

Verify the opposite direction is unchanged. (getting ~30mbps benchmark )

The set-up of the queues on OVS was left out of this example. but the basic setup is as follows:

  • Give 10GB bandwidth to the port (thats what it supports)
  • Add a qos record with 3 queues on it
  • 1st queue, q0 is default, give it a max of 10GB
  • 2nd queue is q1, rate limited it to 20Mbps
  • 3rd queue is q2, rate limited to 2Mbps.

Ultimately QoS and OpenFlow are at their beginning still, it will mature as the latter specs become adopted by hardware and virtual switches. The improvement and adoption of OFConfig will also play a major role in this realm. But this is used as a simple implementation of how it may work. Integrating OFConfig would be an exciting feature.