diff --git a/src/switch/README.md b/src/switch/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ea76469a606c53981920828543911d3229e00867
--- /dev/null
+++ b/src/switch/README.md
@@ -0,0 +1,5 @@
+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
diff --git a/src/switch/api/v1/ned.proto b/src/switch/api/v1/ned.proto
new file mode 100644
index 0000000000000000000000000000000000000000..2a3e6a96b1a8d57918fb310d63981883cf929257
--- /dev/null
+++ b/src/switch/api/v1/ned.proto
@@ -0,0 +1,37 @@
+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;
+}
diff --git a/src/switch/cmd/grpc-server/main.go b/src/switch/cmd/grpc-server/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..85bcee32db04af50b9c5a7722df49ee8b2279d1d
--- /dev/null
+++ b/src/switch/cmd/grpc-server/main.go
@@ -0,0 +1,76 @@
+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)
+	}
+}
diff --git a/src/switch/cmd/l2sm-add-port/main.go b/src/switch/cmd/l2sm-add-port/main.go
index 353c462d08e6e57297259734e770ac2a9c9e450e..bc6a59806c106f0d1329be70e068c486bb87d34f 100644
--- a/src/switch/cmd/l2sm-add-port/main.go
+++ b/src/switch/cmd/l2sm-add-port/main.go
@@ -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)
diff --git a/src/switch/cmd/l2sm-init/main.go b/src/switch/cmd/l2sm-init/main.go
index 5c9a8212a804f34ad54314ed55f7ee85ea776e6c..0ecafa360227263dbb562a810728a4bb255984bc 100644
--- a/src/switch/cmd/l2sm-init/main.go
+++ b/src/switch/cmd/l2sm-init/main.go
@@ -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
 }
diff --git a/src/switch/cmd/l2sm-init/main_test.go b/src/switch/cmd/l2sm-init/main_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..bd26d7f70b41b567cc23d0371e6bfba0594adfcf
--- /dev/null
+++ b/src/switch/cmd/l2sm-init/main_test.go
@@ -0,0 +1,98 @@
+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)
+}
diff --git a/src/switch/cmd/l2sm-vxlans/main.go b/src/switch/cmd/l2sm-vxlans/main.go
index 016d2436a48e0600c02e2de27b9892867daebdf8..8e486cd90347e321a9c9db80e0520c40faa00349 100644
--- a/src/switch/cmd/l2sm-vxlans/main.go
+++ b/src/switch/cmd/l2sm-vxlans/main.go
@@ -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 {
diff --git a/src/switch/cmd/l2sm-vxlans/main_test.go b/src/switch/cmd/l2sm-vxlans/main_test.go
index 4ee7c33f0219ab9ea8cb0da9cb544edbb57250c6..47737f76b4d03d743007d56a62b3d80a21b4e275 100644
--- a/src/switch/cmd/l2sm-vxlans/main_test.go
+++ b/src/switch/cmd/l2sm-vxlans/main_test.go
@@ -4,7 +4,7 @@ import (
 	"encoding/json"
 	"testing"
 
-	"ovs-switch/pkg/ovs"
+	"l2sm.local/ovs-switch/pkg/ovs"
 )
 
 func TestCreateTopology(t *testing.T) {
diff --git a/src/switch/go.mod b/src/switch/go.mod
index ba5ccbb23213db1f98ee3dac41d5468dc509bcdd..fca2823355c2813a5d5b2b348541cd6732da9fd0 100644
--- a/src/switch/go.mod
+++ b/src/switch/go.mod
@@ -1,9 +1,16 @@
-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
 )
diff --git a/src/switch/go.sum b/src/switch/go.sum
index f3cb5d3b425b85fbeab9f19fa387d626a66b5326..ba494d14b837aca4f8f34c86d5414f3090826157 100644
--- a/src/switch/go.sum
+++ b/src/switch/go.sum
@@ -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=
diff --git a/src/switch/pkg/nedpb/ned.pb.go b/src/switch/pkg/nedpb/ned.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..7a03427b916b1d3a3c42bf1e85733726371ea72a
--- /dev/null
+++ b/src/switch/pkg/nedpb/ned.pb.go
@@ -0,0 +1,374 @@
+// 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
+}
diff --git a/src/switch/pkg/ovs/utils.go b/src/switch/pkg/ovs/utils.go
new file mode 100644
index 0000000000000000000000000000000000000000..57b7b323a4275594b205299cde7b72b82abd8243
--- /dev/null
+++ b/src/switch/pkg/ovs/utils.go
@@ -0,0 +1,26 @@
+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
+}
diff --git a/src/switch/pkg/ovs/vsctl.go b/src/switch/pkg/ovs/vsctl.go
index 8df0a16597b480d4607052b486dc87d1a2a09c32..f3f1283542ba22b7758c71c84d54688df4c88b4c 100644
--- a/src/switch/pkg/ovs/vsctl.go
+++ b/src/switch/pkg/ovs/vsctl.go
@@ -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
diff --git a/src/switch/setup_switch.sh b/src/switch/setup_switch.sh
index 5bc2dfe286a2dbbc5beb488d8723e3392fff3566..cb16ee060165e54402863c12f42e8a1c7f213e13 100644
--- a/src/switch/setup_switch.sh
+++ b/src/switch/setup_switch.sh
@@ -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