Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ This repository started as a fork of
longer actively maintained. This repository is mainly used by Antrea, and a lot
of code that is not needed in Antrea has been removed compared to the original
Contiv repository.

# Ofctrl

This library implements a simple Openflow1.5 controller API

You can see docs here: [Ofctrl Documentation](ofctrl/README.md)
117 changes: 80 additions & 37 deletions ofctrl/README.md
Original file line number Diff line number Diff line change
@@ -1,76 +1,119 @@
# Ofctrl

This library implements a simple Openflow1.3 controller API
This library implements a simple Openflow1.5 controller API

# Usage

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

// Listen for connections
ctrler.Listen(":6633")
```go
// 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.

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

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

type AppInterface interface {
// A Switch connected to the controller
SwitchConnected(sw *OFSwitch)
// Controller received a packet from the switch
PacketRcvd(sw *OFSwitch, pkt *PacketIn)

// Switch disconnected from the controller
SwitchDisconnected(sw *OFSwitch)
// Controller received a multi-part reply from the switch
MultipartReply(sw *OFSwitch, rep *openflow15.MultipartReply)

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

TLVMapEnabledOnSwitch() bool

// PortStatusRcvd notifies AppInterface a new PortStatus message is received.
PortStatusRcvd(status *openflow15.PortStatus)
}
```

# Example app

type OfApp struct {
Switch *ofctrl.OFSwitch
}
```go
package main

import (
"log"

"antrea.io/libOpenflow/openflow15"
"antrea.io/ofnet/ofctrl"
)

type OfApp struct {
Switch *ofctrl.OFSwitch
}

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

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

// Store switch for later use
o.Switch = sw
}
func (o *OfApp) SwitchDisconnected(sw *ofctrl.OFSwitch) {
log.Printf("App: Switch Disconnected: %v", sw.DPID())
}

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

// Main app
func (o *OfApp) FlowGraphEnabledOnSwitch() bool {
return true
}

func (o *OfApp) TLVMapEnabledOnSwitch() bool {
return true
}

func (o *OfApp) ExperimenterMessageEnabledOnSwitch() bool {
return false
}

func (o *OfApp) PortStatusRcvd(status *openflow15.PortStatus) {
log.Printf("App: New PortStatus message: %+v", status)
}

func main() {
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`
```bash
sudo ovs-vsctl set-controller ovsbr0 tcp:127.0.0.1:6633
```
### To enable openflow1.5 support in OVS:
`ovs-vsctl set bridge <bridge-name> protocols=OpenFlow15`

Example:

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

```bash
sudo ovs-vsctl set bridge ovsbr0 protocols=OpenFlow15
```
# 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
Expand Down
13 changes: 9 additions & 4 deletions ofctrl/ofSwitch.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,12 @@ func (s *OFSwitch) switchConnected() error {
log.Errorf("Failed to set switch config: %v", err)
return err
}
// Set controller ID on the Switch.
if err := s.Send(openflow15.NewSetControllerID(s.ctrlID)); err != nil {
log.Errorf("Failed to set controller ID: %v", err)
return err
if s.app.ExperimenterMessageEnabledOnSwitch() {
// Set controller ID on the Switch.
if err := s.Send(openflow15.NewSetControllerID(s.ctrlID)); err != nil {
log.Errorf("Failed to set controller ID: %v", err)
return err
}
}
s.changeStatus(true)
s.app.SwitchConnected(s)
Expand All @@ -215,6 +217,9 @@ func (s *OFSwitch) receive() {
case msg := <-s.stream.Inbound:
// New message has been received from message
// stream.
if !s.app.OFPMessageRcvd(s, msg) {
return
}
s.handleMessages(s.dpid, msg)
case err := <-s.stream.Error:
log.Warnf("Received ERROR message from switch %v. Err: %v", s.dpid, err)
Expand Down
7 changes: 7 additions & 0 deletions ofctrl/ofctrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ type AppInterface interface {

TLVMapEnabledOnSwitch() bool

// Send OFPT_EXPERIMENTER Message on Switch connection
ExperimenterMessageEnabledOnSwitch() bool

// Controller received an Openflow Message from the switch.
// If return value is True, default handler will proceed for the message
OFPMessageRcvd(sw *OFSwitch, msg util.Message) bool

// PortStatusRcvd notifies AppInterface a new PortStatus message is received.
PortStatusRcvd(status *openflow15.PortStatus)
}
Expand Down