Skip to content
Snippets Groups Projects
Commit a605b652 authored by Alejandro Tjaarda's avatar Alejandro Tjaarda
Browse files

l2sm-switch: added grpc server, that enables microservices comm

parent b371bd9d
No related branches found
No related tags found
1 merge request!2repo: added new directory where utils scripts will be
1. Modify the api/v1/ned.proto
2. Generate protofiles:
```bash
protoc -I=api/v1 --go_out=paths=source_relative:./pkg/nedpb api/v1/ned.proto
```
\ No newline at end of file
syntax = "proto3";
package nedpb;
option go_package = "l2sm.local/ovs-switch/pkg/nedpb";
service VxlanService {
// Creates a VxLAN with the specified IP address.
rpc CreateVxlan(CreateVxlanRequest) returns (CreateVxlanResponse);
// Attaches the specified interface to the bridge.
rpc AttachInterface(AttachInterfaceRequest) returns (AttachInterfaceResponse);
}
message CreateVxlanRequest {
// The IP address to attach to the VxLAN.
string ip_address = 1;
}
message CreateVxlanResponse {
// Indicates if the VxLAN was created successfully.
bool success = 1;
// Optional message providing additional information.
string message = 2;
}
message AttachInterfaceRequest {
// The name of the interface to attach to the bridge.
string interface_name = 1;
}
message AttachInterfaceResponse {
// The OpenFlow ID of the attached interface.
int64 interface_num = 1;
// The node name from the environment variable.
string node_name = 2;
}
package main
import (
"context"
"fmt"
"log"
"net"
"os"
"google.golang.org/grpc"
// Adjust the import path based on your module path
"l2sm.local/ovs-switch/pkg/nedpb"
"l2sm.local/ovs-switch/pkg/ovs"
)
// server is used to implement nedpb.VxlanServiceServer
type server struct {
nedpb.UnimplementedVxlanServiceServer
}
// CreateVxlan implements nedpb.VxlanServiceServer
func (s *server) CreateVxlan(ctx context.Context, req *nedpb.CreateVxlanRequest) (*nedpb.CreateVxlanResponse, error) {
ipAddress := req.GetIpAddress()
// Implement your logic to create a VxLAN with the given IP address
// For example, call a function from pkg/ovs/vsctl.go
// success, message := ovs.CreateVxlan(ipAddress)
// Placeholder implementation
bridge := ovs.FromName("brtun")
bridge.CreateVxlan(ovs.Vxlan{"", "", ipAddress, ""})
message := fmt.Sprintf("VxLAN with IP %s created successfully", ipAddress)
return &nedpb.CreateVxlanResponse{
Success: success,
Message: message,
}, nil
}
// AttachInterface implements nedpb.VxlanServiceServer
func (s *server) AttachInterface(ctx context.Context, req *nedpb.AttachInterfaceRequest) (*nedpb.AttachInterfaceResponse, error) {
interfaceName := req.GetInterfaceName()
// Implement your logic to attach the interface to the bridge
// For example, call a function from pkg/ovs/vsctl.go
// openflowID, err := ovs.AttachInterface(interfaceName)
// Placeholder implementation
nodeName := os.Getenv("NODE_NAME")
return &nedpb.AttachInterfaceResponse{
OpenflowId: openflowID,
NodeName: nodeName,
}, nil
}
func main() {
// Listen on a TCP port
lis, err := net.Listen("tcp", ":50051") // Choose your port
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
// Create a gRPC server
grpcServer := grpc.NewServer()
// Register the server
nedpb.RegisterVxlanServiceServer(grpcServer, &server{})
log.Printf("gRPC server listening on :50051")
if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
......@@ -4,7 +4,8 @@ import (
"errors"
"flag"
"fmt"
"ovs-switch/pkg/ovs"
"l2sm.local/ovs-switch/pkg/ovs"
)
// Script that takes two required arguments:
......@@ -21,7 +22,7 @@ func main() {
return
}
bridge.AddPort(portName)
err = bridge.AddPort(portName)
if err != nil {
fmt.Println("Port not added: ", err)
......
......@@ -5,8 +5,9 @@ import (
"flag"
"fmt"
"os/exec"
"ovs-switch/pkg/ovs"
"regexp"
"l2sm.local/ovs-switch/pkg/ovs"
)
// Script that takes two required arguments:
......@@ -14,7 +15,7 @@ import (
// the second one is the path to the configuration file, in reference to the code.
func main() {
vethNumber, controllerIP, err := takeArguments()
vethNumber, controllerIP, switchName, err := takeArguments()
if err != nil {
fmt.Println("Error with the arguments. Error:", err)
......@@ -23,7 +24,7 @@ func main() {
fmt.Println("Initializing switch, connected to controller: ", controllerIP)
bridge, err := initializeSwitch(controllerIP)
bridge, err := initializeSwitch(switchName, controllerIP)
if err != nil {
......@@ -43,22 +44,22 @@ func main() {
fmt.Printf("Switch initialized, current state: ", bridge)
}
func takeArguments() (int, string, error) {
func takeArguments() (int, string, string, error) {
vethNumber := flag.Int("n_veths", 0, "number of pod interfaces that are going to be attached to the switch")
controllerIP := flag.String("controller_ip", "", "ip where the SDN controller is listening using the OpenFlow13 protocol. Required")
switchName := flag.String("switch_name", "", "name of the switch that will be used to set a custom datapath id. If not set, a randome datapath will be assigned")
flag.Parse()
switch {
case *controllerIP == "":
return 0, "", errors.New("controller IP is not defined")
return 0, "", "", errors.New("controller IP is not defined")
}
return *vethNumber, *controllerIP, nil
return *vethNumber, *controllerIP, *switchName, nil
}
func initializeSwitch(controllerIP string) (ovs.Bridge, error) {
func initializeSwitch(switchName, controllerIP string) (ovs.Bridge, error) {
re := regexp.MustCompile(`\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b`)
if !re.MatchString(controllerIP) {
......@@ -68,7 +69,8 @@ func initializeSwitch(controllerIP string) (ovs.Bridge, error) {
controller := fmt.Sprintf("tcp:%s:6633", controllerIP)
bridge, err := ovs.NewBridge(ovs.Bridge{Name: "brtun", Controller: controller, Protocol: "OpenFlow13"})
datapathId := ovs.GenerateDatapathID(switchName)
bridge, err := ovs.NewBridge(ovs.Bridge{Name: "brtun", Controller: controller, Protocol: "OpenFlow13", DatapathId: datapathId})
return bridge, err
}
package main
import (
"errors"
"flag"
"fmt"
"os"
"os/exec"
"testing"
"l2sm.local/ovs-switch/pkg/ovs"
)
// Mock implementation of ovs.Bridge for testing purposes
type MockBridge struct {
Name string
Controller string
Protocol string
DatapathId string
}
func (b *MockBridge) AddPort(port string) error {
return nil
}
func (b *MockBridge) String() string {
return fmt.Sprintf("MockBridge{Name: %s, Controller: %s, Protocol: %s, DatapathId: %s}", b.Name, b.Controller, b.Protocol, b.DatapathId)
}
// Override ovs.NewBridge for testing
var NewBridge = func(b ovs.Bridge) (ovs.Bridge, error) {
return ovs.Bridge{
Name: b.Name,
Controller: b.Controller,
Protocol: b.Protocol,
DatapathId: b.DatapathId,
}, nil
}
func TestTakeArguments(t *testing.T) {
// Backup original command line arguments
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
tests := []struct {
args []string
expectedErr error
}{
{[]string{"cmd", "-n_veths", "5", "-controller_ip", "192.168.1.1", "-switch_name", "switch1"}, nil},
{[]string{"cmd", "-n_veths", "5", "-controller_ip", ""}, errors.New("controller IP is not defined")},
}
for _, test := range tests {
os.Args = test.args
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
_, _, _, err := takeArguments()
if err != nil && err.Error() != test.expectedErr.Error() {
t.Errorf("Expected error: %v, got: %v", test.expectedErr, err)
}
}
}
func TestInitializeSwitch(t *testing.T) {
// Mock exec.Command for testing
oldExecCommand := exec.Command
defer func() { exec.Command = oldExecCommand }()
exec.Command = func(name string, arg ...string) *exec.Cmd {
cmd := oldExecCommand("echo", "192.168.1.1")
return cmd
}
tests := []struct {
switchName string
controllerIP string
expectedErr error
}{
{"switch1", "192.168.1.1", nil},
{"switch1", "invalid-ip", nil},
}
for _, test := range tests {
bridge, err := initializeSwitch(test.switchName, test.controllerIP)
if err != nil && err.Error() != test.expectedErr.Error() {
t.Errorf("Expected error: %v, got: %v", test.expectedErr, err)
}
if bridge == nil {
t.Errorf("Expected bridge to be initialized, got nil")
}
}
}
func TestGenerateDatapathID(t *testing.T) {
datapathID := generateDatapathID("pod")
fmt.Println(datapathID)
}
......@@ -7,7 +7,8 @@ import (
"fmt"
"net"
"os"
"ovs-switch/pkg/ovs"
"l2sm.local/ovs-switch/pkg/ovs"
)
type Node struct {
......@@ -66,6 +67,10 @@ func main() {
}
err = connectToNeighbors(bridge, node)
if err != nil {
fmt.Println("Could not connect neighbors: ", err)
return
}
}
if err != nil {
......
......@@ -4,7 +4,7 @@ import (
"encoding/json"
"testing"
"ovs-switch/pkg/ovs"
"l2sm.local/ovs-switch/pkg/ovs"
)
func TestCreateTopology(t *testing.T) {
......
module ovs-switch
module l2sm.local/ovs-switch
go 1.21.7
require github.com/eclipse/paho.mqtt.golang v1.4.3
require (
golang.org/x/sys v0.24.0 // indirect
golang.org/x/text v0.17.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
google.golang.org/protobuf v1.34.2 // indirect
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/mock v1.6.0 // indirect
......@@ -11,7 +18,8 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/stretchr/testify v1.9.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/sync v0.8.0 // indirect
google.golang.org/grpc v1.67.0
gopkg.in/yaml.v3 v3.0.1 // indirect
)
......@@ -21,24 +21,37 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.34.2
// protoc v5.28.2
// source: ned.proto
package nedpb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type CreateVxlanRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The IP address to attach to the VxLAN.
IpAddress string `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"`
}
func (x *CreateVxlanRequest) Reset() {
*x = CreateVxlanRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ned_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateVxlanRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateVxlanRequest) ProtoMessage() {}
func (x *CreateVxlanRequest) ProtoReflect() protoreflect.Message {
mi := &file_ned_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateVxlanRequest.ProtoReflect.Descriptor instead.
func (*CreateVxlanRequest) Descriptor() ([]byte, []int) {
return file_ned_proto_rawDescGZIP(), []int{0}
}
func (x *CreateVxlanRequest) GetIpAddress() string {
if x != nil {
return x.IpAddress
}
return ""
}
type CreateVxlanResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Indicates if the VxLAN was created successfully.
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"`
// Optional message providing additional information.
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *CreateVxlanResponse) Reset() {
*x = CreateVxlanResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_ned_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateVxlanResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateVxlanResponse) ProtoMessage() {}
func (x *CreateVxlanResponse) ProtoReflect() protoreflect.Message {
mi := &file_ned_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateVxlanResponse.ProtoReflect.Descriptor instead.
func (*CreateVxlanResponse) Descriptor() ([]byte, []int) {
return file_ned_proto_rawDescGZIP(), []int{1}
}
func (x *CreateVxlanResponse) GetSuccess() bool {
if x != nil {
return x.Success
}
return false
}
func (x *CreateVxlanResponse) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
type AttachInterfaceRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The name of the interface to attach to the bridge.
InterfaceName string `protobuf:"bytes,1,opt,name=interface_name,json=interfaceName,proto3" json:"interface_name,omitempty"`
}
func (x *AttachInterfaceRequest) Reset() {
*x = AttachInterfaceRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_ned_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *AttachInterfaceRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AttachInterfaceRequest) ProtoMessage() {}
func (x *AttachInterfaceRequest) ProtoReflect() protoreflect.Message {
mi := &file_ned_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AttachInterfaceRequest.ProtoReflect.Descriptor instead.
func (*AttachInterfaceRequest) Descriptor() ([]byte, []int) {
return file_ned_proto_rawDescGZIP(), []int{2}
}
func (x *AttachInterfaceRequest) GetInterfaceName() string {
if x != nil {
return x.InterfaceName
}
return ""
}
type AttachInterfaceResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The OpenFlow ID of the attached interface.
OpenflowId int64 `protobuf:"varint,1,opt,name=openflow_id,json=openflowId,proto3" json:"openflow_id,omitempty"`
// The node name from the environment variable.
NodeName string `protobuf:"bytes,2,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"`
}
func (x *AttachInterfaceResponse) Reset() {
*x = AttachInterfaceResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_ned_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *AttachInterfaceResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AttachInterfaceResponse) ProtoMessage() {}
func (x *AttachInterfaceResponse) ProtoReflect() protoreflect.Message {
mi := &file_ned_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AttachInterfaceResponse.ProtoReflect.Descriptor instead.
func (*AttachInterfaceResponse) Descriptor() ([]byte, []int) {
return file_ned_proto_rawDescGZIP(), []int{3}
}
func (x *AttachInterfaceResponse) GetOpenflowId() int64 {
if x != nil {
return x.OpenflowId
}
return 0
}
func (x *AttachInterfaceResponse) GetNodeName() string {
if x != nil {
return x.NodeName
}
return ""
}
var File_ned_proto protoreflect.FileDescriptor
var file_ned_proto_rawDesc = []byte{
0x0a, 0x09, 0x6e, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x6e, 0x65, 0x64,
0x70, 0x62, 0x22, 0x33, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x78, 0x6c, 0x61,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x70, 0x5f, 0x61,
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x70,
0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x49, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x56, 0x78, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18,
0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x22, 0x3f, 0x0a, 0x16, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x49, 0x6e, 0x74, 0x65,
0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e,
0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4e,
0x61, 0x6d, 0x65, 0x22, 0x57, 0x0a, 0x17, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x49, 0x6e, 0x74,
0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f,
0x0a, 0x0b, 0x6f, 0x70, 0x65, 0x6e, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x03, 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x6e, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12,
0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x32, 0xa6, 0x01, 0x0a,
0x0c, 0x56, 0x78, 0x6c, 0x61, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x44, 0x0a,
0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x78, 0x6c, 0x61, 0x6e, 0x12, 0x19, 0x2e, 0x6e,
0x65, 0x64, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x78, 0x6c, 0x61, 0x6e,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6e, 0x65, 0x64, 0x70, 0x62, 0x2e,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x56, 0x78, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x49, 0x6e, 0x74,
0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x2e, 0x6e, 0x65, 0x64, 0x70, 0x62, 0x2e, 0x41,
0x74, 0x74, 0x61, 0x63, 0x68, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6e, 0x65, 0x64, 0x70, 0x62, 0x2e, 0x41, 0x74,
0x74, 0x61, 0x63, 0x68, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x21, 0x5a, 0x1f, 0x6c, 0x32, 0x73, 0x6d, 0x2e, 0x6c, 0x6f,
0x63, 0x61, 0x6c, 0x2f, 0x6f, 0x76, 0x73, 0x2d, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x2f, 0x70,
0x6b, 0x67, 0x2f, 0x6e, 0x65, 0x64, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_ned_proto_rawDescOnce sync.Once
file_ned_proto_rawDescData = file_ned_proto_rawDesc
)
func file_ned_proto_rawDescGZIP() []byte {
file_ned_proto_rawDescOnce.Do(func() {
file_ned_proto_rawDescData = protoimpl.X.CompressGZIP(file_ned_proto_rawDescData)
})
return file_ned_proto_rawDescData
}
var file_ned_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_ned_proto_goTypes = []any{
(*CreateVxlanRequest)(nil), // 0: nedpb.CreateVxlanRequest
(*CreateVxlanResponse)(nil), // 1: nedpb.CreateVxlanResponse
(*AttachInterfaceRequest)(nil), // 2: nedpb.AttachInterfaceRequest
(*AttachInterfaceResponse)(nil), // 3: nedpb.AttachInterfaceResponse
}
var file_ned_proto_depIdxs = []int32{
0, // 0: nedpb.VxlanService.CreateVxlan:input_type -> nedpb.CreateVxlanRequest
2, // 1: nedpb.VxlanService.AttachInterface:input_type -> nedpb.AttachInterfaceRequest
1, // 2: nedpb.VxlanService.CreateVxlan:output_type -> nedpb.CreateVxlanResponse
3, // 3: nedpb.VxlanService.AttachInterface:output_type -> nedpb.AttachInterfaceResponse
2, // [2:4] is the sub-list for method output_type
0, // [0:2] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_ned_proto_init() }
func file_ned_proto_init() {
if File_ned_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_ned_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*CreateVxlanRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ned_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*CreateVxlanResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ned_proto_msgTypes[2].Exporter = func(v any, i int) any {
switch v := v.(*AttachInterfaceRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_ned_proto_msgTypes[3].Exporter = func(v any, i int) any {
switch v := v.(*AttachInterfaceResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_ned_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_ned_proto_goTypes,
DependencyIndexes: file_ned_proto_depIdxs,
MessageInfos: file_ned_proto_msgTypes,
}.Build()
File_ned_proto = out.File
file_ned_proto_rawDesc = nil
file_ned_proto_goTypes = nil
file_ned_proto_depIdxs = nil
}
package ovs
import (
"crypto/sha256"
"encoding/hex"
)
// generateDatapathID generates a datapath ID from the switch name
func GenerateDatapathID(switchName string) string {
// Create a new SHA256 hash object
hash := sha256.New()
// Write the switch name to the hash object
hash.Write([]byte(switchName))
// Get the hashed bytes
hashedBytes := hash.Sum(nil)
// Take the first 8 bytes of the hash to create a 64-bit ID
dpidBytes := hashedBytes[:8]
// Convert the bytes to a hexadecimal string
dpid := hex.EncodeToString(dpidBytes)
return dpid
}
......@@ -19,6 +19,7 @@ type Bridge struct {
Controller string
Name string
Protocol string
DatapathId string
Ports []Port
}
......@@ -58,11 +59,18 @@ func NewBridge(bridgeConf Bridge) (Bridge, error) {
return bridge, errors.New("could not set brtun interface up")
}
if bridgeConf.DatapathId != "" {
err := exec.Command("ovs-vsctl", "set", "bridge", bridge.Name, fmt.Sprintf("other-config:datapath-id=%s", bridgeConf.DatapathId)).Run()
if err != nil {
return bridge, errors.New("could not set custom datapath id")
}
}
protocolString := fmt.Sprintf("protocols=%s", bridgeConf.Protocol)
err = exec.Command("ovs-vsctl", "set", "bridge", "brtun", protocolString).Run()
if err != nil {
return bridge, errors.New("could not set brtun messaing protocol to OpenFlow13")
return bridge, errors.New("could not set brtun messaging protocol to OpenFlow13")
}
bridge.Protocol = bridgeConf.Protocol
......
......@@ -6,7 +6,7 @@ ovs-vsctl --db=unix:/var/run/openvswitch/db.sock --no-wait init
ovs-vswitchd --pidfile=/var/run/openvswitch/ovs-vswitchd.pid --detach
l2sm-init --n_veths=$NVETHS --controller_ip=$CONTROLLERIP
l2sm-init --n_veths=$NVETHS --controller_ip=$CONTROLLERIP --switch_name=$NODENAME
sleep 20
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment