ofctrl

package
v0.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2015 License: Apache-2.0, Apache-2.0 Imports: 9 Imported by: 0

README

Ofctrl

This library implements a simple Openflow1.3 controller API

Usage

// Create a controller
ctrler := ofctrl.NewController(&app)

// Listen for connections
ctrler.Listen(":6633")

This creates a new controller and registers the app for event callbacks. The app needs to implement following interface to get callbacks when an openflow switch connects to the controller.

type AppInterface interface {
    // A Switch connected to the controller
    SwitchConnected(sw *OFSwitch)

    // Switch disconnected from the controller
    SwitchDisconnected(sw *OFSwitch)

    // Controller received a packet from the switch
    PacketRcvd(sw *OFSwitch, pkt *PacketIn)
}

Example app

type OfApp struct {
    Switch *ofctrl.OFSwitch
}

func (o *OfApp) PacketRcvd(sw *ofctrl.OFSwitch, packet *openflow13.PacketIn) {
    log.Printf("App: Received packet: %+v", packet)
}

func (o *OfApp) SwitchConnected(sw *ofctrl.OFSwitch) {
    log.Printf("App: Switch connected: %v", sw.DPID())

    // Store switch for later use
    o.Switch = sw
}

func (o *OfApp) SwitchDisconnected(sw *ofctrl.OFSwitch) {
    log.Printf("App: Switch connected: %v", sw.DPID())
}

// Main app
var app OfApp

// Create a controller
ctrler := ofctrl.NewController(&app)

// start listening
ctrler.Listen(":6633")

Working with OpenVswitch

Command to make ovs connect to controller:

ovs-vsctl set-controller <bridge-name> tcp:<ip-addr>:<port>

Example:

sudo ovs-vsctl set-controller ovsbr0 tcp:127.0.0.1:6633
To enable openflow1.3 support in OVS:

ovs-vsctl set bridge <bridge-name> protocols=OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13

Example:

sudo ovs-vsctl set bridge ovsbr0 protocols=OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13

Forwarding Graph API

An app can install flow table entries into the Openflow switch by using forwarding graph API. Forwarding graph is made up of forwarding elements which determine how a packet lookups are done. Forwarding graph is a higher level interface that is converted to Openflow1.3 flows, instructions, groups and actions by the library

Forwarding graph is specific to each switch. It is roughly structured as follows

         +------------+
         | Controller |
         +------------+
                |
      +---------+---------+
      |                   |
 +----------+        +----------+
 | Switch 1 |        | Switch 2 |
 +----------+        +----------+
       |
       +--------------+---------------+
       |              |               |
       V              V
 +---------+      +---------+     +---------+
 | Table 1 |  +-->| Table 2 |  +->| Table 3 |
 +---------+  |   +---------+  |  +---------+
      |       |        |       |      |
 +---------+  |   +---------+  |  +--------+     +------+
 | Flow 1  +--+   | Flow 1  +--+  | Flow 1 +---->| Drop |
 +---------+      +---------+     +--------+     +------+
      |
 +---------+            +----------+
 | Flow 2  +----------->+ OutPut 1 |
 +---------+            +----------+
      |
 +---------+                 +----------+
 | Flow 3  +---------------->| Output 2 |
 +---------+                 +----------+
      |                            ^
 +---------+       +---------+     |      +----------+
 | Flow 4  +------>| Flood 1 +-----+----->| Output 3 |
 +---------+       +---------+     |      +----------+
      |                            |
 +---------+     +-----------+     |      +----------+
 | Flow 5  +---->| Multipath |     +----->| Output 4 |
 +---------+     +-----+-----+            +----------+
                       |
          +------------+-------------+
          |            |             |
    +----------+  +----------+  +----------+
    | Output 5 |  | Output 6 |  | Output 7 |
    +----------+  +----------+  +----------+

Forwarding graph is made up of Fgraph elements. Currently there are four kinds of elements.

1. Table - Represents a flow table
2. Flow - Represents a specific flow
3. Output - Represents an output action either drop or send it on a port
4. Flood - Represents flood to list of ports

In future we will support an additional type.

5. Multipath - Represents load balancing across a set of ports

Forwarding Graph elements are linked together as follows

  • Each Switch has a set of Tables. Switch has a special DefaultTable where all packet lookups start.
  • Each Table contains list of Flows. Each Flow has a Match condition which determines the packets that match the flow and a NextElem which it points to
  • A Flow can point to following elements
    1. Table - This moves the forwarding lookup to specified table
    2. Output - This causes the packet to be sent out or dropped
    3. Flood - This causes the packet to be flooded to list of ports
    4. Multipath - This causes packet to be load balanced across set of ports. This can be used for link aggregation and ECMP
  • There are three kinds of outputs
    1. drop - which causes the packet to be dropped
    2. toController - sends the packet to controller
    3. port - sends the packet out of specified port. Tunnels like Vxlan VTEP are also represented as ports.
  • A flow can have additional actions like:
    1. Set Vlan tag
    2. Set metadata Which is used for setting VRF for a packet
    3. Set VNI/tunnel header etc

Example usage:

     // Find the switch we want to operate on
     switch := app.Switch

     // Create all tables
     rxVlanTbl := switch.NewTable(1)
     macSaTable := switch.NewTable(2)
     macDaTable := switch.NewTable(3)
     ipTable := switch.NewTable(4)
     inpTable := switch.DefaultTable() // table 0. i.e starting table

     // Discard mcast source mac
     dscrdMcastSrc := inpTable.NewFlow(FlowMatch{
                                      &McastSrc: { 0x01, 0, 0, 0, 0, 0 }
                                      &McastSrcMask: { 0x01, 0, 0, 0, 0, 0 }
                                      }, 100)
     dscrdMcastSrc.Next(switch.DropAction())

     // All valid packets go to vlan table
     validInputPkt := inpTable.NewFlow(FlowMatch{}, 1)
     validInputPkt.Next(rxVlanTbl)

     // Set access vlan for port 1 and go to mac lookup
     tagPort := rxVlanTbl.NewFlow(FlowMatch{
                                  InputPort: Port(1)
                                  }, 100)
     tagPort.SetVlan(10)
     tagPort.Next(macSaTable)

     // Match on IP dest addr and forward to a port
     ipFlow := ipTable.NewFlow(FlowParams{
                               Ethertype: 0x0800,
                               IpDa: &net.IPv4("10.10.10.10")
                              }, 100)

     outPort := switch.NewOutputPort(10)
     ipFlow.Next(outPort)

Documentation

Overview

** Copyright 2014 Cisco Systems Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

** Copyright 2014 Cisco Systems Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

** Copyright 2014 Cisco Systems Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

** Copyright 2014 Cisco Systems Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

** Copyright 2014 Cisco Systems Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

** Copyright 2014 Cisco Systems Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

** Copyright 2014 Cisco Systems Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

** Copyright 2014 Cisco Systems Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppInterface

type AppInterface interface {
	// A Switch connected to the controller
	SwitchConnected(sw *OFSwitch)

	// Switch disconnected from the controller
	SwitchDisconnected(sw *OFSwitch)

	// Controller received a packet from the switch
	PacketRcvd(sw *OFSwitch, pkt *PacketIn)
}

type Controller

type Controller struct {
	// contains filtered or unexported fields
}

func NewController

func NewController(app AppInterface) *Controller

Create a new controller

func (*Controller) Delete

func (c *Controller) Delete()

Cleanup the controller

func (*Controller) Listen

func (c *Controller) Listen(port string)

Listen on a port

func (*Controller) Parse

func (c *Controller) Parse(b []byte) (message util.Message, err error)

Demux based on message version

type FgraphElem

type FgraphElem interface {
	// Returns the type of fw graph element
	Type() string

	// Returns the formatted instruction set.
	// This is used by the previous Fgraph element to install instruction set
	// in the flow entry
	GetFlowInstr() openflow13.Instruction
}

type Flood

type Flood struct {
	Switch  *OFSwitch // Switch where this flood entry is present
	GroupId uint32    // Unique id for the openflow group

	FloodList []FloodOutput // List of output ports to flood to
	// contains filtered or unexported fields
}

Flood Fgraph element

func (*Flood) AddOutput

func (self *Flood) AddOutput(out *Output) error

Add a new Output to group element

func (*Flood) AddTunnelOutput

func (self *Flood) AddTunnelOutput(out *Output, tunnelId uint64) error

Add a new Output to group element

func (*Flood) Delete

func (self *Flood) Delete() error

Delete a flood list

func (*Flood) GetFlowInstr

func (self *Flood) GetFlowInstr() openflow13.Instruction

instruction set for output element

func (*Flood) NumOutput

func (self *Flood) NumOutput() int

Return number of ports in flood list

func (*Flood) RemoveOutput

func (self *Flood) RemoveOutput(out *Output) error

Remove a port from flood list

func (*Flood) Type

func (self *Flood) Type() string

Fgraph element type for the output

type FloodOutput

type FloodOutput struct {
	// contains filtered or unexported fields
}

type Flow

type Flow struct {
	Table    *Table     // Table where this flow resides
	Match    FlowMatch  // Fields to be matched
	NextElem FgraphElem // Next fw graph element
	// contains filtered or unexported fields
}

State of a flow entry

func (*Flow) Delete

func (self *Flow) Delete() error

Delete the flow

func (*Flow) GetFlowInstr

func (self *Flow) GetFlowInstr() openflow13.Instruction

instruction set for flow element

func (*Flow) Next

func (self *Flow) Next(elem FgraphElem) error

Set Next element in the Fgraph. This determines what actions will be part of the flow's instruction set

func (*Flow) PopVlan

func (self *Flow) PopVlan() error

Special actions on the flow to set vlan id

func (*Flow) SetMacDa

func (self *Flow) SetMacDa(macDa net.HardwareAddr) error

Special actions on the flow to set mac dest addr

func (*Flow) SetMacSa

func (self *Flow) SetMacSa(macSa net.HardwareAddr) error

Special action on the flow to set mac source addr

func (*Flow) SetMetadata

func (self *Flow) SetMetadata(metadata, metadataMask uint64) error

Special actions on the flow to set metadata

func (*Flow) SetTunnelId

func (self *Flow) SetTunnelId(tunnelId uint64) error

Special actions on the flow to set vlan id

func (*Flow) SetVlan

func (self *Flow) SetVlan(vlanId uint16) error

Special actions on the flow to set vlan id

func (*Flow) Type

func (self *Flow) Type() string

Fgraph element type for the flow

type FlowAction

type FlowAction struct {
	// contains filtered or unexported fields
}

additional actions in flow's instruction set

type FlowMatch

type FlowMatch struct {
	Priority     uint16 // Priority of the flow
	InputPort    uint32
	MacDa        *net.HardwareAddr
	MacDaMask    *net.HardwareAddr
	MacSa        *net.HardwareAddr
	MacSaMask    *net.HardwareAddr
	Ethertype    uint16
	VlanId       uint16
	IpSa         *net.IP
	IpSaMask     *net.IP
	IpDa         *net.IP
	IpDaMask     *net.IP
	Metadata     *uint64
	MetadataMask *uint64
	TunnelId     uint64
}

Small subset of openflow fields we currently support

type OFSwitch

type OFSwitch struct {
	// contains filtered or unexported fields
}

func NewSwitch

func NewSwitch(stream *util.MessageStream, dpid net.HardwareAddr, app AppInterface) *OFSwitch

Builds and populates a Switch struct then starts listening for OpenFlow messages on conn.

func Switch

func Switch(dpid net.HardwareAddr) *OFSwitch

Returns a pointer to the Switch mapped to dpid.

func (*OFSwitch) DPID

func (self *OFSwitch) DPID() net.HardwareAddr

Returns the dpid of Switch s.

func (*OFSwitch) DefaultTable

func (self *OFSwitch) DefaultTable() *Table

Return table 0 which is the starting table for all packets

func (*OFSwitch) DeleteTable

func (self *OFSwitch) DeleteTable(tableId uint8) error

Delete a table. Return an error if there are fgraph nodes pointing at it

func (*OFSwitch) Disconnect

func (self *OFSwitch) Disconnect()

func (*OFSwitch) DropAction

func (self *OFSwitch) DropAction() *Output

Return the drop graph element

func (*OFSwitch) NewFlood

func (self *OFSwitch) NewFlood() (*Flood, error)

Create a new flood list

func (*OFSwitch) NewTable

func (self *OFSwitch) NewTable(tableId uint8) (*Table, error)

Create a new table. return an error if it already exists

func (*OFSwitch) OutputPort

func (self *OFSwitch) OutputPort(portNo uint32) (*Output, error)

Return a output graph element for the port

func (*OFSwitch) Send

func (self *OFSwitch) Send(req util.Message)

Sends an OpenFlow message to this Switch.

func (*OFSwitch) SendToController

func (self *OFSwitch) SendToController() *Output

Return send to controller graph element

type Output

type Output struct {
	// contains filtered or unexported fields
}

func (*Output) GetFlowInstr

func (self *Output) GetFlowInstr() openflow13.Instruction

instruction set for output element

func (*Output) GetOutAction

func (self *Output) GetOutAction() openflow13.Action

Return an output action (Used by group mods)

func (*Output) Type

func (self *Output) Type() string

Fgraph element type for the output

type PacketIn

type PacketIn openflow13.PacketIn

type Table

type Table struct {
	Switch  *OFSwitch
	TableId uint8
	// contains filtered or unexported fields
}

Fgraph table element

func (*Table) Delete

func (self *Table) Delete() error

Delete the table

func (*Table) DeleteFlow

func (self *Table) DeleteFlow(flowKey string) error

Delete a flow from the table

func (*Table) GetFlowInstr

func (self *Table) GetFlowInstr() openflow13.Instruction

instruction set for table element

func (*Table) NewFlow

func (self *Table) NewFlow(match FlowMatch) (*Flow, error)

Create a new flow on the table

func (*Table) Type

func (self *Table) Type() string

Fgraph element type for table

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL