Skip to content

Commit

Permalink
Add support to specify ofport_request in the network configuration (#239
Browse files Browse the repository at this point in the history
) (#239)

Signed-off-by: Nick Rogers <[email protected]>

Signed-off-by: Nick Rogers <[email protected]>
Co-authored-by: Nick Rogers <[email protected]>
  • Loading branch information
courtland and courtland authored Sep 27, 2022
1 parent a8fd7ed commit ebb876e
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 7 deletions.
1 change: 1 addition & 0 deletions docs/cni-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Another example with a trunk port and jumbo frames:
* `mtu` (integer, optional): MTU.
* `trunk` (optional): List of VLAN ID's and/or ranges of accepted VLAN
ID's.
* `ofport_request` (integer, optional): request a static OpenFlow port number in range 1 to 65,279
* `configuration_path` (optional): configuration file containing ovsdb
socket file path, etc.

Expand Down
11 changes: 8 additions & 3 deletions pkg/ovsdb/ovsdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ func (ovsd *OvsDriver) ovsdbTransact(ops []ovsdb.Operation) ([]ovsdb.OperationRe
// **************** OVS driver API ********************

// CreatePort Create an internal port in OVS
func (ovsd *OvsBridgeDriver) CreatePort(intfName, contNetnsPath, contIfaceName, ovnPortName string, vlanTag uint, trunks []uint, portType string) error {
intfUUID, intfOp, err := createInterfaceOperation(intfName, ovnPortName)
func (ovsd *OvsBridgeDriver) CreatePort(intfName, contNetnsPath, contIfaceName, ovnPortName string, ofportRequest uint, vlanTag uint, trunks []uint, portType string) error {
intfUUID, intfOp, err := createInterfaceOperation(intfName, ofportRequest, ovnPortName)
if err != nil {
return err
}
Expand Down Expand Up @@ -782,7 +782,7 @@ func (ovsd *OvsDriver) isMirrorExistsByConditions(conditions []ovsdb.Condition)
return true, nil
}

func createInterfaceOperation(intfName, ovnPortName string) (ovsdb.UUID, *ovsdb.Operation, error) {
func createInterfaceOperation(intfName string, ofportRequest uint, ovnPortName string) (ovsdb.UUID, *ovsdb.Operation, error) {
intfUUIDStr := fmt.Sprintf("Intf%s", intfName)
intfUUID := ovsdb.UUID{GoUUID: intfUUIDStr}

Expand All @@ -798,6 +798,11 @@ func createInterfaceOperation(intfName, ovnPortName string) (ovsdb.UUID, *ovsdb.
intf["external_ids"] = oMap
}

// Requested OpenFlow port number for this interface
if ofportRequest != 0 {
intf["ofport_request"] = ofportRequest
}

// Add an entry in Interface table
intfOp := ovsdb.Operation{
Op: "insert",
Expand Down
6 changes: 3 additions & 3 deletions pkg/plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ func getBridgeName(bridgeName, ovnPort string) (string, error) {
return "", fmt.Errorf("failed to get bridge name")
}

func attachIfaceToBridge(ovsDriver *ovsdb.OvsBridgeDriver, hostIfaceName string, contIfaceName string, vlanTag uint, trunks []uint, portType string, contNetnsPath string, ovnPortName string) error {
err := ovsDriver.CreatePort(hostIfaceName, contNetnsPath, contIfaceName, ovnPortName, vlanTag, trunks, portType)
func attachIfaceToBridge(ovsDriver *ovsdb.OvsBridgeDriver, hostIfaceName string, contIfaceName string, ofportRequest uint, vlanTag uint, trunks []uint, portType string, contNetnsPath string, ovnPortName string) error {
err := ovsDriver.CreatePort(hostIfaceName, contNetnsPath, contIfaceName, ovnPortName, ofportRequest, vlanTag, trunks, portType)
if err != nil {
return err
}
Expand Down Expand Up @@ -307,7 +307,7 @@ func CmdAdd(args *skel.CmdArgs) error {
}
}

if err = attachIfaceToBridge(ovsDriver, hostIface.Name, contIface.Name, vlanTagNum, trunks, portType, args.Netns, ovnPort); err != nil {
if err = attachIfaceToBridge(ovsDriver, hostIface.Name, contIface.Name, netconf.OfportRequest, vlanTagNum, trunks, portType, args.Netns, ovnPort); err != nil {
return err
}

Expand Down
32 changes: 32 additions & 0 deletions pkg/plugin/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"encoding/json"
"errors"
"fmt"
"math/rand"
"net"
"os/exec"
"strconv"
Expand Down Expand Up @@ -663,6 +664,37 @@ var testFunc = func(version string) {
Expect(string(output[:len(output)-1])).To(Equal(ovsOutput))
})
})
Context("specified OfportRequest", func() {
It("should configure an ovs interface with a specific ofport", func() {
// Pick a random ofport 5000-6000
ofportRequest := rand.Intn(1000) + 5000
ovsOutput := fmt.Sprintf("ofport : %d", ofportRequest)

conf := fmt.Sprintf(`{
"cniVersion": "%s",
"name": "mynet",
"type": "ovs",
"ofport_request": %d,
"bridge": "%s"}`, version, ofportRequest, bridgeName)

targetNs := newNS()
defer func() {
closeNS(targetNs)
}()

result := attach(targetNs, conf, IFNAME, "", "")
hostIface := result.Interfaces[0]

// Wait for OVS to actually assign the port, even when the add returns
// successfully, ofport can still be blank ("[]") for a short period of
// time.
Eventually(func() bool {
output, err := exec.Command("ovs-vsctl", "--column=ofport", "find", "Interface", fmt.Sprintf("name=%s", hostIface.Name)).CombinedOutput()
Expect(err).NotTo(HaveOccurred())
return (string(output[:len(output)-1]) == ovsOutput)
}, time.Minute, 100*time.Millisecond).Should(Equal(true))
})
})
Context("specify trunk with multiple ranges", func() {
trunks := `[ {"minID": 10, "maxID": 12}, {"minID": 19, "maxID": 20} ]`
It("testSplitVlanIds method should return with specifed values in the range", func() {
Expand Down
3 changes: 2 additions & 1 deletion pkg/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ type NetConf struct {
VlanTag *uint `json:"vlan"`
MTU int `json:"mtu"`
Trunk []*Trunk `json:"trunk,omitempty"`
DeviceID string `json:"deviceID"` // PCI address of a VF in valid sysfs format
DeviceID string `json:"deviceID"` // PCI address of a VF in valid sysfs format
OfportRequest uint `json:"ofport_request"` // OpenFlow port number in range 1 to 65,279
ConfigurationPath string `json:"configuration_path"`
SocketFile string `json:"socket_file"`
LinkStateCheckRetries int `json:"link_state_check_retries"`
Expand Down

0 comments on commit ebb876e

Please sign in to comment.