Skip to content

Commit

Permalink
Add support for PortStatus message. (#82)
Browse files Browse the repository at this point in the history
Add function PortStatusRcvd in AppInterface to notify the applications when a
PortStatus message is received from the OpenFlow switch.

Signed-off-by: Wenying Dong <[email protected]>
  • Loading branch information
wenyingd authored Oct 8, 2024
1 parent ee69f57 commit 3796388
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 2 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.13.0
v0.14.0
3 changes: 2 additions & 1 deletion ofctrl/ofSwitch.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,8 @@ func (self *OFSwitch) handleMessages(dpid net.HardwareAddr, msg util.Message) {
case *openflow15.FlowRemoved:

case *openflow15.PortStatus:
// FIXME: This needs to propagated to the app.
// Propagate the PortStatus message to the app.
self.app.PortStatusRcvd(t)
case *openflow15.PacketOut:

case *openflow15.FlowMod:
Expand Down
3 changes: 3 additions & 0 deletions ofctrl/ofctrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ type AppInterface interface {
FlowGraphEnabledOnSwitch() bool

TLVMapEnabledOnSwitch() bool

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

type ConnectionRetryControl interface {
Expand Down
83 changes: 83 additions & 0 deletions ofctrl/ofctrl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ limitations under the License.
package ofctrl

import (
"bytes"
"encoding/binary"
"fmt"
"net"
Expand All @@ -41,6 +42,8 @@ type OfActor struct {
pktInCount int
tlvTableStatus *TLVTableStatus
tlvMapCh chan struct{}

portStatusCh chan *openflow15.PortStatus
}

func (o *OfActor) PacketRcvd(sw *OFSwitch, packet *PacketIn) {
Expand Down Expand Up @@ -81,6 +84,12 @@ func (o *OfActor) TLVMapEnabledOnSwitch() bool {
return true
}

func (o *OfActor) PortStatusRcvd(status *openflow15.PortStatus) {
if o.portStatusCh != nil {
o.portStatusCh <- status
}
}

// Controller/Application/ovsBr work on clientMode
var ofActor *OfActor
var ctrler *Controller
Expand Down Expand Up @@ -2387,3 +2396,77 @@ func TestWriteactionsFlows(t *testing.T) {
"conjunction(101,2/3)")

}

func TestPortStatusRcvd(t *testing.T) {
app := new(OfActor)
ctrl := NewController(app)
brName := "br4PortStatus"
ovsBr := prepareControllerAndSwitch(t, app, ctrl, brName)
defer func() {
assert.Nilf(t, ovsBr.DeleteBridge(brName), "Failed to delete br %s", brName)
ctrl.Delete()
}()

portStatusCh := make(chan *openflow15.PortStatus)
app.portStatusCh = portStatusCh

for _, tc := range []struct {
name string
portName string
portNo int
requestOFPort bool
}{
{
name: "OVS port without ofport_request",
portName: "p1",
portNo: 1,
requestOFPort: false,
}, {
name: "OVS port with ofport_request",
portName: "p2",
portNo: 100,
requestOFPort: true,
},
} {
t.Run(tc.name, func(t *testing.T) {
// OVSDB operation to add port.
cmd := fmt.Sprintf("ovs-vsctl --may-exist add-port %s %s -- set Interface %s type=internal", brName, tc.portName, tc.portName)
if tc.requestOFPort {
cmd = fmt.Sprintf("%s ofport_request=%d", cmd, tc.portNo)
}
err := exec.Command("/bin/bash", "-c", cmd).Run()
require.NoError(t, err)

// Verifications on the PortStatus message -- Add.
addPort := <-portStatusCh
assert.Equal(t, openflow15.PR_ADD, int(addPort.Reason))
assert.Equal(t, openflow15.PS_LINK_DOWN, int(addPort.Desc.State))
assert.Equal(t, tc.portName, string(bytes.Trim(addPort.Desc.Name, "\x00")))
assert.Equal(t, tc.portNo, int(addPort.Desc.PortNo))

// Set ip link up.
cmd = fmt.Sprintf("ip link set %s up", tc.portName)
err = exec.Command("/bin/bash", "-c", cmd).Run()
require.NoError(t, err)

// Verifications on the PortStatus message -- Modify.
modPort := <-portStatusCh
assert.Equal(t, openflow15.PR_MODIFY, int(modPort.Reason))
assert.Equal(t, openflow15.PS_LIVE, int(modPort.Desc.State))
assert.Equal(t, tc.portName, string(bytes.Trim(modPort.Desc.Name, "\x00")))
assert.Equal(t, tc.portNo, int(modPort.Desc.PortNo))

// OVSDB operation to delete port.
cmd = fmt.Sprintf("ovs-vsctl del-port %s %s", brName, tc.portName)
err = exec.Command("/bin/bash", "-c", cmd).Run()
require.NoError(t, err)

// Verifications on the PortStatus message -- Delete.
delPort := <-portStatusCh
assert.Equal(t, openflow15.PR_DELETE, int(delPort.Reason))
assert.Equal(t, openflow15.PS_LIVE, int(delPort.Desc.State))
assert.Equal(t, tc.portName, string(bytes.Trim(delPort.Desc.Name, "\x00")))
assert.Equal(t, tc.portNo, int(delPort.Desc.PortNo))
})
}
}

0 comments on commit 3796388

Please sign in to comment.