Skip to content

Commit

Permalink
Merge pull request #67 from linkernetworks/johnlin/ovs-dpdk
Browse files Browse the repository at this point in the history
support ovs/dpdk type

Former-commit-id: 8f4bad95cf05fb8acd4e500d770e5a45b6d33a58 [formerly 8f4bad95cf05fb8acd4e500d770e5a45b6d33a58 [formerly bd8533d]]
Former-commit-id: 0b6c4117652af17169c8bf41718d4b0e80fa0e0f
Former-commit-id: b33954a
  • Loading branch information
John-Lin authored Jul 9, 2018
2 parents 79a6680 + ebedbbf commit 82cf36a
Show file tree
Hide file tree
Showing 9 changed files with 579 additions and 32 deletions.
22 changes: 12 additions & 10 deletions src/entity/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,25 @@ import (
type NetworkType string

const (
OVSNetworkType NetworkType = "ovs"
FakeNetworkType NetworkType = "fake"
OVSKernelspaceNetworkType NetworkType = "system"
OVSUserspaceNetworkType NetworkType = "netdev"
FakeNetworkType NetworkType = "fake"
)

const (
NetworkCollectionName string = "networks"
)

type Network struct {
ID bson.ObjectId `bson:"_id,omitempty" json:"id"`
Type NetworkType `bson:"type" json:"type"`
Name string `bson:"name" json:"name"`
Clusterwise bool `bson:"clusterwise" json:"clusterwise"`
NodeName string `bson:"nodeName,omitempty" json:"nodeName,omitempty"`
CreatedAt *time.Time `bson:"createdAt,omitempty" json:"createdAt,omitempty"`
OVS OVSNetwork `bson:"ovs,omitempty" json:"ovs"`
Fake FakeNetwork `json:"fake"` //FakeNetwork, for restful testing.
ID bson.ObjectId `bson:"_id,omitempty" json:"id"`
Type NetworkType `bson:"type" json:"type"`
Name string `bson:"name" json:"name"`
Clusterwise bool `bson:"clusterwise" json:"clusterwise"`
NodeName string `bson:"nodeName,omitempty" json:"nodeName,omitempty"`
CreatedAt *time.Time `bson:"createdAt,omitempty" json:"createdAt,omitempty"`
OVS OVSNetwork `bson:"ovs,omitempty" json:"ovs"`
OVSUserspace OVSUserspaceNetwork `bson:"ovsUserspace,omitempty" json:"ovsUserspace"`
Fake FakeNetwork `json:"fake"` //FakeNetwork, for restful testing.
}

//GetCollection - get model mongo collection name.
Expand Down
18 changes: 18 additions & 0 deletions src/entity/network_ovs.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
package entity

// physical NIC port
type PhysicalPort struct {
Name string `bson:"name" json:"name"`
MTU int `bson:"MTU" json:"MTU"`
VlanTags []int32 `bson:"vlanTags" MTC:"vlanTags"`
}

// physical NIC port dpdk enabled
type DPDKPhysicalPort struct {
Name string `bson:"name" json:"name"`
MTU int `bson:"MTU" json:"MTU"`
PCIID string `bson:"pciID" json:"pciID"`
VlanTags []int32 `bson:"vlanTags" json:"vlanTags"`
}

// kernel space datapath
type OVSNetwork struct {
BridgeName string `bson:"bridgeName" json:"bridgeName"`
PhysicalPorts []PhysicalPort `bson:"physicalPorts" json:"physicalPorts"`
}

// userspace space datapath
type OVSUserspaceNetwork struct {
BridgeName string `bson:"bridgeName" json:"bridgeName"`
// exclusive fields
PhysicalPorts []PhysicalPort `bson:"physicalPorts" json:"physicalPorts"`
DPDKPhysicalPorts []DPDKPhysicalPort `bson:"dpdkPhysicalPorts" json:"dpdkPhysicalPorts"`
}
78 changes: 78 additions & 0 deletions src/networkcontroller/network_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,84 @@ func (nc *NetworkController) DeleteOVSNetwork(bridgeName string) error {
if err != nil {
return err
}
return nil
}

func (nc *NetworkController) CreateOVSDPDKNetwork(bridgeName string, ports []entity.DPDKPhysicalPort) error {
if _, err := nc.ClientCtl.CreateBridge(
nc.Context,
&pb.CreateBridgeRequest{
BridgeName: bridgeName,
DatapathType: "netdev",
}); err != nil {
return err
}

for _, port := range ports {
_, err := nc.ClientCtl.AddDPDKPort(
nc.Context,
&pb.AddPortRequest{
BridgeName: bridgeName,
IfaceName: port.Name,
DpdkDevargs: port.PCIID,
})
if err != nil {
return err
}

if len(port.VlanTags) > 0 {
_, err := nc.ClientCtl.SetPort(
nc.Context,
&pb.SetPortRequest{
IfaceName: port.Name,
Options: &pb.PortOptions{
VLANMode: "trunk",
Trunk: port.VlanTags,
},
})
if err != nil {
return err
}
}
}
return nil
}

func (nc *NetworkController) CreateOVSUserpsaceNetwork(bridgeName string, ports []entity.PhysicalPort) error {
if _, err := nc.ClientCtl.CreateBridge(
nc.Context,
&pb.CreateBridgeRequest{
BridgeName: bridgeName,
DatapathType: "netdev",
}); err != nil {
return err
}

for _, port := range ports {
_, err := nc.ClientCtl.AddPort(
nc.Context,
&pb.AddPortRequest{
BridgeName: bridgeName,
IfaceName: port.Name,
})
if err != nil {
return err
}

if len(port.VlanTags) > 0 {
_, err := nc.ClientCtl.SetPort(
nc.Context,
&pb.SetPortRequest{
IfaceName: port.Name,
Options: &pb.PortOptions{
VLANMode: "trunk",
Trunk: port.VlanTags,
},
})
if err != nil {
return err
}
}
}
return nil
}
31 changes: 30 additions & 1 deletion src/networkcontroller/network_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,36 @@ func (suite *NetworkControllerTestSuite) TestCreateNetwork() {
suite.NoError(err)
nc, err := New(net.JoinHostPort(nodeIP, DEFAULT_CONTROLLER_PORT))
suite.NoError(err)
err = nc.CreateOVSNetwork(tName, network.OVS.PhysicalPorts)
err = nc.CreateOVSNetwork(tName, network.OVSUserspace.PhysicalPorts)
suite.NoError(err)

//TODO we need support the list function to check the ovs is existed
defer exec.Command("ovs-vsctl", "del-br", tName).Run()
}

func (suite *NetworkControllerTestSuite) TestCreateOVSUserpsaceNetwork() {
eth1 := entity.PhysicalPort{
Name: suite.ifName,
MTU: 1500,
VlanTags: []int32{2043, 2143, 2243},
}

tName := namesgenerator.GetRandomName(0)
network := entity.Network{
Name: tName,
OVSUserspace: entity.OVSUserspaceNetwork{
BridgeName: tName,
PhysicalPorts: []entity.PhysicalPort{eth1},
},
Type: "netdev",
NodeName: suite.nodeName,
}

nodeIP, err := suite.kubectl.GetNodeExternalIP(suite.nodeName)
suite.NoError(err)
nc, err := New(net.JoinHostPort(nodeIP, DEFAULT_CONTROLLER_PORT))
suite.NoError(err)
err = nc.CreateOVSUserpsaceNetwork(tName, network.OVS.PhysicalPorts)
suite.NoError(err)

//TODO we need support the list function to check the ovs is existed
Expand Down
4 changes: 3 additions & 1 deletion src/networkprovider/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ type NetworkProvider interface {

func GetNetworkProvider(network *entity.Network) (NetworkProvider, error) {
switch network.Type {
case entity.OVSNetworkType:
case entity.OVSKernelspaceNetworkType:
return OVSNetworkProvider{network.OVS}, nil
case entity.OVSUserspaceNetworkType:
return OVSUserspaceNetworkProvider{network.OVSUserspace}, nil
case entity.FakeNetworkType:
return FakeNetworkProvider{network.Fake}, nil
default:
Expand Down
3 changes: 2 additions & 1 deletion src/networkprovider/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ func TestGetNetworkProvider(t *testing.T) {
netType entity.NetworkType
netProviderType interface{}
}{
{"ovs", entity.OVSNetworkType, reflect.TypeOf(OVSNetworkProvider{})},
{"system", entity.OVSKernelspaceNetworkType, reflect.TypeOf(OVSNetworkProvider{})},
{"netdev", entity.OVSUserspaceNetworkType, reflect.TypeOf(OVSUserspaceNetworkProvider{})},
{"fake", entity.FakeNetworkType, reflect.TypeOf(FakeNetworkProvider{})},
}

Expand Down
123 changes: 123 additions & 0 deletions src/networkprovider/ovs_netdev.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package networkprovider

import (
"fmt"
"net"

"github.com/linkernetworks/vortex/src/entity"
"github.com/linkernetworks/vortex/src/networkcontroller"
"github.com/linkernetworks/vortex/src/serviceprovider"
"gopkg.in/mgo.v2/bson"
)

type OVSUserspaceNetworkProvider struct {
entity.OVSUserspaceNetwork
}

func (ovsu OVSUserspaceNetworkProvider) ValidateBeforeCreating(sp *serviceprovider.Container, network *entity.Network) error {
session := sp.Mongo.NewSession()
defer session.Close()
// FIXME validate both dpdk or userspace datapath
// Check whether vlangTag is 0~4095
for _, pp := range ovsu.DPDKPhysicalPorts {
for _, vlangTag := range pp.VlanTags {
if vlangTag < 0 || vlangTag > 4095 {
return fmt.Errorf("The vlangTag %v in PhysicalPort %v should between 0 and 4095", pp.Name, vlangTag)
}
}
}

q := bson.M{}
if network.Clusterwise {
//Only check the bridge name
q = bson.M{"ovsUserspace.bridgeName": ovsu.BridgeName}
} else {
q = bson.M{"nodeName": network.NodeName, "ovsUserspace.bridgeName": ovsu.BridgeName}
}

n, err := session.Count(entity.NetworkCollectionName, q)
if n >= 1 {
return fmt.Errorf("The bridge name %s is exist, please check your cluster type and reassign another bridge name", ovsu.BridgeName)
} else if err != nil {
return err
}
return nil
}

func (ovsu OVSUserspaceNetworkProvider) CreateNetwork(sp *serviceprovider.Container, network *entity.Network) error {
if network.Clusterwise {
nodes, _ := sp.KubeCtl.GetNodes()
for _, v := range nodes {
nodeIP, err := sp.KubeCtl.GetNodeExternalIP(v.GetName())
if err != nil {
return err
}
// TODO if dpdk==true
if err := createOVSDPDKNetwork(nodeIP, network.OVSUserspace.BridgeName, network.OVSUserspace.DPDKPhysicalPorts); err != nil {
return err
}
// TODO else dpdk==false
// if err := createOVSUserspaceNetwork(nodeIP, network.OVS.BridgeName, network.OVS.PhysicalPorts); err != nil {
// return err
// }
}
return nil
}
nodeIP, err := sp.KubeCtl.GetNodeExternalIP(network.NodeName)
if err != nil {
return err
}
// TODO if dpdk==true
return createOVSDPDKNetwork(nodeIP, network.OVSUserspace.BridgeName, network.OVSUserspace.DPDKPhysicalPorts)
// TODO else dpdk==false
// return createOVSUserspaceNetwork(nodeIP, network.OVS.BridgeName, network.OVS.PhysicalPorts)
}

func (ovsu OVSUserspaceNetworkProvider) DeleteNetwork(sp *serviceprovider.Container, network *entity.Network) error {
if network.Clusterwise {
nodes, _ := sp.KubeCtl.GetNodes()
for _, v := range nodes {
nodeIP, err := sp.KubeCtl.GetNodeExternalIP(v.GetName())
if err != nil {
return err
}
if err := deleteOVSUserspaceNetwork(nodeIP, ovsu.BridgeName); err != nil {
return err
}
}
return nil
}

nodeIP, err := sp.KubeCtl.GetNodeExternalIP(network.NodeName)
if err != nil {
return err
}
return deleteOVSUserspaceNetwork(nodeIP, ovsu.BridgeName)
}

func createOVSDPDKNetwork(nodeIP string, bridgeName string, ports []entity.DPDKPhysicalPort) error {
nodeAddr := net.JoinHostPort(nodeIP, networkcontroller.DEFAULT_CONTROLLER_PORT)
nc, err := networkcontroller.New(nodeAddr)
if err != nil {
return err
}
return nc.CreateOVSDPDKNetwork(bridgeName, ports)
}

func createOVSUserspaceNetwork(nodeIP string, bridgeName string, ports []entity.PhysicalPort) error {
nodeAddr := net.JoinHostPort(nodeIP, networkcontroller.DEFAULT_CONTROLLER_PORT)
nc, err := networkcontroller.New(nodeAddr)
if err != nil {
return err
}
return nc.CreateOVSUserpsaceNetwork(bridgeName, ports)
}

func deleteOVSUserspaceNetwork(nodeIP string, bridgeName string) error {
nodeAddr := net.JoinHostPort(nodeIP, networkcontroller.DEFAULT_CONTROLLER_PORT)
nc, err := networkcontroller.New(nodeAddr)
if err != nil {
return err
}
return nc.DeleteOVSNetwork(bridgeName)
}
Loading

0 comments on commit 82cf36a

Please sign in to comment.